NGINX caching

How to set up page caching to speed up your site and reduce server load.

When a website receives high traffic, the server quickly spends resources generating pages repeatedly. NGINX caching allows serving pre-generated responses from memory or disk, dramatically improving response time and offloading PHP and the database.

NGINX can cache:

  • static files (CSS, JS, images)
  • dynamic pages (PHP/CMS responses)
  • error pages (404, 502, etc.)

On VPS and dedicated servers, you have full control over NGINX configuration.

1. Setting up general proxy cache (proxy_cache)

Open the main config file /etc/nginx/nginx.conf and add this to the http { ... } block:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:32m inactive=60m max_size=2g;
  • /var/cache/nginx — cache storage folder (create it: sudo mkdir -p /var/cache/nginx)
  • levels=1:2 — directory structure for faster lookups
  • keys_zone=static_cache:32m — in-memory zone for keys and metadata (32 MB)
  • inactive=60m — files are removed if not accessed for 60 minutes
  • max_size=2g — maximum cache size on disk

Create the folder and set permissions:

sudo mkdir -p /var/cache/nginx
sudo chown www-data:www-data /var/cache/nginx

2. Simple site-wide caching (proxy_cache)

Edit or create your site config (e.g., /etc/nginx/sites-available/site.com). Example: caching all traffic via proxy:

server {
    listen 80;
    server_name site.com www.site.com;

    location / {
        proxy_pass http://127.0.0.1:8080;  # your PHP-FPM or backend port
        proxy_cache static_cache;
        proxy_cache_valid 200 301 302 60m;   # cache successful responses for 60 minutes
        proxy_cache_valid 404 1m;            # cache errors for 1 minute
        proxy_cache_methods GET HEAD;        # cache only GET and HEAD requests
        proxy_ignore_headers Cache-Control Expires Set-Cookie;
        proxy_cache_bypass $http_cookie;     # bypass cache if cookies are present
    }
}

3. FastCGI caching (for PHP responses)

To cache dynamic pages (e.g., CMS-generated content), use fastcgi_cache.

Add this to the http { ... } block in /etc/nginx/nginx.conf:

fastcgi_cache_path /var/cache/nginx-fcgi levels=1:2 keys_zone=fcgi_cache:100m inactive=60m max_size=5g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;

Create the folder:

sudo mkdir -p /var/cache/nginx-fcgi
sudo chown www-data:www-data /var/cache/nginx-fcgi

In your main server block (where PHP is handled), add caching to the PHP location:

location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;  # adjust to your PHP-FPM socket
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    fastcgi_cache fcgi_cache;
    fastcgi_cache_valid 200 301 302 60m;   # cache successful responses for 60 minutes
    fastcgi_cache_valid 404 1m;            # cache errors for 1 minute
    fastcgi_cache_bypass $http_cookie;     # bypass cache if cookies are present
    fastcgi_no_cache $http_cookie;         # do not store in cache if cookies are present
}

Useful Notes

  • Do not cache pages with authentication, personal accounts, carts, or admin areas — use fastcgi_cache_bypass and fastcgi_no_cache for those URIs.
  • For dynamic CMS (Bitrix, WordPress, etc.), cache only GET requests without cookies.
  • After any changes, test and reload NGINX:
sudo nginx -t          # check configuration
sudo systemctl reload nginx
  • Clear cache manually if needed:
sudo rm -rf /var/cache/nginx/*
sudo rm -rf /var/cache/nginx-fcgi/*

Help

If you have any questions or need assistance, please contact us through the ticket system — we're always here to help!

Need help?Our engineers will help you free of charge with any question in minutesContact us