{"id":2359,"date":"2026-06-30T02:00:44","date_gmt":"2026-06-30T02:00:44","guid":{"rendered":"https:\/\/news.jurskitech.pl\/blog\/uncategorized\/5-technik-optymalizacji-api-ktore-realnie-przyspieszaja-aplikacje\/"},"modified":"2026-06-30T02:00:44","modified_gmt":"2026-06-30T02:00:44","slug":"5-technik-optymalizacji-api-ktore-realnie-przyspieszaja-aplikacje","status":"publish","type":"post","link":"https:\/\/news.jurskitech.pl\/blog\/warto-wiedziec\/5-technik-optymalizacji-api-ktore-realnie-przyspieszaja-aplikacje\/","title":{"rendered":"5 technik optymalizacji API, kt\u00f3re realnie przyspieszaj\u0105 aplikacj\u0119"},"content":{"rendered":"<h2 id=\"wstp\">Wst\u0119p<\/h2>\n<p>Wydajno\u015b\u0107 API to jeden z tych temat\u00f3w, o kt\u00f3rym wszyscy m\u00f3wi\u0105, ale ma\u0142o kto robi to dobrze. Zauwa\u017cam, \u017ce w rozmowach z klientami cz\u0119sto s\u0142ysz\u0119: \u201eAPI mamy szybkie, problem le\u017cy gdzie indziej\u201d. Tymczasem po wdro\u017ceniu kilku prostych optymalizacji czas odpowiedzi spada o 40-60%, a u\u017cytkownicy przestaj\u0105 narzeka\u0107 na \u201elagi\u201d. W tym artykule poka\u017c\u0119 5 technik, kt\u00f3re sam stosuj\u0119 w projektach \u2013 od ma\u0142ych sklep\u00f3w e-commerce po platformy SaaS.<\/p>\n<h2 id=\"1paginacjacursorbasedzamiastoffsetowej\">1. Paginacja cursor-based zamiast offsetowej<\/h2>\n<p>Wi\u0119kszo\u015b\u0107 developer\u00f3w domy\u015blnie si\u0119ga po <code>LIMIT<\/code> i <code>OFFSET<\/code> w SQL, bo to proste. Problem zaczyna si\u0119, gdy dane rosn\u0105. Offsetowa paginacja skaluje si\u0119 liniowo \u2013 im g\u0142\u0119biej, tym wolniej. Przy 100 tysi\u0105cach rekord\u00f3w i offset=50k, baza musi przeskanowa\u0107 50 tysi\u0119cy wierszy, zanim zwr\u00f3ci w\u0142a\u015bciwe 20.<\/p>\n<p>Rozwi\u0105zanie? Paginacja cursorowa. Zamiast numeru strony, klient wysy\u0142a identyfikator ostatniego elementu z poprzedniej odpowiedzi (np. <code>?cursor=eyJpZCI6MTIzNH0=<\/code>). Backend wykonuje prosty <code>WHERE id &gt; :cursor LIMIT 20<\/code>, co jest praktycznie O(1) niezale\u017cnie od rozmiaru zbioru.<\/p>\n<p><strong>Przyk\u0142ad z \u017cycia<\/strong>: W migracji API dla sklepu z 200k produkt\u00f3w, zmiana z offsetu na kursory skr\u00f3ci\u0142a \u015bredni czas odpowiedzi z 1.2s do 200ms, a baza przesta\u0142a generowa\u0107 alerty o wysokim CPU.<\/p>\n<h2 id=\"2responsecachingnapoziomieapigateway\">2. Response caching na poziomie API Gateway<\/h2>\n<p>Cz\u0119sto widz\u0119, \u017ce ka\u017cdy endpoint jest traktowany tak samo \u2013 bez cache\u2019owania, nawet je\u015bli dane zmieniaj\u0105 si\u0119 rzadko (np. lista kategorii, regulamin czy opisy produkt\u00f3w). Tymczasem dobrze skonfigurowany cache mo\u017ce obs\u0142u\u017cy\u0107 90% \u017c\u0105da\u0144 bez dotykania backendu.<\/p>\n<p>U\u017cyj API Gateway (np. Cloudflare, AWS, Kong) lub wstaw warstw\u0119 Redis\/Varnish. Ustaw nag\u0142\u00f3wki <code>Cache-Control: public, max-age=3600<\/code> dla zasob\u00f3w statycznych. Dla dynamicznych danych, gdzie ka\u017cdy u\u017cytkownik widzi co\u015b innego, rozwa\u017c cache prywatny z <code>s-maxage<\/code> dla CDN i <code>private<\/code> dla przegl\u0105darki.<\/p>\n<p><strong>Przyk\u0142ad z \u017cycia<\/strong>: W platformie kursowej z 10k u\u017cytkownik\u00f3w, strona g\u0142\u00f3wna kategorii by\u0142a renderowana dla ka\u017cdego requestu. Po dodaniu cache\u2019u Redis z TTL 5 minut, obci\u0105\u017cenie serwera spad\u0142o o 80%, a czas odpowiedzi z 300ms do 5ms.<\/p>\n<h2 id=\"3kompresjajsonaiserializacja\">3. Kompresja JSON-a i serializacja<\/h2>\n<p>Serializacja\/deserializacja JSON-a jest dro\u017csza, ni\u017c my\u015blisz. W aplikacjach Node.js cz\u0119sto stanowi 20-30% czasu odpowiedzi. Mo\u017cna to poprawi\u0107 na dwa sposoby:<\/p>\n<ul>\n<li><strong>Wyb\u00f3r szybszego serializatora<\/strong>: Zamiast domy\u015blnego <code>JSON.stringify<\/code>, u\u017cyj <code>fast-json-stringify<\/code> lub <code>msgpack<\/code>. W testach na du\u017cej strukturze JSON (10KB) <code>fast-json-stringify<\/code> by\u0142 3x szybszy.<\/li>\n<li><strong>Kompresja odpowiedzi<\/strong>: W\u0142\u0105cz gzip lub brotli na poziomie serwera. W przypadku API HTTP\/2, brotli daje lepsz\u0105 kompresj\u0119 (nawet 20% mniejszy rozmiar ni\u017c gzip) przy niskim koszcie CPU.<\/li>\n<\/ul>\n<p><strong>Przyk\u0142ad z \u017cycia<\/strong>: W jednym projekcie SaaS, gdzie API zwraca\u0142o list\u0119 500 obiekt\u00f3w po 2KB ka\u017cdy, zmiana serializatora i w\u0142\u0105czenie brotli skr\u00f3ci\u0142o czas odpowiedzi z 120ms do 45ms, a transfer danych zmniejszy\u0142 si\u0119 o 65%.<\/p>\n<h2 id=\"4connectionpoolingipersistentconnections\">4. Connection pooling i persistent connections<\/h2>\n<p>Ka\u017cde nowe po\u0142\u0105czenie z baz\u0105 danych kosztuje czas i zasoby. W \u015brodowisku produkcyjnym bez poolowania, przy 100 r\u00f3wnoczesnych requestach, powstaje 100 nowych po\u0142\u0105cze\u0144, co mo\u017ce przeci\u0105\u017cy\u0107 baz\u0119.<\/p>\n<p>Rozwi\u0105zanie to connection pooling. W PostgreSQL u\u017cywamy <code>pg-pool<\/code> lub w MySQL <code>mysql2\/pool<\/code>. Dla zapyta\u0144 HTTP do zewn\u0119trznych API \u2013 <code>keep-alive<\/code> i agent z pul\u0105.<\/p>\n<p><strong>Przyk\u0142ad z \u017cycia<\/strong>: W aplikacji, kt\u00f3ra integruje si\u0119 z 3 zewn\u0119trznymi API, brak keep-alive powodowa\u0142 op\u00f3\u017anienia rz\u0119du 300ms na ka\u017cde \u017c\u0105danie (TCP handshake). Po w\u0142\u0105czeniu persistent connections czas skr\u00f3ci\u0142 si\u0119 do 30ms na \u017c\u0105danie.<\/p>\n<h2 id=\"5batchingideduplikacjazapyta\">5. Batching i deduplikacja zapyta\u0144<\/h2>\n<p>Cz\u0119sty problem: frontend wysy\u0142a 10 osobnych request\u00f3w, podczas gdy jeden batch m\u00f3g\u0142by je zast\u0105pi\u0107. Np. panel administratora \u0142aduje statystyki dla 10 produkt\u00f3w \u2013 ka\u017cde osobne API to osobny koszt.<\/p>\n<p>Zaimplementuj endpoint <code>POST \/batch<\/code> lub <code>GET \/products?ids=1,2,3,4,5<\/code>. W backendzie u\u017cyj deduplikacji zapyta\u0144: je\u015bli dwa requesty dotycz\u0105 tych samych danych w kr\u00f3tkim czasie (np. w promieniu 50ms), po\u0142\u0105cz je w jedno zapytanie do bazy.<\/p>\n<p><strong>Przyk\u0142ad z \u017cycia<\/strong>: W dashboardzie SaaS z 50 u\u017cytkownikami, ka\u017cdy \u0142adowa\u0142 swoje dane w p\u0119tli 15 request\u00f3w. Po dodaniu batchnigu i cache\u2019a zapyta\u0144 (DataLoader w GraphQL), \u015bredni czas \u0142adowania strony spad\u0142 z 4s do 0.8s.<\/p>\n<h2 id=\"podsumowanie\">Podsumowanie<\/h2>\n<p>Optymalizacja API nie musi oznacza\u0107 przepisywania ca\u0142ego systemu. Wystarczy spojrze\u0107 na najcz\u0119stsze w\u0105skie gard\u0142a: paginacj\u0119, cache, serializacj\u0119, po\u0142\u0105czenia i batchnig. Ka\u017cda z tych technik jest stosunkowo prosta do wdro\u017cenia, a korzy\u015bci s\u0105 natychmiastowe \u2013 szybsze odpowiedzi, mniejsze obci\u0105\u017cenie serwera i zadowoleni u\u017cytkownicy.<\/p>\n<p>Je\u015bli chcesz, \u017ceby Twoje API dzia\u0142a\u0142o jak dobrze naoliwiona maszyna, zacznij od tych pi\u0119ciu krok\u00f3w. A gdyby\u015b potrzebowa\u0142 wsparcia \u2013 w JurskiTech.pl pomagamy firmom w optymalizacji wydajno\u015bci na co dzie\u0144.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wst\u0119p Wydajno\u015b\u0107 API to jeden z tych temat\u00f3w, o kt\u00f3rym wszyscy m\u00f3wi\u0105, ale ma\u0142o kto robi to dobrze. Zauwa\u017cam, \u017ce w rozmowach z klientami cz\u0119sto s\u0142ysz\u0119: \u201eAPI mamy szybkie, problem le\u017cy gdzie indziej\u201d. Tymczasem po wdro\u017ceniu kilku prostych optymalizacji czas odpowiedzi spada o 40-60%, a u\u017cytkownicy przestaj\u0105 narzeka\u0107 na \u201elagi\u201d. W tym artykule poka\u017c\u0119 5<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[699,556,539,431],"class_list":["post-2359","post","type-post","status-publish","format-standard","hentry","category-warto-wiedziec","tag-api-gateway","tag-architektura-backend","tag-optymalizacja-aplikacji","tag-optymalizacja-wydajnosci"],"_links":{"self":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/posts\/2359","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/comments?post=2359"}],"version-history":[{"count":0,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/posts\/2359\/revisions"}],"wp:attachment":[{"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/media?parent=2359"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/categories?post=2359"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/news.jurskitech.pl\/blog\/wp-json\/wp\/v2\/tags?post=2359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}