Everything on your page arrives over a connection, compressed by some algorithm, from a server with a certain amount of capacity, possibly out of a cache. That layer sits beneath all the front-end work, and when it is wrong, no amount of image optimization compensates.

Advertisement. We earn a commission if you sign up through this link, at no extra cost to you.
Four things live here: which protocol you speak, how you compress, what you cache, and whether the machine is big enough.
Protocols: HTTP/2 and HTTP/3
Under HTTP/1.1, a browser could only fetch a few things at a time per connection, which is why an entire era of optimization advice was about combining files and spreading assets across subdomains.
HTTP/2, standardized in 2015, fixed that with multiplexing — many requests over one connection — plus header compression and server push, since abandoned. This is the version that made file-concatenation advice obsolete, and if you are on modern hosting with HTTPS, you almost certainly have it.
HTTP/3, standardized as RFC 9114 in June 2022, moves from TCP to QUIC, which runs over UDP. Three things follow:
Faster connection setup. QUIC combines the transport and TLS handshakes. A first connection needs one round trip instead of two or three; a repeat connection can be zero.
No transport-level head-of-line blocking. Under HTTP/2, a lost packet stalls every stream on the connection, because TCP guarantees ordering across all of them. QUIC keeps streams independent, so a lost packet affects only its own stream.
Connection migration. Switching from wifi to mobile data keeps the connection alive instead of renegotiating it.
Honest assessment, because this gets oversold: on a good fixed connection the difference between HTTP/2 and HTTP/3 is small — often within noise. The gains are real and sometimes large on lossy networks: mobile data, congested wifi, long-distance routes. If a meaningful share of your visitors are on phones or far away, it matters. If everyone is on office fiber nearby, it is a checkbox, not a project.
Enabling it is usually one toggle. Cloudflare and most CDNs have a switch. Managed hosts increasingly have it on by default. On your own server it means a recent nginx built with QUIC support, or LiteSpeed, or Caddy — which does it without configuration. Check yours at any HTTP/3 test tool, or in DevTools by adding the Protocol column to the Network panel and looking for h3.
Compression
Text compresses extraordinarily well. HTML, CSS, JavaScript, JSON and SVG routinely shrink by 70 to 80 percent, which makes this one of the highest-return settings on a server.
Gzip is the universal baseline. Every browser has supported it for two decades. If you have nothing else, have this.
Brotli typically achieves 15 to 20 percent better compression than gzip on text, and has been supported by every major browser since around 2017. It is the current sensible default. The one thing to know: Brotli has quality levels 1 to 11, and level 11 is very slow to compress. Use high levels for static files compressed once at build or deploy time, and a middle level for dynamic responses compressed on every request.
Zstandard is the newer option — comparable ratios to Brotli at substantially faster compression. Chrome added support for it as a content encoding in 2024 and other browsers have followed, but server-side support is still catching up. Worth knowing about; not yet worth restructuring anything for.
What not to compress: images, video, and fonts in WOFF2. These are already compressed, and running them through gzip spends CPU to make them very slightly larger.
Check what you have by looking at the content-encoding response header in DevTools. If it says gzip and your stack supports Brotli, that is a free improvement across every text file you serve.
Caching, in layers
Caching is not one thing. On a WordPress site there are four distinct layers and they fail in different ways.
Browser cache
Assets the visitor already has, kept locally. Controlled by response headers:
Cache-Control: public, max-age=31536000, immutable # versioned assets
Cache-Control: public, max-age=0, must-revalidate # HTML
The rule that makes this safe: cache aggressively only what has a version in its filename. A file named style.a1b2c3.css can be cached for a year because changing it produces a different name. A file named style.css cannot, because you have no way to tell the browser it changed.
Getting this wrong in the other direction is the most common cause of “I updated the site and it looks broken for some people and fine for me”.
Page cache
The generated HTML, stored so WordPress does not rebuild it for every visitor. This is the largest single improvement available to a WordPress site — the difference between a page that runs PHP and database queries on every request and one that serves a file.
LiteSpeed Cache, WP Rocket, W3 Total Cache and most host-level caches all do this. Exclude cart, checkout, account and any logged-in view.
Object cache
Database query results held in memory, in Redis or Memcached, so repeated queries do not hit MySQL. WordPress has a built-in object cache that only lives for one request; a persistent one makes it survive between requests.
This matters most for logged-in and dynamic traffic — exactly the pages a page cache cannot help. On a WooCommerce store or a membership site, a persistent object cache is often the single biggest server-side win.
OPcache
Compiled PHP bytecode, held in memory so PHP does not reparse every file on every request. It is on by default in most modern PHP installations and worth confirming, because the improvement is substantial and the cost is nothing.
How much server do you actually need
Underspecified hosting produces a specific signature: the site is fine when quiet and falls apart under load, and Time to First Byte swings wildly between requests.
The constraint on a PHP site is usually not CPU or RAM but PHP workers — how many requests can be processed simultaneously. When they are all busy, further requests queue, and queueing shows up as latency that no front-end work touches. Budget shared hosting often provides two or three workers, which is fine until anything happens.
What to look at before spending money:
TTFB under load versus at rest. If it is 300 milliseconds quiet and 3 seconds busy, you have a capacity problem, not a code problem.
The database. Query Monitor will show slow queries and their count. A page running 400 queries is a plugin problem that no server upgrade fixes economically.
Whether caching is actually on. A great many “we need a bigger server” conclusions are really “page caching was never enabled”. Check first; it is free.
The order that saves the most money: enable page caching, add a persistent object cache, fix the worst queries, and only then buy more machine. Upgrading hosting to compensate for an uncached site works, and it is the most expensive way to solve the problem.
Dynamic content, which cannot be cached the easy way
Personalized pages — a logged-in dashboard, a cart with items in it — cannot be served from a shared cache. The usual approaches:
Cache the page, load the personal part separately. Serve cached HTML with a placeholder, fill in the user-specific fragment with a small request afterward. Fast for everyone, and the personal data stays personal.
Cache fragments. Store the expensive shared parts — a product grid, a navigation tree — and assemble the page around them.
Vary the cache by user segment. Separate cached copies per logged-out, member, admin. Works while the number of segments is small; becomes unmanageable quickly.
The general principle: cache the shared thing, not the personal thing, and keep the boundary between them explicit.
The short version
Turn on HTTP/3 if it is a toggle and do not expect miracles on good connections. Serve Brotli instead of gzip. Set long cache lifetimes only on versioned filenames. Enable page caching, add a persistent object cache if you have logged-in traffic, and confirm OPcache is on. Then measure TTFB under load — and if it is bad, check whether caching is actually running before concluding you need a bigger server.
A service worker can add a further caching layer above all of this, with a different set of trade-offs and a real risk of serving stale pages. PWAs and service workers covers when that is worth taking on.
Working through this list on your own site and would rather not? That is what an Expert Web Audit is for.

Advertisement. We earn a commission if you sign up through this link, at no extra cost to you.





