Why Browser Caching Matters
Browser caching stores static files (CSS, JS, images) on user's device, eliminating repeated downloads. Result: faster repeat visits, lower server bandwidth, reduced CPU. This guide explains how to set cache headers for Nginx, Apache, and CDN integration on Hostxpeed VPS.
How Browser Caching Works
Server sends Cache-Control header (max-age=seconds). Browser stores response and reuses for specified duration. Etag (entity tag) or Last-Modified used for revalidation. Example: max-age=604800 (one week). After expiry, browser requests file with If-None-Match, server may return 304 Not Modified (no content). Proper caching reduces requests by 60-80% for repeat visitors.
Step 1: Identify Cacheable Assets
Cacheable: images (jpg, png, gif, svg, webp), CSS, JavaScript, fonts (woff2, ttf), PDFs, media files. Non-cacheable: HTML (dynamic), API responses, user-specific content. Cache duration: versioned assets (style.css?ver=1.2) can have long expiry (1 year). Unversioned: 1 day to 1 week. Usually use Cache-Control: public, max-age=31536000, immutable for versioned.
Step 2: Nginx Configuration
Add to server block: location ~* .(jpg|jpeg|png|gif|ico|css|js|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }. For HTML: location ~ .html$ { expires -1; add_header Cache-Control "no-cache, private"; }. Use map for dynamic expiration: map $sent_http_content_type $expires { default off; text/html epoch; text/css 1y; application/javascript 1y; image/* 1y; }. Then apply expires $expires. Test with curl -I http://example.com/style.css (check Cache-Control).
Step 3: Apache Configuration
Using mod_expires:
Step 4: Cache Busting for Versioned Assets
When updating CSS/JS, you want browsers to fetch new version. Use file versioning: style.css?ver=2.0 (query string) or style.2.0.css (filename). For Webpack, use content hash (main.abc123.js). Set long expiry (1 year) for these files. In HTML, reference versioned URLs. Avoid query string (some proxies don't cache). Better to rename files: gulp rev, grunt filerev. For WordPress, plugins like WP Rocket handle this.
Step 5: Testing and Validation
Browser DevTools: Network tab, refresh, see "Size" column (from disk cache or memory cache). Response headers: Cache-Control, Etag. Online tools: GTmetrix, PageSpeed Insights (caching recommendations). Check for missing expires: curl -I example.com/logo.png | grep -i cache-control. Use webpagetest.org to see repeat view load time improvement.
Step 6: Advanced: Cache Control for CDN
With Cloudflare (Hostxpeed integrated), set Cache Level to Standard, Browser Cache TTL to 1 month. Cloudflare respects origin Cache-Control. For maximal caching, use page rules: cache everything (static). But exclude admin pages. Hostxpeed includes Cloudflare Enterprise (default caching good). Additional: edge cache TTL vs browser TTL: set s-maxage for CDN.
Step 7: Handling HTTPS and Mixed Content
Cache works same for HTTPS; no special steps. Ensure all assets served over HTTPS to avoid mixed content warnings. Use scheme-relative URLs (//example.com/script.js) or enforce HTTPS redirects. Also avoid pragma: no-cache; if present, browser ignores cache.
Performance Impact Examples
WordPress site without caching: repeat view load 1.2s (8 requests). With browser caching (CSS, JS, images): repeat view 180ms (1 HTML request, others cached). Bandwidth reduction: 85%. For e-commerce product image heavy: repeat view images from cache vs re-download (2MB -> 200KB). Improved user experience and lower server cost.
Conclusion
Set long cache headers for static assets on your Hostxpeed VPS. Nginx/Apache configuration simple. Use versioned filenames for cache busting. Test with DevTools. Combined with CDN, caching reduces load time dramatically.