Najczęstsze zdanie w raportach z testów wydajnościowych brzmi: „wytrzymaliśmy tysiąc użytkowników”. Jest to zdanie bez treści i warto zrozumieć dlaczego, zanim zainwestujecie kwartał w program testów, który będzie takie zdania produkował.
Tysiąc użytkowników — przy jakim miksie scenariuszy? Samych logowań czy głównie przeglądania? Z jakim czasem namysłu między akcjami, czy w ogóle bez niego? I najważniejsze: wobec jakiego progu ten wynik jest sukcesem, a od którego momentu porażką — i czy ten próg istniał przed uruchomieniem testu, czy powstał po, gdy trzeba było zinterpretować to, co wyszło?
Nazywam się Marcin Godula i zajmuję się w ARDURA Consulting inżynierią jakości. Ten tekst jest praktycznym przewodnikiem po testach obciążeniowych, ale prowadzonym wokół jednej tezy: liczba wirtualnych użytkowników jest najmniej ważną liczbą w całym teście. Jeśli szukacie definicji i taksonomii — czym w ogóle są testy wydajności i jak się dzielą — mamy to opisane osobno w tekście czym są testy wydajności oprogramowania. Jeśli interesuje was strona kosztowa programu, jest budżet testów wydajnościowych. Tutaj jest o tym, jak testy prowadzić, żeby rozstrzygały decyzje.
Zdanie, które nic nie znaczy
Test obciążeniowy bez progu zdefiniowanego z góry nie jest testem. Jest generatorem liczb, które potem interpretuje się tak, żeby pasowały do tego, co wyszło.
Brzmi to surowo, ale mechanizm jest banalny i widziałem go wielokrotnie. Zespół uruchamia test, dostaje dziewięćdziesiąty piąty percentyl na poziomie 420 milisekund i zaczyna się rozmowa: czy to dużo? No, użytkownicy nie narzekają. Ale przy szczycie może być gorzej. Z drugiej strony to środowisko przejściowe, więc produkcja będzie szybsza. Kończy się konkluzją „w porządku, ale trzeba obserwować” — czyli brakiem decyzji przebranym za decyzję.
Ten sam przebieg z progiem uzgodnionym wcześniej wygląda inaczej: dziewięćdziesiąty piąty percentyl poniżej 300 milisekund na punktach końcowych dotykających użytkownika, odsetek błędów poniżej progu przepalania budżetu awarii. Wynik 420 milisekund jest wtedy jednoznaczny: czerwony, wydanie zablokowane, szukamy przyczyny. Nie ma miejsca na negocjację, bo próg powstał, gdy nikt jeszcze nie wiedział, jaki będzie wynik.
To jest cała różnica między programem testów, który cokolwiek zmienia, a takim, który produkuje wykresy na spotkanie statusowe.
Percentyl, nie średnia — i dlaczego akurat dziewięćdziesiąty piąty
Skoro próg jest sercem całej sprawy, warto poświęcić chwilę temu, jak go wyrazić. Bo próg wyrażony źle jest niewiele lepszy od jego braku.
Średnia jest bezużyteczna i to nie jest przesada. Rozważcie system, w którym dziewięćdziesiąt procent żądań wraca w 50 milisekund, a dziesięć procent w 2 sekundy. Średnia wynosi 245 milisekund i wygląda przyzwoicie. Tymczasem co dziesiąty użytkownik czeka dwie sekundy, a przy pięciu żądaniach na jedną akcję w interfejsie prawie każda sesja zawiera przynajmniej jedno takie żądanie. Średnia zamazała problem, który dotyczy w praktyce wszystkich.
Percentyl mówi co innego i mówi to uczciwie: dziewięćdziesiąty piąty percentyl na poziomie 300 milisekund znaczy, że dziewiętnaście na dwadzieścia żądań mieści się poniżej tej wartości. To jest zdanie, które da się zweryfikować i o które da się spierać.
Dlaczego zwykle akurat dziewięćdziesiąty piąty, a nie dziewięćdziesiąty dziewiąty? Bo to kwestia stosunku kosztu do sygnału. Dziewięćdziesiąty dziewiąty percentyl jest bardzo czuły na pojedyncze zdarzenia — jedno przeciążone zapytanie, jedno odświeżenie połączenia, jeden moment przełączenia węzła potrafi nim rzucić. Przy krótkim teście jest go po prostu za mało, żeby był stabilny: przy dziesięciu tysiącach żądań dziewięćdziesiąty dziewiąty percentyl opiera się na setce pomiarów, a jego wartość skacze między przebiegami bez żadnej zmiany w kodzie. Dziewięćdziesiąty piąty jest dostatecznie odporny, żeby porównywać przebiegi, i dostatecznie czuły, żeby złapać regres.
To nie znaczy, że dziewięćdziesiąty dziewiąty należy ignorować — należy go obserwować, ale nie warto zawieszać na nim bramki blokującej wydanie, dopóki nie macie przebiegów na tyle długich, żeby był stabilny.
Druga rzecz, którą trzeba wyrazić w progu, to odsetek błędów wraz z tempem przepalania budżetu. Sam próg opóźnienia nie wystarcza: system, który odpowiada błyskawicznie, bo zwraca błąd, przejdzie każdą bramkę opartą wyłącznie na czasie. Próg musi być parą: opóźnienie i poprawność.
Baseline: jedyny dokument, od którego wolno zacząć
Nie da się przetestować czegoś, czego się nie zmierzyło. Każdy wiarygodny program zaczyna się od jednostronicowego dokumentu opisującego, jak system zachowuje się dzisiaj.
Buduje się go z trzech źródeł i żadne z nich nie jest opcjonalne.
Z monitoringu bierzecie ostatnie trzydzieści dni ruchu i wyciągacie godzinę szczytu: szczytową liczbę równoczesnych użytkowników, szczytową liczbę żądań na sekundę per punkt końcowy, medianę oraz dziewięćdziesiąty piąty i dziewięćdziesiąty dziewiąty percentyl opóźnień, a także odsetek błędów. To jest wasz punkt odniesienia — nie liczba wymyślona na spotkaniu.
Od zespołu produktowego bierzecie cele: jakie opóźnienie jest zobowiązaniem, jaka dostępność. Jeśli takich celów nie ma, to jest pierwsza rzecz do zrobienia i nie da się jej ominąć — bez nich test nie ma progu, a bez progu wracamy do zdania, które nic nie znaczy.
Od biznesu bierzecie prognozę wzrostu: czy szykuje się kampania, sezonowy szczyt, wejście na nowy rynek, albo kontrakt, który potroi wolumen jednego klienta.
Te trzy wejścia składają się na zestaw celów testowych. Wzorzec, który sprawdza się w większości organizacji: test bazowy na zaobserwowanym szczycie, test zapasu przy półtorakrotności szczytu, test wytrzymałościowy przy trzykrotności, test wysycenia na osiemdziesięciu procentach szczytu utrzymywany przez cztery do ośmiu godzin, test skokowy przechodzący od jednokrotności do dziesięciokrotności w trzydzieści sekund.
Te cele trzymajcie w repozytorium, nie w prezentacji. Stają się wtedy kontraktem między inżynierią, utrzymaniem i produktem, a nie czyjąś notatką. Leżą obok definicji wskaźników i reguł alertowania, i zmieniają się przez zgłoszenie zmiany, nie przez rozmowę na korytarzu.
Dokument baseline zawiera jeszcze jedną rzecz, którą pomija się najczęściej: mapę zależności. Jakie usługi zewnętrzne system woła, jakie są limity czasu na wywołanie, jakie ograniczenia liczby żądań obowiązują, które kolejki obsługują które akcje użytkownika. Bez tej mapy nie wiecie, czy test w ogóle uderza w warstwę, którą chcecie zmierzyć — testowanie przez serwer proxy trafia w cache, testowanie usługi bezpośrednio już nie. Większość błędów w testach obciążeniowych zaczyna się od niejasnego obrazu zależności.
Cztery testy, cztery różne pytania
„Test obciążeniowy” jest pojęciem zbiorczym i mylenie jego odmian jest drugim najczęstszym powodem, dla którego program nie przynosi decyzji. Dojrzały program prowadzi cztery typy, bo każdy odpowiada na inne pytanie.
| Typ testu | Pytanie, na które odpowiada | Typowy kształt | Co znajduje |
|---|---|---|---|
| Bazowy | Czy spełniamy zobowiązania przy spodziewanym ruchu? | Szczyt z monitoringu, 15–30 minut | Regres wobec poprzedniego wydania |
| Wytrzymałościowy | Gdzie jest sufit i co pęka pierwsze? | Narastanie do wielokrotności szczytu | Pulę połączeń, wysycenie cache’a, opóźnienie kolejki |
| Wysycenia | Co się psuje po godzinach, nie po minutach? | 0,8 szczytu przez 4–12 godzin | Wycieki pamięci, dryf puli, deskryptory, certyfikaty |
| Skokowy | Czy autoskalowanie nadąża? | Skok 1× → 10× w 30 sekund | Koszt zimnego startu, czas reakcji skalowania |
Wiersz o teście skokowym zasługuje na osobne zdanie, bo pominięcie go pod hasłem „przecież mamy autoskalowanie” jest najczęstszą awarią do uniknięcia w epoce chmury. Jeśli czas reakcji skalowania wynosi dziewięćdziesiąt sekund, a szczyt trwa sześćdziesiąt, to macie problem, którego żadna metryka uśredniona nigdy nie pokaże.
Wiersz o teście wysycenia jest równie ważny z innego powodu: system, który przechodzi trzydziestominutowy test bazowy i nie przechodzi ośmiogodzinnego wysycenia, to system, który padnie w produkcji w nocy z soboty na niedzielę. Wycieki, dryf i wyczerpanie zasobów systemowych nie mają jak się ujawnić w krótkim przebiegu.
Czas namysłu, czyli dlaczego 1000 VU to nie 1000 użytkowników
Tu jest miejsce, w którym najczęściej rozjeżdża się liczba raportowana z testu i liczba widoczna na pulpicie produkcyjnym.
Prawdziwi użytkownicy robią przerwy między akcjami. Test, który strzela żądaniami tak szybko, jak potrafi, mierzy coś użytecznego — surową przepustowość — ale nie mierzy doświadczenia użytkownika. I co gorsza, zawyża współbieżność w sposób, który psuje porównywalność: tysiąc użytkowników wirtualnych bez czasu namysłu generuje większe obciążenie niż dziesięć tysięcy realistycznych, a to ta druga liczba pojawia się w waszych dashboardach produkcyjnych.
Konsekwencja praktyczna jest taka, że raport „wytrzymaliśmy tysiąc” bez podanego czasu namysłu jest nieporównywalny nawet z waszym własnym przebiegiem sprzed miesiąca, jeśli ktoś w międzyczasie zmienił ten parametr.
Rozsądne wartości: jedna do trzech sekund między nawigacjami, pięć do piętnastu sekund na stronach z formularzem, trzydzieści do dziewięćdziesięciu sekund na stronach do czytania. Losowane, nie stałe — stały odstęp tworzy sztuczną synchronizację, której w realnym ruchu nie ma.
Miks scenariuszy i wariancja danych
Test jest tyle wart, ile scenariusz, który wykonuje. Najczęstsza porażka to syntetyczny test szczęśliwej ścieżki — jeden punkt końcowy, jeden użytkownik, stałe tempo — który przechodzi, podczas gdy ruch o kształcie produkcyjnym się wywraca.
Modelowanie ścieżek użytkownika. Wyciągnijcie z analityki najczęstsze przepływy: logowanie, przeglądanie lub wyszukiwanie, transakcję, ustawienia. Zaimplementujcie każdy jako osobną grupę z własnym tempem. Użytkownik przeglądający dotyka kilkunastu punktów końcowych w wolnym tempie; użytkownik transakcyjny — kilku, ale z wysoką współbieżnością na tym jednym, który finalizuje. Zmieszajcie je w proporcjach z produkcji. Test, który w stu procentach składa się z finalizacji transakcji, raportuje liczby, jakich wasza produkcja nigdy nie widzi.
Wariancja danych. Test uderzający dziesięć tysięcy razy w ten sam identyfikator mówi o skuteczności cache’a, nie o aplikacji. Zbiór danych ma odzwierciedlać produkcję: realistyczny rozkład identyfikatorów, zapytań i zawartości żądań. Wszystkie współczesne narzędzia czytają pliki z danymi i losują je per użytkownik wirtualny — praktyka, którą stosujemy, to eksport reprezentatywnej próbki z repliki bazy produkcyjnej do pliku sterującego testem.
Wybór narzędzia znaczy mniej, niż myślicie
Rynek skonsolidował się wokół trzech otwartych narzędzi i długiego ogona rozwiązań specjalistycznych. Powiem to wprost, bo oszczędzi wam to kwartału dyskusji: wybór narzędzia jest najmniej ważną decyzją w całym programie. Ważniejsze jest, czy macie próg przed uruchomieniem i czy scenariusz odzwierciedla realny ruch.
k6 jest domyślnym wyborem dla nowych projektów. Testy pisze się w JavaScripcie, czyli w języku, który zespół produktowy zwykle już zna. Progi przechodzi–nie przechodzi są wbudowane, więc wpięcie w potok wydawniczy nie wymaga pisania własnego parsowania wyników — a to jest różnica między „test jest w CI” a „test blokuje zgłoszenie zmian”.
JMeter zostaje tam, gdzie zespół ma kompetencje w ekosystemie Javy albo potrzebuje protokołów spoza HTTP: kolejek, baz danych, katalogów. Ma większy koszt pamięciowy na użytkownika wirtualnego, a jego pliki gorzej znoszą wersjonowanie. Dla zespołu, który już go używa i ma działający potok, przesiadka prawie nigdy się nie opłaca.
Gatling ma najniższy koszt pamięciowy i najlepsze raporty w kategorii, ale wymaga wejścia w Scalę.
Do tego dochodzą narzędzia niszowe: opcja natywna dla zespołów pythonowych, rozwiązania oparte na plikach konfiguracyjnych do szybkich testów dymnych API, oraz klasyczne narzędzia wiersza poleceń do mikropomiarów pojedynczego punktu końcowego — po te ostatnie sięgamy, gdy potrzebny jest pięciosekundowy test rzeczywistości, zanim uruchomimy pełny scenariusz.
Dlaczego tak stanowczo? Bo koszt zmiany narzędzia w połowie drogi jest wysoki i rzadko zwraca się w tym, co naprawdę ogranicza program. Scenariusze trzeba przepisać, progi przełożyć na inną składnię, integrację z potokiem zbudować od nowa, a zespół przeprowadzić przez kolejną krzywą uczenia. Tymczasem żaden z problemów, które realnie psują testy wydajnościowe — brak progu ustalonego z góry, nierealistyczny miks scenariuszy, generator będący wąskim gardłem, środowisko o innym rzędzie wielkości danych — nie znika przez zmianę narzędzia. Wszystkie wracają w nowym, tylko z opóźnieniem o kwartał.
Praktyczna rekomendacja: zacznijcie od k6, zmieniajcie dopiero, gdy uderzycie w konkretne ograniczenie, które umiecie nazwać.
Trzy poziomy w CI/CD zamiast jednego testu przed premierą
Model „test obciążeniowy raz przed premierą” nie przeżył codziennych wydań. Zespoły wydające często potrzebują podziału, w którym koszt każdego poziomu jest proporcjonalny do częstotliwości uruchomień.
Testy dymne przy każdym zgłoszeniu zmian. Sześćdziesiąt sekund, kilkanaście do kilkudziesięciu użytkowników wirtualnych, kilka krytycznych punktów końcowych. Kryteria luźne: brak błędów, dziewięćdziesiąty piąty percentyl nie dramatycznie gorszy niż na gałęzi głównej. Celem nie jest złapanie wszystkich regresji, tylko oczywistych — zapytania w pętli, połączenia otwieranego na każde żądanie, źle ustawionych limitów zasobów dławiących procesor. Werdykt musi być w trzy minuty łącznie z budowaniem i sprzątaniem, inaczej zespół zacznie go omijać.
Pełne testy po scaleniu do gałęzi głównej. Kilkanaście do trzydziestu minut, dedykowane środowisko odwzorowujące topologię produkcji. Nie blokują scalenia, ale głośno alarmują. Ten poziom łapie to, czego testy dymne nie zobaczą: dryf skuteczności cache’a, pogorszone plany zapytań, regresje limitów czasu wobec usług zależnych. Zaplanujcie je tak, żeby kończyły się przed startem kolejnego — nakładające się przebiegi na współdzielonym środowisku produkują śmieci, nie dane.
Testy wysycenia nocą. Cztery do ośmiu godzin bez nadzoru, na środowisku lustrzanym. Wynik ląduje na pulpicie i w kanale zespołu. Wyciek pamięci znaleziony we wtorek nad ranem to tydzień debugowania zaoszczędzony wobec znalezienia go w produkcji w dniu premiery.
Jeśli dopiero budujecie tę warstwę automatyzacji, rozpisaliśmy kolejność wdrażania w planie wdrożenia automatyzacji testów na 90 dni, a szerszy kontekst narzędziowy jest w tekście o automatyzacji testów oprogramowania.
Pięć liczb i cztery wzorce
Uruchomienie testu to połowa pracy. Druga połowa to przełożenie liczb na przyczyny.
Pięć liczb, które mają znaczenie w każdym przebiegu: mediana, dziewięćdziesiąty piąty percentyl, dziewięćdziesiąty dziewiąty percentyl, odsetek błędów i przepustowość. Mediana to typowe doświadczenie. Dziewięćdziesiąty piąty percentyl to zwykle próg, wobec którego się zobowiązaliście. Dziewięćdziesiąty dziewiąty to ogon generujący najgorsze skargi. Odsetek błędów mówi, jak szybko przepalacie budżet awarii. Przepustowość jest liczbą pojemnościową do porównania z prognozą.
Ważniejsze od pojedynczych wartości są jednak wzorce między nimi, bo to one kierują w konkretne miejsce:
- Płaska mediana, rosnący dziewięćdziesiąty piąty, eksplodujący dziewięćdziesiąty dziewiąty → rywalizacja o zasób. Zwykle pula połączeń, pula wątków albo wysycenie węzła cache’a.
- Mediana rosnąca proporcjonalnie z resztą → wysycenie. Zwykle procesor albo pojemność usługi zależnej.
- Odsetek błędów narastający dopiero po kilkudziesięciu minutach → wyciek. Deskryptory plików, połączenia albo pamięć.
- Rozkład dwumodalny — żądania dzielą się na szybkie i wolne → sprawa cache’a. Skuteczność trafień spadła i trzeba ustalić dlaczego.
Czytanie samej średniej jest w tym świetle stratą całego przebiegu: średnia zamazuje każdy z tych czterech wzorców.
Jak to wygląda na konkretnym przebiegu
Przykład, żeby te cztery wzorce nie zostały abstrakcją. Test bazowy, trzydzieści minut, obciążenie na poziomie zaobserwowanego szczytu. Mediana przez cały przebieg stoi na 60 milisekundach i nie drgnie. Dziewięćdziesiąty piąty percentyl zaczyna od 180 milisekund i po dwunastej minucie zaczyna piąć się do 400. Dziewięćdziesiąty dziewiąty w tym samym momencie wystrzeliwuje z 300 milisekund do trzech sekund. Odsetek błędów zostaje na zerze. Przepustowość jest płaska.
Co to jest? Płaska mediana przy rozjeżdżającym się ogonie to rywalizacja o zasób. Większość żądań obsługiwana jest natychmiast, mniejszość czeka w kolejce po coś, czego jest skończona liczba. Zero błędów mówi, że kolejka jeszcze nie przepełnia się do odrzucania — czyli macie zapas, ale malejący. Płaska przepustowość wyklucza wysycenie procesora, bo przy wysyceniu przepustowość przestałaby rosnąć wraz z obciążeniem, a mediana ruszyłaby razem z resztą.
Podejrzani są więc trzej: pula połączeń do bazy, pula wątków obsługujących żądania, albo pojedynczy węzeł cache’a przyjmujący nieproporcjonalny ruch. Rozstrzyga to zestawienie okna dwunastej minuty z metrykami systemowymi — i to jest dokładnie ten moment, w którym test przestaje wystarczać sam sobie.
Bez korelacji z metrykami systemu tylko zgadujecie
Liczby z testu same w sobie mówią, że jest problem. Nie mówią, gdzie.
Zawsze zestawiajcie to samo okno czasowe z metrykami systemowymi: zużycie procesora, pamięć, wejście-wyjście sieci, metryki środowiska uruchomieniowego. Jeśli dziewięćdziesiąty piąty percentyl skoczył w dwunastej minucie, pytanie brzmi: co jeszcze zmieniło się w dwunastej minucie. Śledzenie rozproszone pozwala kliknąć z wolnego żądania wprost do wywołania bazy albo usługi, która odpowiada za opóźnienie. Bez tego dopasowujecie wzorce po omacku.
Druga rzecz: pojedynczy przebieg to migawka, dopiero trend tygodniowy jest sygnałem. Warto utrzymywać historię wyników per środowisko i przeglądać różnice tydzień do tygodnia — tak wyłapuje się powolną regresję, której nikt nie zauważył, bo każdy pojedynczy przebieg mieścił się w progu.
Generator obciążenia bywa wąskim gardłem i wtedy mierzycie siebie
Antywzorzec, który zasługuje na osobną sekcję, bo jest podstępny: maszyna generująca obciążenie sama staje się ograniczeniem, a wynik wygląda jak problem po stronie badanego systemu.
Objaw jest mylący. Zwiększacie liczbę użytkowników wirtualnych, opóźnienia rosną, wykres wygląda jak klasyczne wysycenie — więc wyciągacie wniosek o pojemności systemu. Tymczasem to procesor maszyny testującej nie nadąża z generowaniem żądań i szyfrowaniem połączeń, a mierzony czas odpowiedzi zawiera czas, w którym żądanie czekało w kolejce u was, zanim w ogóle wyszło w sieć.
Dwie kontrole, które to wykluczają, obie tanie:
Po pierwsze, monitorujcie maszynę generującą tak samo jak badany system. Jeśli jej procesor przekracza mniej więcej siedemdziesiąt procent wykorzystania, wyniki z tego przebiegu są podejrzane niezależnie od tego, jak ładnie wyglądają.
Po drugie, zróbcie test kontrolny na dwóch maszynach zamiast jednej, przy tym samym łącznym obciążeniu. Jeśli liczby się poprawiają, znaleźliście wąskie gardło i było ono po waszej stronie. Jeśli są identyczne, generator nie był problemem i możecie ufać poprzednim przebiegom.
Powiązana pułapka dotyczy lokalizacji: generator w innym regionie niż badany system dokłada do każdego pomiaru opóźnienie sieci, którego realny użytkownik może nie mieć — albo odwrotnie, generator w tym samym centrum danych usuwa opóźnienie, które użytkownik ma zawsze. Ani jedno, ani drugie nie jest błędem samo w sobie; błędem jest nie wiedzieć, który wariant się uruchamia.
Wierność środowiska: co musi się zgadzać, a za co nie warto płacić
Środowisko lustrzane wobec produkcji jest ideałem, za który nie każdy chce i nie każdy musi płacić. Warto więc wiedzieć, na czym oszczędność psuje wynik, a na czym nie.
Musi się zgadzać topologia. Liczba warstw, obecność serwera proxy, obecność cache’a, sposób rozkładania ruchu. To one tworzą kolejki i punkty rywalizacji, czyli wszystko, co test ma zmierzyć. Środowisko z aplikacją wystawioną bezpośrednio, podczas gdy produkcja stoi za dwiema warstwami pośredniczącymi, mierzy inny system.
Musi się zgadzać rząd wielkości danych. Baza z tysiącem rekordów zachowuje się inaczej niż baza z dziesięcioma milionami — inne plany zapytań, inna skuteczność indeksów, inne trafienia w cache. To jest najczęściej pomijana różnica i jednocześnie ta, która najmocniej fałszuje wynik. Nie musicie mieć kopii produkcji; musicie mieć ten sam rząd wielkości i podobny rozkład.
Musi się zgadzać konfiguracja limitów. Limity zasobów, rozmiary pul, limity czasu, ograniczenia liczby żądań. Środowisko z hojniejszymi limitami niż produkcja przechodzi testy, których produkcja by nie przeszła — i to jest najgorszy możliwy rodzaj fałszywego zielonego, bo daje pewność siebie dokładnie tam, gdzie jej nie powinno być.
Nie musi się zgadzać skala pozioma, o ile umiecie ją przeliczyć. Środowisko o połowie mocy produkcji jest użyteczne, jeśli testujecie na połowie obciążenia i wiecie, że skalowanie w waszym systemie jest w tym zakresie liniowe. Warunek jest jednak istotny: liniowość trzeba wcześniej sprawdzić testem wytrzymałościowym, a nie założyć.
Nie musi się zgadzać zawartość danych — ważny jest rozkład i rozmiar, nie treść. To dobra wiadomość, bo zdejmuje z was potrzebę kopiowania danych osobowych na środowisko testowe, a przy okazji zamyka temat, który i tak wróciłby przy pierwszym audycie ochrony danych.
Czerwony test i co się dzieje potem
Ostatnia rzecz, bez której cała reszta jest ćwiczeniem akademickim: kto jest właścicielem progu i co się dzieje, gdy test jest czerwony.
Program testów wydajnościowych umiera nie wtedy, gdy testy przestają działać, tylko wtedy, gdy czerwony wynik przestaje cokolwiek powodować. Sekwencja jest zawsze ta sama: pierwszy raz ktoś mówi „to pewnie flaki, puśćmy jeszcze raz”, drugi raz „wydajemy, poprawimy w kolejnym sprincie”, trzeci raz nikt już nie patrzy na wynik.
Trzy zapisy, które temu zapobiegają, i wszystkie trzy są organizacyjne, nie techniczne:
- Próg ma właściciela z imienia i nazwiska — jedną osobę po stronie produktu, która może go zmienić. Zmiana progu jest wtedy decyzją z autorem i datą, a nie cichym rozluźnieniem.
- Czerwony test bazowy blokuje wydanie, a odblokowanie wymaga jawnego odstępstwa od tej samej osoby. Odstępstwo jest w porządku — bywa uzasadnione. Nie jest w porządku odstępstwo, którego nikt nie podpisał.
- Powtórzenie przebiegu jest dozwolone raz i musi być odnotowane. Jeśli drugi przebieg jest zielony, w raporcie zostaje informacja, że pierwszy był czerwony. Niestabilny test to też wynik — mówi, że jesteście blisko progu.
To wygląda na biurokrację i po części nią jest. Ale bez tego wracamy dokładnie tam, gdzie zaczęliśmy: do zdania „wytrzymaliśmy tysiąc użytkowników”, wypowiadanego z ulgą, że nikt nie dopytał.
Trzy antywzorce, które palą najwięcej czasu
Testowanie na maszynie lokalnej. Aplikacja i baza na jednym laptopie dzielą procesor, dysk i pamięć, a sieć między nimi nie istnieje. Wynik nie jest ani optymistyczny, ani pesymistyczny — jest nieporównywalny, co jest gorsze, bo trudniej to zauważyć. Minimum to środowisko przejściowe z własnymi komponentami na realnych ścieżkach sieciowych.
Ignorowanie rozgrzewki. Pierwsze trzydzieści do sześćdziesięciu sekund testu uderza w zimne cache’e, nierozgrzane maszyny wirtualne języka, puste pule połączeń i instancje, które nie pobrały jeszcze wszystkiego, czego potrzebują. Liczby z tego okna nie są reprezentatywne. Albo uruchamiajcie fazę rozgrzewki przed pomiarem, albo odrzucajcie ten fragment w analizie — byle świadomie i zawsze tak samo.
Udawanie współbieżności. Test wysyłający tysiąc żądań na sekundę z jednego użytkownika wirtualnego to nie to samo, co tysiąc równoczesnych użytkowników. Pierwszy mierzy przepustowość zaplecza; drugi mierzy obsługę równoczesnych połączeń, rywalizację o wątki i zachowanie kolejek. Dopasujcie model współbieżności do pytania, na które odpowiadacie — i przeczytajcie to pytanie uważnie, zanim zaprojektujecie test.
Polski kontekst: gdzie próg przestaje być kwestią inżynierską
Trzy sytuacje na naszym rynku, w których „obserwujemy” przestaje być dopuszczalną odpowiedzią.
Sektor finansowy i wymogi odporności operacyjnej. Unijne rozporządzenie o operacyjnej odporności cyfrowej sektora finansowego (DORA), stosowane od 17 stycznia 2025 roku, wymaga od podmiotów finansowych regularnego testowania odporności cyfrowej, w tym zdolności systemów do obsługi obciążenia. Dla banku, ubezpieczyciela czy dostawcy usług płatniczych test obciążeniowy przestaje być praktyką inżynierską dobrej woli, a staje się elementem wykazania zgodności. Konsekwencja praktyczna: wynik testu musi być udokumentowany i powtarzalny, a nie odtworzony z pamięci inżyniera, który akurat go uruchamiał.
Szczyty wymuszone kalendarzem, nie marketingiem. Polskie systemy księgowe i fakturowe mają obciążenie skoncentrowane wokół końców okresów rozliczeniowych — to nie jest rozkład równomierny, który da się uśrednić. Test bazowy na średniej dziennej nie powie nic o dniu, w którym cała baza klientów wystawia dokumenty naraz. Tu właśnie test skokowy przestaje być teoretyczny.
Testy przed migracją i przy zmianie dostawcy. Osobny, bardzo polski przypadek: organizacja przenosi system do innego dostawcy chmury albo z własnej serwerowni do chmury, i całą decyzję opiera na porównaniu cenników. Test obciążeniowy przed migracją i po niej jest jedynym sposobem, żeby dowiedzieć się, czy porównujecie to samo — bo maszyna o tej samej nazwie i tej samej liczbie rdzeni u dwóch dostawców potrafi dawać wyraźnie różną wydajność wejścia-wyjścia, a to właśnie ona zwykle decyduje o czasie odpowiedzi aplikacji biznesowej. Bez pomiaru przed i po nie macie jak rozstrzygnąć, czy pogorszenie po migracji wynika z infrastruktury, z konfiguracji, czy z tego, że akurat wtedy wzrósł ruch. Ten sam argument dotyczy zmiany wersji bazy danych i większych aktualizacji środowiska uruchomieniowego.
Kary umowne w kontraktach B2B. W polskich umowach na utrzymanie systemów poziom usługi bywa obwarowany karami. Jeśli zobowiązaliście się do konkretnego czasu odpowiedzi, to ten zapis jest waszym progiem — gotowym, wynegocjowanym i podpisanym. Zdumiewająco często zespół inżynierski go nie zna, bo umowa leży u prawnika, a próg do testu wymyśla się osobno. Zanim ustalicie własny próg, sprawdźcie, czy nie macie już jednego w kontrakcie.
Co zrobić w najbliższy poniedziałek
Trzy rzeczy wykonalne w jeden dzień roboczy, każda niezależna od wyboru narzędzia:
- Wyciągnijcie z monitoringu godzinę szczytu z ostatnich trzydziestu dni i zapiszcie pięć liczb: równoczesnych użytkowników, żądań na sekundę, medianę, dziewięćdziesiąty piąty percentyl i odsetek błędów. To jest cały baseline, od którego wolno zacząć.
- Sprawdźcie, czy macie zapisany próg — w celach usługowych albo w umowie z klientem. Jeśli nie macie, ustalcie go z produktem, zanim uruchomicie jakikolwiek test. Próg ustalony po teście nie jest progiem.
- Uruchomcie jeden sześćdziesięciosekundowy test dymny na środowisku przejściowym i zmierzcie, ile czasu zajmuje pełny cykl z budowaniem i sprzątaniem. Jeśli przekracza trzy minuty, macie problem z potokiem, nie z testowaniem — i to jego trzeba naprawić najpierw.
Jeżeli po tym ćwiczeniu okaże się, że brakuje wam kompetencji do zbudowania tej warstwy, albo że potrzebujecie kogoś na kwartał, żeby postawić potok i przekazać go zespołowi — to jest zakres, w którym pracujemy. Można zobaczyć naszą ofertę testowania, sprawdzić dostępnych ekspertów albo po prostu napisać do nas z opisem systemu; odpowiemy uczciwie także wtedy, gdy naszym zdaniem poradzicie sobie sami.
Podsumowanie
Liczba wirtualnych użytkowników jest najmniej ważną liczbą w teście obciążeniowym. Bez podanego miksu scenariuszy i czasu namysłu jest nieporównywalna nawet z waszym własnym przebiegiem sprzed miesiąca, a bez progu uzgodnionego przed uruchomieniem cały test degeneruje się do generatora liczb interpretowanych po fakcie.
Kolejność, która działa, jest odwrotna do intuicyjnej: najpierw baseline z telemetrii i próg z celów usługowych albo z umowy, potem dobór typu testu do konkretnego pytania, potem scenariusz odwzorowujący realny ruch, i dopiero na końcu narzędzie — bo to ostatnia i najmniej znacząca decyzja. Wyniki czyta się przez cztery wzorce, nie przez średnią, i zawsze w zestawieniu z metrykami systemu, inaczej wiadomo tylko, że coś jest nie tak, ale nie gdzie.
A jeśli działacie w sektorze finansowym, macie szczyty wymuszone kalendarzem albo kary umowne za czas odpowiedzi — to próg już istnieje, tylko prawdopodobnie leży w dokumencie, do którego zespół inżynierski nie zagląda.