O co tak naprawdę chodzi w serverless: model, a nie magia
Kontekst chmury i przesunięcie odpowiedzialności
Serverless computing budzi skrajne emocje: dla jednych to cudowny sposób na „bezserwerowe” aplikacje, dla innych – marketingowa naklejka na stare pomysły. Klucz leży w zrozumieniu, że serverless to model odpowiedzialności i rozliczania, a nie zaklęcie, które usuwa serwery z rzeczywistości.
W klasycznych modelach (serwery fizyczne, maszyny wirtualne, nawet kontenery) zespół IT zajmuje się nie tylko kodem, ale też:
- prowizjonowaniem i konfiguracją maszyn,
- aktualizacjami systemu operacyjnego i runtime’ów,
- monitoringiem zasobów (CPU, RAM, dysk),
- skalowaniem przy rosnącym ruchu,
- planowaniem pojemności (capacity planning).
W modelu serverless gros tej pracy przechodzi na dostawcę chmury. Zespół skupia się na logice biznesowej w postaci funkcji lub drobnych serwisów, a nie na serwerach. Serwery nadal istnieją, ale stają się raczej „detalem implementacyjnym” po stronie AWS, Azure, GCP czy innej platformy.
Z punktu widzenia biznesu istotne jest to, że zmienia się sposób, w jaki płacisz: zamiast kupować lub rezerwować zasoby „na wszelki wypadek”, płacisz za rzeczywiste wykorzystanie – np. za czas wykonywania funkcji i zużytą pamięć. To przesuwa ryzyko niewykorzystanej mocy obliczeniowej na dostawcę chmury.
„Brak serwera” w marketingu vs realna infrastruktura
Hasło „serverless” jest mylące. Serwery jak najbardziej istnieją – działają centra danych, hypervisory, klastry Kubernetes, systemy kolejkowania. Różnica polega na tym, że nie zarządzasz nimi bezpośrednio. Nie wybierasz rozmiaru maszyn, nie konfigurujesz load balancera, nie martwisz się o patchowanie systemu.
Od strony technicznej dostawca:
- utrzymuje flotę maszyn fizycznych i wirtualnych,
- zarządza orkiestracją kontenerów, na których uruchamiane są funkcje,
- implementuje autoskalowanie na poziomie pojedynczych wywołań funkcji,
- zapewnia izolację między tenantami (kontenery, sandboxing, VM-y per funkcja).
Twoja perspektywa zostaje uproszczona do kilku parametrów: język, handler (wejściowy punkt funkcji), ilość pamięci, maksymalny czas wykonania, zmienne środowiskowe i uprawnienia. Reszta to „czarna skrzynka”. Z jednej strony radykalnie obniża to próg wejścia, z drugiej – ogranicza kontrolę i możliwości tuningu.
Serverless to więc nie „chmura w wersji 2.0”, lecz specyficzna odmiana usług PaaS, gdzie poziom abstrakcji jest jeszcze wyższy, a relacja: kod → zdarzenie → wynik uproszczona do granic możliwości.
Serverless na tle bare metal, VM i kontenerów
Łatwiej zrozumieć serverless, kiedy umieści się go na osi rozwiązań infrastrukturalnych:
- Bare metal – pełna kontrola nad fizycznym serwerem, maksymalna odpowiedzialność po stronie zespołu.
- VM (IaaS) – elastyczność w doborze rozmiaru, ale nadal opieka nad systemem operacyjnym, paczkami, security hardeningiem.
- Kontenery/Kubernetes – ustandaryzowane środowisko uruchomieniowe, deklaratywne zarządzanie, ale konieczność utrzymania klastra.
- PaaS – np. Heroku, App Service; dostawca zarządza częścią stosu, ale masz długotrwale działające instancje.
- FaaS/serverless – kod uruchamiany na żądanie, krótko żyjące instancje, rozliczanie w modelu pay-per-use.
Im wyżej na tej osi, tym mniej czasu poświęcasz na infrastrukturę, a więcej na logikę domenową. Cena: ograniczona swoboda, vendor lock-in, mniejsza przewidywalność zachowania pod obciążeniem.
Serverless nie wnosi rewolucji technologicznej w sensie nowych prymitywów obliczeniowych. Rewolucją jest raczej model dostarczania, skalowania i rozliczania: nie rezerwujesz mocy obliczeniowej, tylko korzystasz z puli współdzielonej i rozliczasz się na podstawie krótkich, izolowanych wykonów.
Jak działa serverless pod maską: funkcje, zdarzenia i krótko żyjące zasoby
FaaS w praktyce: cykl życia funkcji
Trzon serverless computing stanowią Functions as a Service (FaaS). Z perspektywy programisty jedna funkcja to zazwyczaj:
- mały fragment kodu (np. jedna metoda/handler),
- opis konfiguracji (język, pamięć, timeout, zmienne środowiskowe),
- powiązane wyzwalacze (HTTP, kolejka, zdarzenia z innych usług).
Standardowy cykl życia wywołania funkcji wygląda tak:
- Zdarzenie (np. HTTP request, wiadomość w kolejce) trafia do usługi orkiestrującej.
- Platforma wybiera lub tworzy instancję wykonawczą (kontener/VM z runtime’em).
- Ładowany jest kod funkcji i ewentualne zależności.
- Funkcja otrzymuje dane wejściowe (payload, parametry) i kontekst.
- Funkcja wykonuje logikę i zwraca wynik lub zapisuje efekty w innych usługach (baza, kolejka, storage).
- Instancja zostaje wygaszona lub utrzymana w trybie „ciepłym” na potrzeby kolejnych wywołań.
Najważniejsza konsekwencja: nie masz gwarancji, że kolejne wywołanie funkcji trafi do tego samego procesu. Funkcja musi być stateless; wszelka trwała informacja musi trafiać do baz danych, cache’y, kolejek czy storage’u.
Źródła zdarzeń: HTTP, kolejki, schedulery i integracje
Serverless żyje zdarzeniami. Przykładowe źródła:
- HTTP/API – wywołania przez API Gateway, Application Gateway czy inny front HTTP.
- Kolejki i strumienie – SQS, Pub/Sub, Service Bus, Kafka (bezpośrednio lub przez adaptery).
- Schedulery – cron-like (np. CloudWatch Events, Azure Timer Trigger) uruchamiające funkcje cyklicznie.
- Zdarzenia z usług chmurowych – upload pliku do object storage, zapis do bazy NoSQL, zmiana w rejestrze.
- Webhooki – sygnały od systemów zewnętrznych (płatności, CRM, systemy partnerskie).
Każde takie zdarzenie jest mapowane na strukturę wejściową funkcji. Programista skupia się więc na obsłudze zdarzenia, a nie na zarządzaniu infrastrukturą nasłuchującą. To sprzyja architekturze event-driven, w której aplikacja składa się z wielu małych, niezależnych reakcji na zdarzenia.
Dobrze zaprojektowany system serverless ma czytelną mapę: jakie zdarzenie → jaka funkcja → jaki efekt. Przy większej skali warto używać mechanizmów orkiestracji (np. AWS Step Functions, Azure Durable Functions), aby uniknąć „spaghetti funkcji” wywołujących się nawzajem.
Żywotność instancji i cold start
Pod maską jedna funkcja obsługiwana jest zwykle przez krótko żyjącą instancję kontenera lub mikro-VM. Platforma może wykorzystać istotne optymalizacje:
- utrzymywać „ciepłe” instancje przez jakiś czas po zakończeniu wywołania,
- re-używać tej samej instancji do obsługi wielu kolejnych wywołań,
- tworzyć nowe instancje równolegle, gdy rośnie liczba zdarzeń.
Kiedy funkcja jest wywoływana po raz pierwszy lub po dłuższej przerwie, występuje tzw. cold start. Obejmuje on:
- przydzielenie zasobów i uruchomienie instancji,
- załadowanie runtime’u (np. Node.js, .NET, Python),
- załadowanie kodu i bibliotek aplikacji,
- inicjalizację globalnych struktur (np. połączenia do bazy).
Cold start zwiększa czas odpowiedzi pierwszych wywołań, często o dziesiątki-kilkadziesiąt milisekund, a przy „ciężkich” pakietach – więcej. Dla API o ostrych wymaganiach latency bywa to problemem. Zmniejszyć ten efekt można m.in. przez:
- minimalizację rozmiaru paczki funkcji (mało zależności, brak zbędnych bibliotek),
- wybór szybkiego runtime’u (np. Go bywa szybszy niż JVM przy zimnym starcie),
- utrzymywanie „ciepła” funkcji sztucznym ruchem (np. ping co kilka minut),
- stosowanie warstw (layers) dla współdzielonych zależności.
Z drugiej strony, przy wielu typach zadań (eventowe procesy w tle, batch) opóźnienia rzędu setek milisekund są akceptowalne i cold start praktycznie nie wpływa na jakość usługi.
Skalowanie poziome a autoskalowanie VM/kontenerów
W tradycyjnym świecie, gdy ruch rośnie, uruchamiasz:
- więcej maszyn (scale-out na poziomie VM),
- więcej replik podów w Kubernetesie,
- większe instancje (scale-up), jeśli aplikacja tego wymaga.
W serverless nie deklarujesz liczby instancji. Platforma automatycznie skaluje liczbę równoległych wywołań. Dla Ciebie istotne są limity typu: maksymalna liczba concurrency dla funkcji czy limity konta. Pod dużym, nagłym ruchem platforma:
- tworzy dodatkowe instancje funkcji,
- rozrzuca wywołania pomiędzy nimi,
- po spadku ruchu wygasza nadmiarowe instancje.
W przeciwieństwie do autoskalowania VM:
- nie czekasz minut na podniesienie maszyny – tworzenie instancji funkcji trwa zwykle setki milisekund,
- nie „płacisz” za pustostan – nie ma kosztu za działającą, ale nieużywaną instancję,
- nie planujesz capacity – jest ono w praktyce „nieograniczone” w ramach globalnych limitów.
Ten model świetnie obsługuje gwałtowne piki i okresy ciszy. Gdy ruch jest stabilny i wysoki, korzyść finansowa może zniknąć, a serverless staje się wygodą operacyjną, niekoniecznie oszczędnością.
Co się dzieje z logami, plikami i zmiennymi środowiskowymi
Środowisko funkcji jest efemeryczne. To ma konkretne konsekwencje:
- System plików – zwykle dostępny jest mały, tymczasowy filesystem, kasowany po wygaszeniu instancji. Wszystkie trwałe dane muszą trafić do object storage, bazy lub innej zewnętrznej usługi.
- Zmiennie środowiskowe – definiowane na poziomie konfiguracji funkcji, dostępne w każdym wywołaniu, traktowane jako dane konfiguracyjne. Sekrety warto przenosić do dedykowanych usług typu Secret Manager.
- Logi – standard output/err kierowane są do centralnego logowania (CloudWatch, Application Insights, Stackdriver), gdzie można je przeszukiwać i agregować.
- Pamięć procesu – dane w pamięci żyją tylko tak długo, jak instancja. Czasem można je współdzielić pomiędzy „ciepłymi” wywołaniami, ale nie wolno na tym opierać krytycznej logiki.
To wymusza inne podejście do przechowywania stanu: wszystko, co ma przetrwać zakończenie funkcji, musi być wyciągnięte na zewnątrz. Dobrą praktyką jest jasne rozdzielenie:
- stanu trwałego – w dedykowanych bazach i storage,
- stanu sesyjnego – np. w cache (Redis, ElastiCache, Memorystore),
- stanu lokalnego – tylko na czas pojedynczego wywołania.

Serverless vs klasyczne podejścia: VM, kontenery, PaaS
VM (IaaS): maksymalna elastyczność, maksymalny narzut
Maszyny wirtualne to baza większości rozwiązań w chmurze. Dają:
- pełną kontrolę nad systemem (dowolny OS, własne sterowniki, customowe firewalle),
- możliwość instalacji dowolnego oprogramowania (nietypowe bazy, serwery gier, specjalistyczne narzędzia),
- stałe zasoby (przewidywalność performance przy odpowiednim tuningu).
Cena to:
- utrzymanie OS – patchowanie, hardening, monitorowanie, backupy,
- samodzielne budowanie wysokiej dostępności (load balancery, health checki),
- planowanie pojemności: kupujesz „górkę” mocy, żeby poradzić sobie z pikami.
VM sprawdzą się tam, gdzie potrzeba:
- niestandardowego środowiska, którego nie da się łatwo odwzorować w FaaS,
Kontenery (CaaS): kontrola środowiska przy rozsądnym narzucie
Kontenery są kompromisem między gołą maszyną a modelem funkcji. Dają:
- powtarzalne środowisko uruchomieniowe (Docker image jako kontrakt),
- izolację aplikacji od hosta przy mniejszym narzucie niż pełna VM,
- spójny model pakowania: od lokalnego developmentu po produkcję w Kubernetesie czy usłudze typu ECS/AKS/GKE.
W zamian pojawia się inny zestaw obowiązków:
- budowanie i utrzymanie obrazów,
- konfiguracja orkiestratora (deploymenty, autoscaling, service discovery),
- monitoring całej warstwy klastrowej: węzły, sieć, storage.
W porównaniu z serverless:
- czas życia procesu – kontener może działać miesiącami, co ułatwia korzystanie z lokalnego cache’u czy połączeń długotrwałych,
- model kosztów – płacisz za działające nody (VM pod klastrem), nawet jeśli ruch jest mały,
- skalowanie – nadal wymaga zdefiniowania reguł HPA/ASG, choć wiele zadań da się zautomatyzować.
Kontenery są sensowne tam, gdzie:
- aplikacja ma bogaty stan w pamięci (np. wewnętrzny cache kilku GB),
- potrzebne są niestandardowe binarki, specyficzne sterowniki lub sidecary,
- przydaje się stabilny adres IP, stickiness sesji czy specyficzne reguły sieciowe.
Serverless przegrywa tu zwykle przy:
- bardzo wysokim, stałym obciążeniu (koszt za request zaczyna być wyższy niż stały koszt węzłów),
- wymaganiu pełnej kontroli nad runtime’em (nietypowe języki, customowe systemy plików),
- skomplikowanych topologiach sieciowych, które trudno zmapować na „funkcje na obrzeżach”.
PaaS (Platform as a Service): złoty środek czy etap przejściowy?
Klasyczne PaaS (Heroku, App Service, App Engine standard/flexible) opierają się na dłużej żyjących procesach webowych/workera. W praktyce:
- deplojujesz aplikację (np. jako repozytorium lub artefakt),
- platforma zarządza serwerami, load balancerami, częścią storage’u,
- skalowanie odbywa się zwykle poprzez zmianę liczby instancji lub ich rozmiaru.
W porównaniu z FaaS:
- model wyceny – płacisz za czas działania instancji, nie za wywołania,
- długi czas życia procesu – łatwiej korzystać z connection pooli, warm cache’u, metryk w pamięci,
- prosty model aplikacyjny – monolit lub zestaw serwisów, a nie setki funkcji.
Serverless wygrywa, gdy:
- ruch jest bardzo nieregularny,
- aplikacja naturalnie rozkłada się na małe, niezależne moduły,
- liczy się minimalizacja pracy operacyjnej (zero serwerów do patchowania).
PaaS ma przewagę, gdy:
- aplikacja jest już zbudowana jako klasyczny web/worker,
- liczba endpointów jest duża, ale ich logika jest spójna (jeden deployment),
- nie chcesz zarządzać klastrem, a jednocześnie unikasz ograniczeń środowiska funkcji.
Serverless w stosie: hybrydy zamiast „albo–albo”
W praktyce rzadko kończy się na jednej warstwie. Typowy układ:
- Kubernetes lub PaaS dla głównych API i usług stanowych,
- funkcje serverless do reakcji na zdarzenia (obsługa kolejek, integracje, przetwarzanie plików),
- kilka VM dla egzotycznych komponentów, których nie da się inaczej uruchomić.
Granicę między FaaS a resztą dobrze rysować według kryteriów:
- charakter obciążenia – bursty i event-driven → FaaS, stały ruch → kontenery/PaaS,
- stan – bogaty stan lokalny → kontenery, stateless + zewnętrzne storage → FaaS,
- czas życia – krótkie zadania, joby, integracje → FaaS, usługi długotrwałe → kontenery/PaaS.
Modele serverless w praktyce chmurowej: AWS, Azure, GCP i alternatywy
AWS: Lambda i ekosystem wokół
AWS Lambda to klasyczny przykład FaaS, ale sama w sobie jest tylko „silnikiem funkcji”. Zupełny obraz daje dopiero otoczenie:
- API Gateway / ALB – wystawianie HTTP/REST/HTTP API z autoryzacją, throttlingiem i cachem,
- SQS, SNS, EventBridge, Kinesis – kolejki i strumienie zdarzeń,
- S3, DynamoDB, RDS Proxy – storage i bazy,
- Step Functions – orkiestracja przepływów funkcji.
Cechy szczególne:
- szeroki wybór triggerów (praktycznie każda usługa AWS może wywoływać Lambdę),
- obsługa wielu języków + custom runtime,
- różne modele wyceny: on-demand oraz Provisioned Concurrency dla ograniczenia cold startów.
W większych projektach krytyczne stają się:
- limity konta (concurrency, liczba wywołań, wielkość paczek),
- projektowanie retry i DLQ (dead-letter queue) przy integracjach eventowych,
- dzielenie funkcji na „właściwe fragmenty” – nie za duże (monolit w Lambdzie), nie za małe (spaghetti funkcji).
Azure: Functions jako część szerszej platformy
Azure Functions są mocno wplecione w resztę platformy, zwłaszcza:
- Event Grid, Service Bus, Storage Queues,
- Logic Apps (workflow) i Durable Functions (stanowa orkiestracja),
- App Service jako wspólna baza technologiczna z klasycznymi aplikacjami webowymi.
Silną stroną jest model triggerów i bindings. Funkcja może mieć:
- trigger (np. HTTP, kolejka, timer),
- bindings wejściowe/wyjściowe (np. automatyczne podpięcie do blob storage, tabel, kolejek).
To upraszcza kod: operacje na storage czy kolejkach da się zadeklarować w konfiguracji funkcji, a nie w kodzie. Wadą bywa:
- czasem zbyt „magiczny” model, utrudniający debugowanie skomplikowanych mapowań,
- silne powiązanie z usługami Azure (utrudnienia przy przenoszeniu do innego dostawcy).
GCP: Cloud Functions i Cloud Run
Google Cloud oferuje dwa modele serverless:
- Cloud Functions – klasyczne FaaS, funkcja jako pojedynczy handler,
- Cloud Run – serverless dla kontenerów (HTTP), w którym pakujesz cały serwis jako obraz.
Cloud Run jest ciekawym kompromisem:
- korzystasz z dowolnego języka i stosu (to po prostu kontener),
- dostajesz autoskalowanie do zera i model „płać za request”,
- masz większą kontrolę nad środowiskiem niż w czystym FaaS.
Z kolei Cloud Functions dobrze współgra z Pub/Sub, Firestore, Cloud Storage i całym modelem eventów GCP. W porównaniu z Lambdą:
- ekosystem integracji jest nieco węższy, ale często prostszy w konfiguracji,
- Cloud Run daje większą elastyczność deploymentu bez wchodzenia w Kubernetes.
Alternatywy: Knative, OpenFaaS, Cloudflare Workers i edge
Poza „wielką trójką” istnieje wiele opcji:
- Knative, OpenFaaS, OpenWhisk – warstwy serverless na klastrach Kubernetes (self-hosted lub managed),
- Cloudflare Workers, Fastly Compute@Edge – funkcje blisko użytkownika, wykonywane na krawędzi sieci CDN,
- Vercel, Netlify – środowiska serverless ściśle połączone z frontendem i JAMstackiem.
Knative i podobne projekty:
- pozwalają zbudować „własne serverless” w prywatnym DC lub chmurze hybrydowej,
- dają większą kontrolę nad limitami, siecią, zgodnością (np. RODO, dane w kraju),
- kosztem tego, że ktoś w organizacji musi utrzymywać klaster i samą warstwę serverless.
Z kolei edge computing:
- skraca latency, bo kod działa blisko użytkownika,
- ma silne ograniczenia środowiskowe (brak pełnego Node.js, ograniczone IO, krótki czas wykonania),
- sprawdza się przy modyfikacji odpowiedzi HTTP, A/B testach, personalizacji i prostym routingiem.
Różnice w modelach cenowych i limitach
Wszyscy dostawcy rozliczają serverless głównie za:
- liczbę wywołań,
- czas wykonywania (zaokrąglany do określonych kwantów, np. 1–100 ms),
- przydzieloną pamięć/CPU.
Różnice widoczne są w szczegółach:
- granularność rozliczeń (im mniejsze kwanty, tym lepiej dla krótkich funkcji),
- darmowe progi miesięczne (istotne przy małych projektach),
- limity domyślne i maksymalne concurrency, rozmiary deploymentu, czas pojedynczego wywołania.
Przy długotrwałych zadaniach (kilka–kilkanaście minut) i wysokiej pamięci obliczenia potrafią kosztować więcej niż joby odpalane na kontenerach batchowych lub VM. Z kolei przy krótkich, rzadkich wywołaniach FaaS zwykle wygrywa kosztowo, bo nie występuje stały koszt infrastruktury.

Gdzie serverless błyszczy: konkretne przypadki użycia
Integracje i klejenie systemów
Serverless świetnie sprawdza się jako „klej” między usługami:
- reakcja na upload pliku (np. transformacja, walidacja, generowanie miniaturek),
- nasłuchiwanie kolejek i strumieni (ETL, przetwarzanie zdarzeń biznesowych),
- budowa webhooków dla systemów zewnętrznych (płatności, CRM, systemy logistyczne).
Zamiast stawiać dedykowany mikroserwis dla prostej integracji, wystarczy funkcja wywoływana zdarzeniem. W efekcie:
- nie płacisz za „czekanie” na pojedyncze webhooki,
- łatwo dorzucić kolejną integrację, dopisując nową funkcję,
- awarie pojedynczych integracji nie wywracają całej aplikacji.
Event-driven backend i „glue microservices”
W architekturze opartej na zdarzeniach funkcje mogą pełnić rolę małych serwisów reagujących na:
- zmianę statusu zamówienia,
- nowe zdarzenie w strumieniu (np. „użytkownik dodał produkt do koszyka”),
- komunikaty z innych domen (np. „płatność zakończona sukcesem”).
Przykładowy scenariusz:
- system płatności wysyła webhook → funkcja serverless weryfikuje podpis,
- na podstawie danych publikuje zdarzenie „PaymentCompleted” na busie,
- inne funkcje (invoice, e-mail, provisioning) reagują niezależnie, każde w swoim tempie.
Taki układ:
- zmniejsza sprzężenie między domenami,
- ułatwia dodawanie nowych reakcji bez modyfikacji centralnego systemu,
- korzysta z naturalnych zalet FaaS – skalowania per zdarzenie, a nie per monolit.
Batch, ETL i przetwarzanie danych
Funkcje radzą sobie dobrze z zadaniami:
- dzielącymi duży problem na wiele małych jednostek (shardy, partycje),
- krótkotrwałymi, ale intensywnymi obliczeniowo,
- związanymi z reakcją na pojawienie się nowych danych.
Przykład z praktyki: import danych z zewnętrznego systemu do hurtowni. Zamiast odpalać raz dziennie duży cron na VM:
- strumień danych trafia do kolejki lub storage’u,
- każdy plik/rekord/partycja wywołuje funkcję transformującą i ładującą dane,
- platforma automatycznie zwiększa liczbę równoległych wywołań przy większym napływie danych.
Przy odpowiednim projekcie:
- czas przetworzenia skraca się dzięki masywnej równoległości,
API i lightweight backendy
Serverless dobrze znosi lekkie, modularne backendy. Nie chodzi wyłącznie o „hello world” na HTTP, ale o całe zestawy endpointów:
- proste API do aplikacji mobilnych lub SPA,
- panele administracyjne o umiarkowanym ruchu,
- API do eksperymentów produktowych (MVP, A/B testy, feature flags).
W porównaniu z klasycznym serwisem w kontenerze różnice są wyraźne:
- przy nieregularnym ruchu nie marnujesz zasobów na „podtrzymywanie” serwera,
- każdy endpoint może skalować się niezależnie (funkcje podzielone według przypadków użycia),
- łatwiej „wycinać” stare funkcje przy refaktoryzacji – nie trzeba zmieniać całego deploymentu.
Z kolei przy:
- bardzo wysokim, stabilnym ruchu 24/7,
- rozbudowanej logice sesji i długich połączeniach (websockety, SSE),
lepszym kandydatem bywa kontener lub PaaS, bo model wywołań per-request potrafi wtedy być droższy i bardziej uciążliwy w utrzymaniu.
Prototypy, hackathony i „eksperymenty na produkcji”
Przy pracy eksperymentalnej serverless daje szansę na szybkie „przyklejenie” nowej funkcjonalności bez grzebania w bazowej infrastrukturze:
- nowy eksperyment produktowy to kilka funkcji + reguła w event busie,
- deployment często sprowadza się do jednego polecenia CLI lub push do repo,
- revert to usunięcie funkcji i ewentualny rollback konfiguracji.
W porównaniu z podejściem „stawiamy nowy mikroserwis”:
- pomijasz konfigurację całej otoczki (serwis discovery, ingress, autoscaling),
- skracasz czas rozmów z zespołem infrastruktury,
- łatwiej uzyskać zgodę na „krótkotrwałe” eksperymenty, bo z góry jest jasny koszt i brak długoterminowego utrzymania VM.
Po udanym teście funkcję można:
- zostawić, jeśli spełnia wymagania niefunkcjonalne,
- lub przepisać do dedykowanego serwisu, jeśli rośnie ruch, złożoność lub potrzeba bardziej wyszukanej observability.
Systemy o ruchu skokowym i sezonowym
Serverless lubi wykresy obciążenia przypominające zęby piły:
- aplikacje eventowe (konferencje online, sprzedaż biletów),
- systemy marketingowe (kampanie, newslettery, flash sale),
- biznesy silnie sezonowe (okresy rozliczeń, święta, początek roku szkolnego).
Przy takim profilu:
- płacisz głównie wtedy, gdy rzeczywiście jest obciążenie,
- nie musisz ręcznie „przewymiarowywać” VM na okresy szczytowe,
- łatwiej wytłumaczyć koszty – korelują bezpośrednio z liczbą akcji użytkowników.
Na tle kontenerów lub klasycznych instancji:
- odchodzi problem rozpoznawania „peaków” z wyprzedzeniem (plan capacity),
- ryzyko niedoszacowania pojemności jest mniejsze, bo scaling dzieje się automatycznie,
- koszt „stały” (rezerwacje, abonamenty VM) maleje, rośnie koszt zmienny powiązany z biznesem.
Automatyzacja operacyjna i DevOps-as-code
Serverless ułatwia automatyzację zadań operacyjnych, które tradycyjnie realizowano jako cron na jakiejś „magicznej” maszynie:
- cykliczne clean-upy w storage’ach i bazach,
- wysyłka raportów, zrzuty danych, archiwizacja logów,
- reakcje na zdarzenia infrastrukturalne (np. zdarzenia z monitoringu, zmiany w konfiguracji).
W porównaniu z „serwerem cronów”:
- eliminujesz pojedynczy punkt awarii,
- nie musisz pamiętać o patchowaniu systemu i przedłużaniu certyfikatów,
- zadania są opisane deklaratywnie (infra as code) i łatwo je odtworzyć w innym środowisku.
Z drugiej strony:
- debugowanie skomplikowanych sekwencji zdarzeń rozproszonych po wielu funkcjach jest trudniejsze niż analiza logów z pojedynczej maszyny,
- łatwiej stworzyć „shadow IT” – mnóstwo małych funkcji, o których nikt nie pamięta, ale nadal się uruchamiają.
Integracja z SaaS i rozszerzanie gotowych systemów
Większość współczesnych systemów SaaS ma hooki, webhooks lub eventy. Serverless dobrze nadaje się na „przedłużenie” tych usług:
- rozszerzenia CRM (np. dodatkowa walidacja leadów, enrichment z zewnętrznych API),
- automatyzacja w narzędziach billingowych i płatniczych,
- customowa logika przy przepływach w narzędziach low-code / no-code.
Zamiast:
- budować dedykowany gateway lub dodatkowy serwis,
- modyfikować istniejący monolit, żeby obsłużył „jeszcze jedną integrację”,
wystarczy mała funkcja reagująca na webhook i odpalająca kolejne zdarzenia wewnątrz organizacji. Różnica jest szczególnie widoczna przy krótkich, prostych przepływach – koszt i złożoność pozostają niskie, a elastyczność jest wysoka.
Gdzie serverless szkodzi: ograniczenia i sytuacje „nie używaj”
Długotrwałe, intensywne obliczenia
FaaS zwykle ma twarde limity czasu wykonania (minuty) i rozmiaru pamięci. Przy zadaniach:
- trwających kilkadziesiąt minut lub więcej,
- wymagających bardzo dużej ilości RAM lub specyficznego sprzętu (GPU, duży dysk lokalny),
koszt i komplikacje szybko rosną. Można oczywiście dzielić pracę na mniejsze części, ale:
- rosną koszty koordynacji (kolejki, orkiestracja, retry),
- zwiększa się powierzchnia błędów (częściowo przetworzone dane, idempotencja),
- czasem i tak płacisz więcej niż za prosty job na kontenerze lub VM.
Przy długich pipeline’ach ML, raportach generowanych raz dziennie czy renderingu wideo lepiej sprawdza się:
- kontener batchowy (ECS/Fargate, Cloud Run jobs, Azure Container Apps jobs),
- klasyczny scheduler (Airflow, Argo, Prefect) korzystający z dłużej żyjących zasobów.
Systemy o stałym, wysokim obciążeniu
Model „płać za wywołanie i czas” zaczyna być niekorzystny, gdy:
- ruch jest stabilny i przewidywalny,
- obciążenie utrzymuje się blisko „sufitu” limitów przez większość dnia,
- skalowanie nie musi reagować na nagłe piki.
W takim scenariuszu:
- koszt per request w FaaS przewyższa koszt utrzymywania kilku stałych instancji,
- tracisz zaletę „braku serwerów”, bo i tak zaczynasz korzystać z opcji typu provisioned concurrency,
- kompleksowość integracji eventowych może nie mieć uzasadnienia ekonomicznego.
Często lepszą kombinacją jest:
- główne API na kontenerach lub PaaS,
- serverless jako „doklejone” funkcje obsługujące edge cases, batchowe integracje czy automatyzacje.
Ciężkie wymagania sieciowe i połączenia trwałe
Typowe środowisko FaaS ma ograniczenia:
- czas życia funkcji,
- brak lub utrudnione wsparcie dla długich połączeń (websocket, gRPC streaming),
- niewielkie możliwości kontroli nad siecią (np. brak pełnego dostępu do VPC bez dodatkowych warstw).
Przy aplikacjach:
- real-time z wieloma równoczesnymi połączeniami,
- systemach IoT utrzymujących stałe kanały komunikacji,
- wewnętrznych protokołach wymagających specyficznych portów i konfiguracji sieci,
serverless funkcje zazwyczaj okazują się niewygodne. Lepiej wtedy:
- postawić dedykowany serwis w kontenerach lub na PaaS,
- ewentualnie użyć specjalizowanych usług (np. managed websocket, IoT hub) i traktować FaaS tylko jako backend logiki biznesowej.
Aplikacje z wymaganiami low-latency i „no cold start”
Cold starty są coraz lepiej optymalizowane, ale wciąż istnieją. Przy:
- frontowej części systemów tradingowych,
- grywalizacji z bardzo ostrymi wymaganiami opóźnień,
- systemach, gdzie każde dodatkowe 50–100 ms liczy się na minus,
nawet sporadyczne opóźnienia podczas cold startu mogą być nieakceptowalne. Można je łagodzić:
- provisioned / pre-warmed concurrency,
- utrzymywaniem ruchu „pingującego” funkcje,
ale to zbliża się już do stałego utrzymywania instancji, więc i tak ponosisz koszty zbliżone do kontenerów. W wielu systemach transakcyjnych lepszą drogą bywa:
- aplikacja w kontenerze lub PaaS z przewidywalnym zachowaniem,
- funkcje tylko dla zadań asynchronicznych, mniej wrażliwych na latency (np. powiadomienia, raporty).
Zespoły bez doświadczenia w architekturze rozproszonej
FaaS zachęca do dzielenia logiki na wiele małych elementów. Bez dyscypliny i doświadczenia powstaje:
- „spaghetti eventowe” – setki funkcji, kolejek i topiców powiązanych nieliniowymi zależnościami,
- duża trudność w odtworzeniu pełnego przepływu danych end-to-end,
- brak jasnych granic domenowych i właścicieli poszczególnych strumieni zdarzeń.
W takim środowisku debugowanie incydentów i analiza awarii potrafią zająć wielokrotnie więcej czasu niż w „nudnym” monolicie. Gdy zespół:
- nie ma nawyków projektowania bounded contexts,
- nie używa konsekwentnie narzędzi do śledzenia requestów end-to-end (tracing, correlation IDs),
serverless może realnie zaszkodzić produktywności. W takiej sytuacji rozsądniejsze bywa:
- zacząć od kilku większych serwisów (moduły, monolit modularny),
- użyć FaaS bardzo wybiórczo – np. tylko dla integracji lub prostych cronów.
Środowiska o ostrych wymaganiach compliance i kontroli
W wielu organizacjach kontrola nad:
- lokacją danych,
- dostępem sieciowym i modelem bezpieczeństwa,
- procedurami audytu i zatwierdzania zmian,
jest bardziej istotna niż elastyczność. Managed serverless w publicznych chmurach bywa wtedy problematyczny:
- część szczegółów implementacyjnych (np. dokładna topologia) jest ukryta,
- logika biznesowa „wędruje” do krótkotrwałych, trudnych do odtworzenia instancji,
- niektóre branże wymagają pełnej widoczności na poziomie systemu operacyjnego i sieci.
W takich przypadkach częściej stosuje się:
- kontenery w prywatnych klastrach (on-prem lub chmura, ale z pełną kontrolą),
- serverless „on Kubernetes” (Knative, OpenFaaS) w ramach własnego DC,
- hybrydę – główne systemy w ściśle kontrolowanym środowisku, FaaS tylko do niekrytycznych integracji.
Vendor lock-in i „zacementowanie” w jednym ekosystemie
Moc serverless wynika w dużej mierze z integracji z usługami konkretnego dostawcy. Ta sama cecha bywa pułapką:
- funkcje silnie sprzężone z eventami specyficznymi dla chmury (np. format logów, zdarzenia storage’u),
- użycie proprietary usług (workflow, bazy, identity),
- configuration-as-code korzystające z narzędzi dostępnych tylko u jednego vendora.
Migracja do innej chmury lub on-premu staje się wtedy kosztownym przedsięwzięciem. Można ten efekt łagodzić:
- warstwą abstrakcji (np. własny moduł event bus, własny interfejs storage),
- wybieraniem rozwiązań otwartych tam, gdzie to sensowne (np. Knative nad Kubernetesem, bazujące na open source message brokerach),
- projektowaniem tak, by logika domenowa była jak najmniej zależna od API chmury.
Najczęściej zadawane pytania (FAQ)
Co to jest serverless i czy naprawdę oznacza „brak serwera”?
Serverless to model uruchamiania aplikacji w chmurze, w którym nie zarządzasz serwerami ani systemem operacyjnym. Skupiasz się na kodzie (najczęściej pojedynczych funkcjach), a dostawca chmury bierze na siebie provisioning, aktualizacje, skalowanie i monitoring infrastruktury.
Serwery oczywiście nadal istnieją, ale są ukryte za warstwą usług. Zamiast wybierać rozmiar maszyny i konfigurować load balancer, definiujesz tylko parametry funkcji: język, ilość pamięci, timeout, zmienne środowiskowe. „Bezserwerowość” dotyczy więc perspektywy dewelopera i modelu odpowiedzialności, a nie faktycznego braku fizycznych serwerów.
Czym serverless różni się od VM, kontenerów i PaaS?
Na VM (IaaS) sam dbasz o system operacyjny, pakiety, bezpieczeństwo i skalowanie. Przy kontenerach zyskujesz ustandaryzowane środowisko i orkiestrację (np. Kubernetes), ale nadal utrzymujesz klaster. PaaS (np. Heroku, Azure App Service) zdejmują część obowiązków, lecz wciąż masz długotrwale działające instancje.
Serverless/FaaS idzie krok dalej: kod uruchamia się tylko w reakcji na zdarzenia, instancje są krótkotrwałe, a rozliczenie jest stricte w modelu pay-per-use. Mniej kontroli nad infrastrukturą, ale też mniej pracy operacyjnej. Dobra reguła: im wyżej na tej osi (bare metal → VM → kontener → PaaS → FaaS), tym mniej zajmujesz się infrastrukturą, a bardziej logiką biznesową – kosztem elastyczności i większego ryzyka vendor lock-in.
Kiedy serverless się opłaca, a kiedy lepiej zostać przy kontenerach lub VM?
Serverless zwykle jest korzystny, gdy ruch jest zmienny lub sporadyczny, trudno przewidzieć obciążenie albo projekt dopiero startuje. Płacisz wtedy tylko za czas wykonywania funkcji i zużytą pamięć, zamiast utrzymywać stale włączone maszyny. To dobre podejście np. dla API o nieregularnym ruchu, webhooków, integracji, zadań batch i event-driven backendów.
VM lub kontenery wygrywają przy stałym, wysokim i przewidywalnym obciążeniu, przy bardzo ostrych wymaganiach wydajnościowych (np. niskie opóźnienia, duży throughput) albo gdy potrzebujesz pełnej kontroli nad środowiskiem i konfiguracją sieci. W takich warunkach stała, dobrze wykorzystana infrastruktura bywa po prostu tańsza i stabilniejsza.
Jak działa serverless „pod maską” i co to jest cykl życia funkcji?
W modelu Functions as a Service tworzysz małe funkcje z konfiguracją (runtime, pamięć, timeout, zmienne) i wiążesz je ze zdarzeniami. Gdy zdarzenie wystąpi (np. HTTP request, wiadomość w kolejce, upload pliku), platforma przydziela instancję wykonawczą (kontener lub mikro-VM), ładuje runtime i Twój kod, przekazuje dane wejściowe, po czym uruchamia funkcję.
Po zakończeniu wywołania instancja może zostać wygaszona albo utrzymana w trybie „ciepłym” i użyta ponownie dla kolejnych wywołań tej samej funkcji. Z punktu widzenia aplikacji oznacza to brak gwarancji, że dwa kolejne wywołania trafią do tego samego procesu, dlatego funkcje muszą być stateless – trwałe dane lądują w zewnętrznych usługach (bazy, cache, kolejki, storage).
Co to jest cold start w serverless i jak bardzo spowalnia aplikację?
Cold start pojawia się, gdy funkcja jest wywoływana po raz pierwszy lub po dłuższej przerwie. Platforma musi wtedy przydzielić zasoby, uruchomić instancję, załadować runtime (np. Node.js, .NET, Python), wgrać Twój kod z bibliotekami i wykonać inicjalizację globalnych struktur. To wszystko dodaje opóźnienie do pierwszego wywołania.
W praktyce mowa najczęściej o dziesiątkach–setkach milisekund, ale przy „ciężkich” pakietach lub wolnym runtime może być gorzej. W API wrażliwych na latency (np. realtime, finanse) ma to znaczenie. Ograniczać cold start pomagają m.in. mniejszy rozmiar paczki, lżejszy runtime (np. Go zamiast JVM), rozsądne korzystanie z bibliotek oraz utrzymywanie funkcji „w cieple” poprzez okresowe wywołania testowe.
Jakie zdarzenia mogą wywoływać funkcje serverless?
Funkcje serverless reagują na szerokie spektrum zdarzeń. Najpopularniejsze to:
- HTTP/API – wywołania przez API Gateway lub podobny front HTTP, np. REST/GraphQL.
- Kolejki i strumienie – wiadomości z SQS, Pub/Sub, Service Bus, Kafki (bezpośrednio lub przez adaptery).
- Schedulery – triggery w stylu cron uruchamiające funkcje cyklicznie (np. co 5 minut, raz dziennie).
- Zdarzenia z innych usług chmurowych – upload pliku do object storage, zmiany w bazach NoSQL, logach czy rejestrach.
- Webhooki od systemów zewnętrznych – np. płatności online, CRM-y, systemy partnerskie.
Dzięki temu łatwo budować architekturę event-driven, w której poszczególne funkcje reagują na konkretne zdarzenia i wykonują małe, jasno zdefiniowane zadania, zamiast tworzyć jeden monolityczny serwis.
Czy serverless zwiększa ryzyko vendor lock-in?
W porównaniu z klasycznymi VM czy „czystymi” kontenerami, serverless zwykle bardziej wiąże z konkretnym dostawcą. Korzystasz nie tylko z funkcji jako takich, ale też z charakterystycznych dla danej chmury mechanizmów zdarzeń, integracji, uprawnień i orkiestracji (np. AWS Step Functions, Azure Durable Functions).
Można to częściowo ograniczyć, projektując funkcje tak, by logika biznesowa była jak najbardziej niezależna od infrastruktury, a integracje z chmurą zamknięte w wąskich adapterach. Trzeba jednak liczyć się z tym, że migracja kompleksowego systemu serverless między chmurami będzie trudniejsza niż przeniesienie zestawu kontenerów czy wirtualnych maszyn.






