Nginx micro-caching — szybkie cache dla aplikacji dynamicznych
Opublikowano: 9 kwietnia 2026 · Kategoria: VPS / Nginx
Aplikacje PHP i Node.js mogą generować setki żądań na sekundę do bazy danych — nawet gdy treść strony zmienia się raz na kilka minut. Nginx micro-caching rozwiązuje ten problem elegancko: cache z TTL zaledwie 1 sekundy pochłania skoki ruchu bez ryzyka wyświetlania nieaktualnych danych. Oto kompletna konfiguracja od podstaw.
Czym jest micro-caching?
Micro-caching to strategia cachowania z bardzo krótkim TTL — zazwyczaj 1 sekundę. W odróżnieniu od tradycyjnego cache (TTL kilka godzin), micro-cache nie wymaga mechanizmu inwalidacji: po 1 sekundzie cache sam wygasa i następne żądanie odświeża dane.
Przy 1000 żądaniach na sekundę, micro-cache obsługuje 999 z pamięci RAM i tylko 1 trafia do backendu. Skutek: PHP-FPM lub Node.js są chronione przed nagłymi skokami ruchu, bez ryzyka wyświetlania danych starszych niż 1 sekunda.
proxy_cache_path — konfiguracja strefy cache
Podstawowa konfiguracja wymaga zdefiniowania strefy cache w bloku http pliku
/etc/nginx/nginx.conf:
# /etc/nginx/nginx.conf — blok http{}
http {
# Definicja strefy cache
# levels=1:2 — struktura katalogów (zapobiega tysiącom plików w 1 katalogu)
# keys_zone=MICRO:10m — nazwa strefy i rozmiar pamięci na klucze (10 MB ~80k kluczy)
# inactive=60s — usuń wpisy nie używane przez 60s
# max_size=1g — maks. rozmiar na dysku
proxy_cache_path /var/cache/nginx/micro
levels=1:2
keys_zone=MICRO:10m
inactive=60s
max_size=1g;
# Opcjonalnie: temp path (musi być na tym samym filesystem co cache_path)
proxy_temp_path /var/cache/nginx/tmp;
} # Utwórz katalogi i ustaw uprawnienia sudo mkdir -p /var/cache/nginx/micro /var/cache/nginx/tmp sudo chown -R www-data:www-data /var/cache/nginx/ sudo nginx -t && sudo systemctl reload nginx
Konfiguracja proxy_cache_valid
W bloku server lub location aktywuj cache i ustaw TTL dla różnych kodów
HTTP:
# /etc/nginx/sites-available/twoja-domena.conf
server {
listen 80;
server_name example.com www.example.com;
# Zmienna do sterowania cache bypass
set $skip_cache 0;
# POST żądania — nigdy nie cachuj
if ($request_method = POST) {
set $skip_cache 1;
}
# URL z query string — pomijaj cache
if ($query_string != "") {
set $skip_cache 1;
}
# WordPress: admin, login, zalogowani użytkownicy, koszyk WooCommerce
if ($request_uri ~* "(/wp-admin/|/wp-login.php|/cart/|/checkout/|/my-account/)") {
set $skip_cache 1;
}
if ($cookie_wordpress_logged_in) {
set $skip_cache 1;
}
if ($cookie_woocommerce_cart) {
set $skip_cache 1;
}
location / {
proxy_pass http://127.0.0.1:9000; # PHP-FPM przez FastCGI lub backend
# Aktywuj strefę cache
proxy_cache MICRO;
# Klucz cache — uwzględnia schemat, hosta i URI
proxy_cache_key "$scheme$host$request_uri";
# TTL per kod HTTP
proxy_cache_valid 200 301 1s; # Sukces i redirect — micro-cache 1 sekunda
proxy_cache_valid 404 1m; # Nie znaleziono — 1 minuta
proxy_cache_valid any 0s; # Pozostałe — nie cachuj
# Bypass i pomijanie cache
proxy_cache_bypass $skip_cache;
proxy_no_cache $skip_cache;
# Dodaj nagłówek informujący o statusie cache
add_header X-Cache-Status $upstream_cache_status;
# Standardowe nagłówki proxy
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
} X-Cache-Status — diagnostyka cache
Nagłówek X-Cache-Status (lub X-Nginx-Cache) pozwala zobaczyć co
Nginx robi z każdym żądaniem:
| Wartość | Znaczenie |
|---|---|
HIT | Odpowiedź serwowana z cache — backend nie był odpytywany |
MISS | Cache nie miał tej odpowiedzi — żądanie trafiło do backendu i zostało zapisane |
BYPASS | Cache pominięty przez proxy_cache_bypass (np. zalogowany użytkownik) |
EXPIRED | Wpis w cache istniał, ale wygasł — backend odpytany, cache odświeżony |
STALE | Serwowany stary wpis (np. gdy backend jest niedostępny i włączono proxy_cache_use_stale) |
UPDATING | Cache jest odświeżany w tle (proxy_cache_background_update) |
# Sprawdź status cache dla strony curl -I https://example.com/ | grep X-Cache-Status # X-Cache-Status: HIT # Pierwsze żądanie po wygaśnięciu curl -I https://example.com/ | grep X-Cache-Status # X-Cache-Status: MISS
fastcgi_cache — bezpośredni cache dla PHP-FPM
Jeśli Nginx komunikuje się z PHP-FPM przez FastCGI (bez pośredniego proxy), użyj
fastcgi_cache zamiast proxy_cache:
# /etc/nginx/nginx.conf — blok http
fastcgi_cache_path /var/cache/nginx/fastcgi
levels=1:2
keys_zone=FASTCGI:10m
inactive=60s
max_size=1g; # /etc/nginx/sites-available/wordpress.conf
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Aktywuj fastcgi_cache
fastcgi_cache FASTCGI;
fastcgi_cache_key "$scheme$host$request_uri";
fastcgi_cache_valid 200 1s;
fastcgi_cache_valid 404 1m;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
add_header X-Cache-Status $upstream_cache_status;
} Purge cache — moduł nginx-cache-purge
Przy micro-cache TTL=1s purge jest rzadko potrzebny, ale przy dłuższym TTL (np. 60s) może
być konieczny po zapisaniu nowego wpisu na blogu. Nginx nie ma wbudowanego purge — potrzebny
jest moduł ngx_cache_purge:
# Ubuntu: nginx-extras zawiera ngx_cache_purge
sudo apt install nginx-extras
# Konfiguracja purge endpointu (dostępny tylko z localhost)
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge MICRO "$scheme$host$1";
} # Purge konkretnego URL (z serwera) curl -X PURGE http://localhost/purge/wp-content/uploads/2026/04/obraz.jpg # Odpowiedź: Successful purge # Weryfikacja — następne żądanie powinno dać MISS curl -I https://example.com/artykul/ | grep X-Cache-Status
Nginx micro-cache vs Varnish vs Redis page cache
| Rozwiązanie | TTL | Purge | Złożoność | Kiedy używać |
|---|---|---|---|---|
| Nginx micro-cache | 1s – 60s | Wymaga modułu | Niska | Ochrona przed skokami ruchu, WordPress |
| Varnish + VCL | Minuty/godziny | Natywny (PURGE) | Wysoka | Długi TTL, ESI, selektywna inwalidacja per-tag |
| Redis page cache | Minuty/godziny | Przez plugin/kod | Średnia | WordPress (WP Super Cache, W3TC), aplikacje PHP |
| LiteSpeed Cache | Minuty/godziny | Natywny | Niska (plugin WP) | Hosting LiteSpeed (LH.pl, home.pl) |
Kiedy micro-cache nie wystarczy?
- Spersonalizowane treści per użytkownik — micro-cache nie działa gdy każdy użytkownik widzi inne dane (dashboard, koszyk). Użyj ESI (Varnish) lub pomijaj cache dla zalogowanych.
- Dane wymagające natychmiastowej aktualności — kursy walut, stan magazynowy na żywo. TTL=1s może być za długi — rozważ Server-Sent Events lub WebSocket.
- Bardzo duże odpowiedzi API — cachowanie kilkudziesięciu MB JSON na dysku jest nieefektywne. Rozważ Redis z TTL po stronie aplikacji.
- Ruch HTTPS z unique tokens w URL — jeśli każdy URL jest unikalny (np. CSRF token w query string), cache key nigdy nie trafi. Przenieś tokeny do nagłówków lub ciasteczek.