ix
ix

informatix

EN version Porozmawiajmy o projekcie
Strona główna / Blog / Load testing i profilowanie Laravel — k6, Blackfire, Xdebug ...
• 7 min czytania •

Load testing i profilowanie Laravel — k6, Blackfire, Xdebug [2026]

Bez pomiaru optymalizacja to zgadywanie. Kompletny warsztat: k6 i percentyle, profilowanie kodu (Blackfire, Xdebug), metryki FPM i bazy oraz testy regresji, które łapią spadki wydajności w CI.

Load testing i profilowanie Laravel — k6, Blackfire, Xdebug [2026]
DevOps i utrzymanie, Web development

„Optymalizowaliśmy dwa tygodnie, ale nie wiemy, czy jest szybciej" — to zdanie powinno nigdy nie paść w profesjonalnym zespole. Bez pomiaru optymalizacja wydajności to zgadywanie: nie wiesz, co naprawić, czy poprawka działa i kiedy wróci regresja. Ten poradnik pokazuje kompletny warsztat pomiarowy: testy obciążeniowe z k6, profilowanie kodu (Blackfire, Xdebug) i budżet wydajnościowy w CI.

Najważniejsze: Najważniejsze — mierz p50/p95/p99 czasu odpowiedzi, nie średnią. Test obciążeniowy planuj jako scenariusze (spokojny ruch, szczyt, nagły skok). Profiluj zanim zoptymalizujesz: 80% czasu zwykle zjada kilka ścieżek kodu. Wyniki zapisuj i porównuj po każdym wdrożeniu — inaczej regresje wracają niezauważone.

Dlaczego średnia kłamie — percentyle

Średni czas odpowiedzi 200 ms brzmi dobrze, dopóki nie zobaczysz rozkładu: p50 = 80 ms, p95 = 900 ms, p99 = 4 s. Średnia ukrywa ogon, a to ogon psuje doświadczenie użytkowników i SEO (Google mierzy realne czasy ładowania).

Interpretacja percentyli

  • p50 (mediana) — typowe doświadczenie użytkownika.
  • p95 — co piąty użytkownik czeka tyle lub dłużej; dobry cel SLA.
  • p99 — najgorsze przypadki: wolne zapytania, blokady, GC, zimny cache.

Cel dla typowej aplikacji Laravel: p50 < 200 ms, p95 < 500 ms dla stron; API odpowiednio niżej. Ustal liczby zanim zaczniesz optymalizować — inaczej nie wiesz, kiedy skończyć.

k6 — testy obciążeniowe bez ciężkiego narzędzia

k6 to nowoczesny load tester (skrypt w JavaScript, jeden binarny plik). Scenariusz opisuje ruch: ile użytkowników wirtualnych (VU), jak długo i co robią.

// load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '1m', target: 20 },   // rozgrzewka
    { duration: '3m', target: 50 },   // stały ruch
    { duration: '1m', target: 150 },  // szczyt
    { duration: '2m', target: 150 },  // utrzymanie szczytu
    { duration: '1m', target: 0 },    // wygaszenie
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],  // 95% żądań poniżej 500 ms
    http_req_failed: ['rate<0.01'],    // <1% błędów
  },
};

export default function () {
  const res = http.get('https://staging.example.com/orders');
  check(res, { 'status 200': (r) => r.status === 200 });
  sleep(1);
}
k6 run load-test.js

Trzy scenariusze, które warto mieć pod ręką

Scenariusz Cel Profil
Smoke czy aplikacja w ogóle działa pod ruchem 1–5 VU, 1 min
Load (średni) wydajność przy typowym ruchu 50–100 VU, 10 min
Spike odporność na nagły skok (kampania, newsletter) 0→300 VU w 30 s

Wskazówka: Testuj na stagingu z kopią produkcyjnej bazy (zanonimizowaną). Test na pustej bazie deweloperskiej nie powie nic o wydajności: brak danych = brak wolnych zapytań, brak N+1, brak blokad. To najczęstszy błąd pierwszego load testu.

Co mierzyć poza k6 — metryki serwera i bazy

Load test obciąża cały stos, więc patrz szerzej

  • PHP-FPM: pm.max_children reached w logu (limit procesów!), średnie zajęcie workerów.
  • Baza danych: liczba aktywnych połączeń vs limit, wolne zapytania w trakcie testu (pg_stat_statements przed/po), blokady.
  • Redis: hit rate, zużycie pamięci, komendy na sekundę.
  • Serwer: load average, CPU iowait, swap (jeśli swap rośnie — RAM na procesy FPM jest przekroczony).

Test bez patrzenia na te metryki to połowa obrazu: aplikacja może odpowiadać w 300 ms, podczas gdy baza jest o krok od wysycenia puli połączeń.

Profilowanie — gdzie naprawdę znika czas

Load test mówi „jest wolno", profil mówi „tutaj". Oto trzy narzędzia.

Blackfire — profesjonalny profiler (SaaS, darmowy plan dev): timeline wywołań, czas per funkcja, liczba zapytań, porównanie profili przed/po. Uruchamiasz na stagingu:

blackfire run php artisan route:call GET /orders   # albo przez rozszerzenie w przeglądarce

Xdebug (tryb profile) — darmowy, lokalny: generuje cachegrind, który otworzysz w KCachegrind/QCachegrind. Wystarczy do znalezienia najdroższych ścieżek; nie nadaje się na produkcję (ogromny narzut).

Laravel Telescope / Pulse — zamiast profilu CPU dostajesz konkret: lista zapytań z czasami, wolne joby, wolne endpointy. Dla 90% problemów „baza vs kod" to wystarczy — szczegóły w Pulse i Telescope — monitoring.

  • Praktyczna kolejność: Debugbar (co jest wolne na ekranie) → Telescope/Pulse (co jest wolne w systemie) → Blackfire/Xdebug (dlaczego ten fragment jest wolny). Profilowanie bez wcześniejszego pomiaru to strata czasu — najpierw wiadro, potem kropla.

Uwaga: Xdebug na produkcji to katastrofa wydajnościowa (narzut liczony w dziesiątkach procent). Profiluj wyłącznie na dev/stagingu. Na produkcji zostają APM-y o niskim narzucie: Pulse, Nightwatch, Blackfire (agent), Scout APM.

Budżet wydajnościowy i regresje w CI

Optymalizacja bez zabezpieczenia wróci. Warto mieć dwa mechanizmy.

1. Budżet wydajnościowy — jawna lista progów, które aplikacja musi spełniać: p95 strony listy < 500 ms, liczba zapytań na dashboard < 15, waga strony głównej < 1 MB. Budżet to część definicji „gotowe".

2. Testy regresji — najprostsza wersja to asercje w testach integracyjnych

// Test: budżet zapytań dla krytycznego ekranu
DB::enableQueryLog();
$this->get('/dashboard')->assertOk();
$this->assertLessThanOrEqual(15, count(DB::getQueryLog()));
  • Cięższa wersja: k6 w pipeline na stagingu po każdym merge do main — z progami z thresholds, które wywalają build przy regresji. Nawet prosty test „liczba zapytań ≤ N" łapie najczęstsze regresje: N+1 dodane w pull requeście.

Cykl pracy, który się nie wypala

  1. Zmierzyć — k6 + metryki, zapisz baseline (p50/p95/p99, RPS, liczba zapytań).
  2. Zdiagnozować — Debugbar → Telescope/Pulse → Blackfire.
  3. Naprawić jedno — największy zysk na jednostkę pracy (typowo: N+1, indeks, cache).
  4. Zmierzyć ponownie — ten sam scenariusz, te same metryki; porównaj z baseline.
  5. Zabezpieczyć — test regresji na to, co naprawiłeś.
  6. Powtórz od kroku 2, aż budżet jest spełniony.

Tylko ten cykl odróżnia optymalizację od rytuału. Pełną checklistę warstw (od zapytań po Octane) znajdziesz w optymalizacji wydajności aplikacji Laravel.

Najczęściej zadawane pytania

Czym się różni load testing od profilowania?

Load testing odpowiada „jak aplikacja zachowuje się pod obciążeniem" (przepustowość, p95, błędy) — testuje cały system z zewnątrz. Profilowanie odpowiada „gdzie znika czas w kodzie" — mierzy pojedyncze żądanie od środka (funkcje, zapytania). Potrzebujesz obu: load test wskaże problem, profil wskaże jego źródło.

Czy k6 może testować scenariusze z logowaniem?

Tak — k6 obsługuje POST-y, cookies, sesje i korelację tokenów: w scenariuszu logujesz użytkownika, przechwytujesz token/ciasteczko i używasz w kolejnych żądaniach. Dla aplikacji z logowaniem to konieczne, żeby testować realistyczne ścieżki (dashboard, koszyk), a nie tylko strony publiczne.

Dlaczego testuję na pustej bazie i wszystko jest szybkie?

Bo wydajność aplikacji zależy od danych: N+1 na 20 rekordach to 20 zapytań, na 100 000 — 100 000. Wolne zapytania bez indeksów na pustych tabelach nie istnieją. Testuj na stagingu z anonimizowaną kopią produkcyjnej bazy — to jedyny wiarygodny scenariusz.

Czy mogę profilować produkcję?

Xdebug — nie (zbyt duży narzut). Możesz za to używać APM-ów o niskim narzucie: Laravel Pulse, Nightwatch, agent Blackfire, Scout APM. One nie pokażą pojedynczej funkcji, ale wskażą wolne endpointy i zapytania — a to zwykle wystarcza do decyzji, co optymalizować.

Jak ustawić progi w k6, żeby były sensowne?

Od biznesu, nie od techniki: „użytkownik nie czeka dłużej niż 0,5 s" → p(95) < 500; „mniej niż 1% błędów w kampanii" → http_req_failed rate < 0.01. Progi poniżej realnych możliwości stosu demotywują; powyżej potrzeb — nie chronią. Ustaw baseline z pierwszego testu i zaostrzaj iteracyjnie.


👉 Chcesz wiedzieć, ile Twoja aplikacja naprawdę wytrzyma? Zrobimy test obciążeniowy z raportem i planem optymalizacji — opisz projekt przez formularz. Zobacz też audyt kodu legacy i utrzymanie techniczne.

📖 Zobacz również: optymalizacja wydajności aplikacji Laravel, problem N+1 w Laravel, indeksy i EXPLAIN ANALYZE oraz Pulse i Telescope — monitoring.

KS

Krzysztof Słonina

Full stack developer i właściciel Inoventis Solutions (informatix). Od 2009 roku buduje aplikacje webowe w Laravel/PHP, integracje e-commerce i automatyzacje procesów — m.in. OneCRMApp i FamilyTimelineApp, działające na Laravel, React i Inertia.js.

O autorze
Darmowy PDF

Checklista wymagań do wyceny aplikacji

12 pytań kontrolnych, które warto przygotować przed rozmową z wykonawcą — szybsza wycena, mniej ukrytych kosztów.

Powiązane wpisy

21.10.2026

Laravel Pulse i Telescope — monitoring aplikacji [2026]

Horizon odpowiada „co robią kolejki", Pulse „jak czuje się aplikacja", a Telescope „co się stało w tym żądaniu". Kompletny przewodnik: karty Pulse, bezpieczeństwo Telescope na produkcji i minimalny zestaw monitoringowy.

Czytaj dalej