Configuring Expires HTTP Headers for Static Content in Nginx: File Extension-Based Cache Control


2 views

The Expires HTTP header tells browsers and proxies how long they should cache static resources. When properly configured, this significantly reduces server load and improves page load times for returning visitors.

Here's how to set expiration headers for all CSS files in your Nginx configuration:


location ~* \.css$ {
    expires 1y;
    add_header Cache-Control "public";
    access_log off;
}

You can combine multiple file extensions in a single location block using regex:


location ~* \.(css|js|jpg|jpeg|png|gif|ico|woff2|webp)$ {
    expires 365d;
    add_header Cache-Control "public, immutable";
}

For more granular control, use separate location blocks with different expiry periods:


# Images
location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
    expires 1y;
}

# CSS and JavaScript
location ~* \.(css|js)$ {
    expires 6M;
}

# Font files
location ~* \.(woff|woff2|eot|ttf|otf)$ {
    expires 1y;
    add_header Cache-Control "public";
}

When implementing long cache times, use filename versioning or query strings to force cache invalidation:


location ~* \.(css|js)$ {
    expires 1y;
    try_files $uri $uri/ /cache-bust-path/$query_string;
}

After making changes, always:

  1. Test your configuration: nginx -t
  2. Reload Nginx: nginx -s reload
  3. Verify headers with: curl -I https://yoursite.com/style.css

When serving static assets through Nginx, properly configured caching headers can significantly improve website performance. The Expires header tells browsers how long they can cache resources before needing to revalidate them.

Here's a fundamental Nginx configuration block for static files:


location ~* \.(css|js|jpg|jpeg|png|gif|ico)$ {
    expires 30d;
    add_header Cache-Control "public";
}

For more precise control, you can set different expiration periods for different file types:


location ~* \.css$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

location ~* \.js$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
    expires 30d;
    add_header Cache-Control "public";
}

When using versioned assets (like style.123456.css), you can implement aggressive caching:


location ~* \.[a-f0-9]{8}\.(css|js)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

After modifying your Nginx configuration, always:


sudo nginx -t
sudo systemctl reload nginx

Then verify headers using curl:


curl -I https://yourdomain.com/style.css
  • Don't set long expiration for frequently updated files without versioning
  • Avoid setting Cache-Control: immutable for files that might change
  • Remember to include the public directive for CDN compatibility