Back to Blog

A slow website doesn’t just frustrate visitors. It costs you money. Every 100-millisecond delay in load time can reduce conversions by up to 7%. And yet, when we audit client sites, caching is one of the most neglected performance levers available.

Caching stores copies of your content at various points between your server and the user’s browser so the same data doesn’t have to be generated or downloaded twice. Implemented correctly, it can cut load times by 50-80% without changing a single line of your actual content. This post covers one piece of a bigger system, and we mapped out the rest in a plain English guide to website performance and Core Web Vitals.

Here’s how caching works at every level, what to implement, and the mistakes that trip up most site owners.

The Layers of Caching

Think of caching as a series of checkpoints between your server and your visitor’s screen. Each layer can serve content faster than the one behind it.

Browser Cache

This is the closest cache to the user. When someone visits your site, their browser downloads assets like images, CSS files, JavaScript, and fonts. With proper cache headers, the browser stores these files locally so it doesn’t have to download them again on subsequent visits or page navigations.

What it’s good for: Returning visitors and multi-page sessions. If someone browses five pages on your site, shared assets like your logo, stylesheet, and navigation JavaScript only download once.

What to cache at the browser level:

  • Images (long cache duration: months)
  • CSS and JavaScript files (long duration with cache-busting for updates)
  • Fonts (long duration, these rarely change)
  • Favicon and other static assets

Server Cache (Page Cache)

Instead of your server running PHP code, querying the database, and assembling HTML on every single request, a server-side page cache saves the fully rendered HTML. The next visitor gets that saved copy instead of triggering the entire generation process again.

For a WordPress site, this is the difference between a 2-second response and a 200-millisecond response. We’re not exaggerating. We’ve measured it.

What it’s good for: Any page that looks the same for all visitors (which is most pages on most business websites).

CDN Cache

A Content Delivery Network distributes cached copies of your site across servers worldwide. When a visitor in Chicago requests your site, they get it from a server in Chicago instead of your origin server in Virginia or wherever your hosting lives.

What it’s good for: Reducing latency for geographically distributed visitors, handling traffic spikes, and adding an extra layer of caching between users and your origin server.

Popular CDN options we work with include Cloudflare, Fastly, and AWS CloudFront. For most local business websites, Cloudflare’s free tier handles everything you need.

Application Cache (Object Cache)

This is the most technical layer. Application caching stores the results of expensive operations (database queries, API calls, computed values) in fast memory storage like Redis or Memcached. Instead of querying the database every time someone loads a page, the application checks the cache first.

What it’s good for: Dynamic sites with heavy database usage, WooCommerce stores, membership sites, and any application that performs complex queries.

Cache Headers Explained

Cache headers are the instructions your server sends to browsers and CDNs telling them what to cache, for how long, and under what conditions. Getting these right is the foundation of any caching strategy.

Cache-Control

This is the primary header for caching policy. Key directives include:

  • max-age=31536000: Cache this resource for one year (used for static assets with versioned filenames)
  • no-cache: Cache it, but revalidate with the server before using it (misleading name, since it does allow caching)
  • no-store: Don’t cache this at all (use for sensitive data like account pages)
  • public: Any cache can store this (CDN, browser, proxy)
  • private: Only the user’s browser should cache this (not CDNs. Use for personalized content)
  • s-maxage=3600: Override max-age specifically for shared caches like CDNs

ETag

An ETag is a unique identifier for a specific version of a resource. When a browser has a cached copy, it sends the ETag back to the server asking “has this changed?” If not, the server responds with a 304 Not Modified: no data transfer needed.

Best practice: Use ETags for HTML pages and API responses where content changes occasionally but you still want caching benefits.

Expires

The older predecessor to Cache-Control’s max-age directive. It sets an absolute expiration date rather than a relative duration. Cache-Control takes precedence when both are present, but including Expires improves compatibility with older systems.

Recommended Header Configurations

Static assets (CSS, JS, images with versioned filenames):

Cache-Control: public, max-age=31536000, immutable

HTML pages (mostly static business site):

Cache-Control: public, max-age=3600, s-maxage=86400

API responses or dynamic content:

Cache-Control: private, no-cache
ETag: "abc123"

Sensitive pages (checkout, account):

Cache-Control: no-store
Core Web Vitals translate engineering effort into search visibility.
Core Web Vitals translate engineering effort into search visibility.

WordPress Caching: The Full Stack

WordPress powers a huge percentage of the business websites we build and maintain. Here’s the complete caching stack for WordPress.

Page Cache

A page caching plugin generates static HTML files from your dynamic WordPress pages. Top options:

  • WP Super Cache: Simple and reliable, good for basic sites
  • W3 Total Cache: More configuration options, steeper learning curve
  • WP Rocket: Premium, but the best all-in-one solution we’ve used
  • LiteSpeed Cache: Excellent if your host runs LiteSpeed server

Page caching alone typically reduces server response time (TTFB) from 500-2000ms to under 100ms.

Object Cache

WordPress makes dozens of database queries per page load. An object cache stores query results in memory using Redis or Memcached.

  • Most managed WordPress hosts (Kinsta, WP Engine, Cloudways) offer Redis built in
  • For sites on shared hosting, the page cache matters more since you likely can’t run Redis
  • Object caching shines on WooCommerce stores and sites with logged-in users where page caching is limited

Opcode Cache (OPcache)

PHP code gets compiled into bytecode before execution. OPcache stores that compiled bytecode so PHP doesn’t have to recompile your files on every request. This is a server-level setting, not a plugin.

  • Most modern hosts have OPcache enabled by default
  • Check with your host if you’re unsure. It’s free performance
  • Typically reduces PHP execution time by 30-50%

Static Site Caching Advantages

For businesses that don’t need a CMS for daily content updates, static site generators (Astro, Next.js, Hugo, Eleventy) have a massive caching advantage: everything is pre-built at deployment time.

There’s no server-side rendering to cache. No database queries to optimize. The entire site is static HTML, CSS, and JavaScript files that can be served entirely from a CDN.

We’ve built static sites for local businesses that load in under 500 milliseconds on a 3G connection. The entire site weighs less than what some WordPress homepages load in JavaScript alone.

When static makes sense:

  • Brochure-style business websites
  • Portfolio sites
  • Landing pages
  • Documentation sites

When you still need dynamic (WordPress or similar):

  • Frequently updated blogs with non-technical editors
  • E-commerce stores
  • Membership or gated content
  • Complex forms with server-side processing

Cache Invalidation Strategies

The hardest problem in caching is knowing when to clear it. Serve stale content and users see outdated information. Clear cache too aggressively and you lose the performance benefits.

Content-Based Cache Busting

Append a hash of the file contents to the filename. When the file changes, the filename changes, and browsers automatically download the new version.

Example: styles.a1b2c3.css becomes styles.d4e5f6.css after an update. Build tools like Vite, Webpack, and Astro do this automatically.

Event-Driven Purging

Clear specific cached pages when their content changes:

  • Blog post updated? Purge that post’s cache and the blog listing page
  • Product price changed? Purge the product page and category pages
  • New testimonial added? Purge the homepage

Most caching plugins and CDNs support targeted purging through APIs or admin interfaces.

Time-Based Expiration

Set reasonable TTLs (time to live) based on how frequently content changes:

  • Homepage: 1-4 hours
  • Blog posts: 24 hours
  • Static assets: 1 year (with filename versioning)
  • API responses: 5-15 minutes

Stale-While-Revalidate

This modern cache strategy serves the cached (potentially stale) version immediately while fetching a fresh copy in the background. The user gets instant response, and the cache updates for the next visitor.

Cache-Control: max-age=3600, stale-while-revalidate=86400

This means: serve from cache for one hour, then for the next 24 hours serve stale content while revalidating in the background. After 25 hours total with no visit, force a fresh fetch.

Common Caching Mistakes

We see these constantly during site audits. Avoid them.

Caching Logged-In Pages

If your site has user accounts, WooCommerce carts, or any personalized content, you must exclude those pages from page caching. Serving one user’s cart to another user is a privacy and functionality disaster.

Fix: Exclude pages with cookies indicating a logged-in session. Most caching plugins handle this, but verify it’s working.

Caching POST Responses

Form submissions, checkout processes, and API writes should never be cached. A cached POST response means the action never actually reaches your server.

No Cache Busting on Asset Updates

You update your CSS, but visitors still see the old design because their browser cached the stylesheet for a year. This happens when you set long cache durations on assets without versioned filenames.

Fix: Always use content-based hashing in filenames or query strings for CSS and JavaScript files.

Over-Caching During Development

Developers pulling their hair out because changes aren’t showing up, usually because there’s an aggressive caching layer they forgot about. Use cache-bypassing headers in development environments.

Setting It and Forgetting It

Caching configurations need to evolve as your site changes. Adding e-commerce to a brochure site? Your caching rules need an overhaul. Launching a members-only section? Time to review what’s excluded.

Real-World Speed Improvements

Here’s what we’ve seen implementing caching strategies for client sites:

Local service business (WordPress)
Implementing page caching + CDN dropped homepage load time from 4.2 seconds to 0.9 seconds
Restaurant with online ordering
Redis object cache reduced checkout page load from 3.1 seconds to 1.4 seconds for logged-in users
Multi-location contractor
Moving to a static site with CDN achieved consistent sub-500ms loads across all 12 location pages
E-commerce store (WooCommerce)
Full caching stack (page cache + object cache + CDN + optimized headers) took the site from a 28 PageSpeed score to 89

The pattern is consistent: proper caching is the single highest-ROI performance optimization available. It costs nothing in hosting or infrastructure (CDN free tiers are generous) and delivers dramatic results.

Where to Start

If you’re not sure where your site stands, here’s the priority order:

  1. Run a speed test (Google PageSpeed Insights or GTmetrix) and note your TTFB and LCP scores
  2. Enable page caching if you’re on WordPress: this alone is transformative
  3. Set up a CDN: Cloudflare free tier takes about 15 minutes
  4. Audit your cache headers using browser developer tools (Network tab, check response headers)
  5. Implement asset versioning so you can use aggressive browser caching safely

Keep Reading

Speed like this is table stakes for converting first-time visitors. See how Dr. Samiya Hashmi’s site turns fast loads into booked consultations in the case study.

About the Author

Brian Hunter is the founder of Hunter Creative Media & Design, an Aurora, IL studio building hand-coded websites and custom web applications for small businesses across Chicago’s western suburbs. He writes about web performance, local SEO, and the software that runs small businesses. Get in touch.