Started building with WordPress
Focused on WooCommerce performance
Lead e-commerce engineering at Merida.
By the end you'll know how to design cache layer by layer, how to measure it, and how to not blow up your store. No theory for theory's sake, but real examples, live demos, and debugging real cache misses.
Different layers jobs. Where each one lives and what it's allowed to hold.
Load tests and the headers that tell you HIT or MISS. No guessing, no vibes.
The things you must never serve stale and how cache quietly corrupts them.
What's not here: selling you a one-click plugin. There is no magic checkbox.
Every layer gets weighed on the same three lenses:
Lock these in now - every layer that follows speaks this language.
Some routes must always be a MISS, as they're personal, live, and can never be shared:
Three places tell you HIT or MISS.
Measure the baseline first. You can't improve a number you've never looked at.
A 4-hour TTL means every warmed page expires 6× a day — so keeping them all warm costs 5,200 × 6 rebuilds.
Scan for the goodies
Without OPcache, every request recompiles all of WordPress + WooCommerce from scratch.
Clean up autoload first. Then cache what's actually left.
NOT A DATABASE
If you’re querying it like a table, it probably belongs in a custom table.
| Transient | Object cache | Custom table | |
|---|---|---|---|
| Scope | One value, with a TTL | Any read, app-wide | Structured rows |
| Persistence | Until TTL or flush | Until evicted | Permanent |
| Invalidation | TTL or delete | Key delete / flush | You own it (SQL) |
| Reach for it | Cheap to recompute, rarely changes | Hot reads, shared across requests | You query it like data |
Full HTML, served straight off disk or RAM. The single biggest jump on the whole list.
WP_CACHE = true.
uses PHP
advanced-cache.php runs early and checks disk for a cached file.
uses PHP
It still runs PHP and loads WordPress just a little — enough to find the file. Server-level cache, next, runs none at all.
These are deliberate MISSes — by design, not by accident.
When any of these are present, the visitor has state. Skip the page cache and serve fresh.
On an edge HIT, the request NEVER REACHES OUR SERVER AT ALL - the edge answers, the origin stays idle.
One missed bypass = a cart leaking between users. Get this rule right.
Which all leads straight to the parameters problem.
Edge Inspector
edge-inspector.zadorozny.rocks
Lab PSI tests the clean URL - 98. The field sees the param-MISS reality. The backend was never fast; the cache was just hiding it.
Monitor your URL params. A high cache hit ratio is what protects your field CWV.
Which is the whole invalidation problem - and we'll come back to it.
Scan for the goodies
| Header | What it tells you | Layer |
|---|---|---|
| x-cache | HIT or MISS at the page cache | Page |
| age | Seconds since this copy was stored | Any |
| cf-cache-status | HIT / MISS / DYNAMIC / BYPASS | Edge |
| x-fastcgi-cache | nginx FastCGI HIT or MISS | Server |
| Woo event | Strategy | Action |
|---|---|---|
| Price / stock change | Event | Purge the product + its listings now |
| New order | Event | Purge stock-sensitive pages |
| Theme / plugin update | Event | Purge everything - output can change site-wide |
| New blog post | TTL | Let it expire - minutes are fine |
| Nothing changed | TTL | Ride the TTL, no purge |
Scan for the goodies
Scan for the goodies