Skip to main content
WordPress 20 August 2026 13 min read

WordPress 7.1 Speculative Loading: What Actually Shipped, and Why It's Now a Hosting Decision

WordPress 7.1 was supposed to speed up prerendering by itself on well-cached sites. That is not what shipped. What landed instead is a lever only your host can pull, and the caching test behind the deferred idea cannot see most of what makes hosting fast.

MM
Mark McNeece Founder & Managing Director, 365i
WordPress 7.1 Speculative Loading title card: a stack of browser windows in perspective, the front one prefetching a page at 90 per cent, with a cursor hovering an About Us link and a speedometer and server icons alongside.

WordPress 7.1 landed on 19 August 2026, on the last day of WordCamp US. Under the responsive styling headlines sits a single line about performance: "Speculative loading defaults can now be configured via environment variables and constants."

That is not the change most of this week's coverage promised. The June roadmap described something more ambitious, and a lot of roundups have repeated it as though it shipped.

The short version: WordPress 7.1 did not teach itself to speed up on well-cached sites. What it shipped is a manual lever, and that lever lives in wp-config.php or the server environment, which is hosting territory rather than anything you will find in your dashboard. Below we go through what actually landed, what beats what when several things try to configure speculative loading at once, and why the caching test behind the deferred idea would have been a poor measure of hosting quality anyway. We covered 7.1's responsive styling and hover states before the beta, and this is the other half of the release.

What WordPress 7.1 Actually Shipped for Speculative Loading

Start with what was announced, because the gap is the story. The Roadmap to 7.1, published on 19 June, put it like this:

"The core performance change planned for 7.1 is an update to speculative loading: when both object caching and page caching are detected, the default eagerness would move from conservative to moderate, prefetching and prerendering more readily on sites equipped to handle it so navigation feels faster."

Roadmap to 7.1, Make WordPress Core, 19 June 2026

Read it again and notice the tense. "Planned for" and "would move". That is a proposal, and the roadmap was honest about being one. By the time Release Candidate 1 arrived on 5 August, the only speculative loading entry was the environment variable line quoted above. Caching is not mentioned in that announcement at all.

The shipped code settles it. Here is wp_get_speculation_rules_default_configuration(), which is new in 7.1 and is where the default now comes from:

function wp_get_speculation_rules_default_configuration(): array {
	$default_mode = 'prefetch';
	$mode         = wp_get_speculative_loading_override( 'WP_SPECULATIVE_LOADING_DEFAULT_MODE' );
	if ( WP_Speculation_Rules::is_valid_mode( $mode ) ) {
		$default_mode = $mode;
	}

	$default_eagerness = 'conservative';
	$eagerness         = wp_get_speculative_loading_override( 'WP_SPECULATIVE_LOADING_DEFAULT_EAGERNESS' );
	if (
		WP_Speculation_Rules::is_valid_eagerness( $eagerness ) &&
		// 'immediate' is a valid eagerness, but for safety WordPress does not allow it for document-level rules.
		'immediate' !== $eagerness
	) {
		$default_eagerness = $eagerness;
	}

	return array(
		'mode'      => $default_mode,
		'eagerness' => $default_eagerness,
	);
}

Prefetch and conservative are written in as literals. The only thing that moves them is one of the two overrides. There is no call to wp_using_ext_object_cache(), no Site Health check, nothing that looks at your caching at all. The same is true of wp_get_speculation_rules_configuration(), whose 7.1 changelog entry records the constants and nothing else.

So the automatic upgrade did not ship. If you have read this week that WordPress 7.1 speeds itself up when it spots your object cache, that came from the roadmap rather than from the release. WordPress 7.1 speculative loading behaves exactly as 6.8 left it, unless somebody deliberately changes it.

We are not being smug about this. Our own 7.1 preview in July was written from Beta 1, and we flagged at the time that the inherited-styles indicator on the roadmap was not in the build. Checking the roadmap against the shipped source is the whole job, and it is the step most release coverage skips.

Why WordPress Ships Prefetch at Conservative Eagerness

Speculative loading arrived in WordPress 6.8 in April 2025. The browser is handed a set of rules describing which links to fetch early, and how keen to be about it. Get it right and the next page is already sitting there when the visitor clicks. Get it wrong and you have paid for pages nobody opened.

Two dials control it. Mode is prefetch or prerender: prefetch pulls the document down, prerender builds the whole page in a hidden tab including running its JavaScript. Eagerness decides how strong a hint the browser waits for before it acts.

Speculation rules eagerness levels and what triggers them
Eagerness Desktop trigger Mobile trigger WordPress default?
Conservative Pointer or touch down, so the click has effectively begun Pointer or touch down Yes, still, in 7.1
Moderate Hovering a link for 200ms Viewport heuristics, from 500ms after scrolling stops No
Eager Hovering a link for 10ms 50ms after the link enters the viewport No
Immediate As soon as the rules are read As soon as the rules are read Blocked by core for document rules

Conservative is the cautious end on purpose. The 6.8 announcement spelled out the reasoning: the default "is in line with the configuration that Cloudflare uses in its speculative loading feature, and it minimizes the chance of any speculative loads without a subsequent navigation to the URL."

Felix Arntz, who works on browser APIs at Google and carried this feature through the WordPress Performance Team, was blunter about why in his write-up of how the feature reached core:

"For WordPress Core, however, we would later opt for a more conservative default (prefetching with 'conservative' eagerness) to ensure resourcefulness at scale. At the massive scale of WordPress (impacting over 40% of the web), this was a safer starting point."

Felix Arntz, Google, 22 May 2025

I have configured speculative loading on my own WordPress sites since 6.8 shipped, and wrote up a full guide to it on 16 April 2025, the day after 6.8 shipped. Reading Felix's line a year later reframed something I had got slightly wrong at the time. I had been treating eagerness as a performance setting, the way you treat an image quality slider, where higher is better until it looks bad. It isn't. It is a bet on your visitors' behaviour, paid for by your server, and the odds change with your traffic and your hosting. Sixteen months of running it on real sites has moved me from "turn it up" to "turn it up if you know what your origin does under load", which is a duller position and a more honest one.

The Speculative Loading Lever Only Your Host Can Pull

What did ship is worth having. WordPress 7.1 reads two values, either as environment variables or as constants of the same name:

// wp-config.php, above the "That's all, stop editing!" line

// prefetch (default) or prerender
define( 'WP_SPECULATIVE_LOADING_DEFAULT_MODE', 'prerender' );

// conservative (default), moderate or eager
define( 'WP_SPECULATIVE_LOADING_DEFAULT_EAGERNESS', 'moderate' );

The resolution order mirrors WP_ENVIRONMENT_TYPE: WordPress reads the environment variable through getenv(), and a constant of the same name overrides it. Set something WordPress does not recognise and it falls back to the core default rather than erroring. immediate is a real eagerness value in the browser API, but core refuses it for document-level rules, which is a sensible piece of paranoia.

Notice where this lives. Not in Settings. Not in a plugin panel. In wp-config.php or the server environment, which on managed WordPress hosting is the host's territory. That is the point of it: a host can now set a sensible default across a whole fleet without shipping a must-use plugin to every site on it.

The honest caveat is that most hosts will never touch it. It is opt-in, it is invisible, and it carries a support risk if a host turns it up on a customer whose site cannot absorb the load. For the overwhelming majority of WordPress sites, nothing about 7.1 changes how speculative loading behaves. It stays on prefetch at conservative eagerness, exactly as it has since 6.8.

What Beats What: Host Constant, Filter and Merged Speculation Rules

Three layers can now have an opinion about speculative loading, and they do not all resolve the same way.

Three glossy UI panels stacked in perspective: a server panel at the bottom, a plugin settings panel above it, and a browser window at the top in which two rule sheets flow together into one, with an arrow rising alongside.
The host constant sets what the default resolves to. An explicit value passed through the filter beats it. The browser then merges every rule set it is given rather than picking one.

The host constant sets the default. It changes the value WordPress falls back to when nothing else has decided.

The wp_speculation_rules_configuration filter beats the constant. This filter has existed since 6.8 and receives an array with mode and eagerness keys, or null to switch speculative loading off entirely. Anything supplying an explicit value through it, whether that is a snippet in your theme, a must-use plugin, or a performance plugin exposing the setting in its own UI, wins over whatever the host configured. Several popular performance plugins expose exactly these two dials, Perfmatters among them, so a site owner who set them a year ago has already answered this question without knowing a host lever was coming.

That interaction is derived from two documented mechanisms rather than measured. The constant sets the default; the filter overrides the default; therefore an explicit filter value overrides the constant. We have not tested it on 7.1, and we would rather say so than dress a deduction up as a finding.

The browser merges, it does not choose. This one surprises people. If WordPress emits a speculation rules block and a plugin or CDN emits another, the browser does not pick a winner. The HTML Standard says a parsed rule set is appended to "document's speculation rule sets", and the same wording covers rules delivered by the Speculation-Rules HTTP header. Every valid rule set applies. So two components each politely configuring "moderate" can produce more speculation than either intended, and an exclusion added in one rule set does nothing about links another rule set is happily prerendering.

What WordPress's Caching Test Can Actually See

The deferred idea deserves a look, because it may come back in a later release and because the threshold it proposed is the interesting part.

It would have keyed on two Site Health tests. Object caching is the simpler one, and it is the one that matters here: WordPress decides you have a persistent object cache by calling wp_using_ext_object_cache(), which comes down to whether an object-cache.php drop-in file exists in wp-content. Page caching is checked by looking for a known page cache plugin, then making three loopback requests to the homepage, sniffing for client caching headers and comparing median response time against a threshold.

A browser panel casting a narrow beam of light that reaches only one small file card, while a much larger server rack, database and globe sit unlit outside the beam.
WordPress can see a drop-in file inside its own directory. Edge caching, server-level page caching and the database layer underneath it all sit outside that view.

Both tests measure what WordPress can see from inside PHP. That is not the same thing as how fast your hosting is.

A site behind serious edge caching and server-level page caching, on fast hardware, can have no object-cache.php drop-in at all and be judged not equipped. A site running Redis on a cheap, overloaded VPS has the drop-in, passes, and is judged equipped. The test does not rank those two correctly, and it was never designed to. It answers "is there a persistent object cache wired into WordPress", which is a useful question with a different subject.

This is not a comfortable point for us to make, so here is our own stack held against it. StackCache, the caching layer on our WordPress plans, is a multi-layer arrangement covering object, page and CDN. Redis object caching is a Managed Cloud Servers feature rather than something on the shared plans, and where it is in play the difference you notice first is moving around the WordPress dashboard, because the repeat database reads the admin makes constantly stop hitting the database. Our Turbo plan does CDN pre-caching, so a page can be sitting at the edge before anyone has asked for it, which is about as far from "not equipped" as caching gets and is completely invisible to a test that inspects wp-content.

Which leaves a real product question rather than a rhetorical one. If a future release does grade hosting by the presence of a drop-in file, every host has to decide whether to ship one by default so that core reaches the right conclusion about them. That is a slightly absurd thing to optimise for, and it is also exactly what will happen. We would rather the test got better than that hosts learned to game it, and we have not decided what we would do.

Speculation Rules Exclusions and the API Endpoint Trap

Whatever eagerness you land on, exclusions are where speculative loading actually goes wrong, and the failure mode is not the one people expect.

WordPress speculation rules exclude a sensible baseline before any filter runs: /wp-*.php, /wp-admin/*, and the uploads, content, plugins, template and stylesheet directories. On pretty permalinks it also drops any URL carrying a query string. Without pretty permalinks it narrows that to URLs with a nonce parameter, which is the important half. Speculative loading is off entirely for logged-in users and for sites without pretty permalinks. You extend the list with wp_speculation_rules_href_exclude_paths:

add_filter(
	'wp_speculation_rules_href_exclude_paths',
	function ( array $paths, string $mode ): array {
		$paths[] = '/basket/*';
		$paths[] = '/checkout/*';

		// Prerendering runs the page. Be stricter about it than prefetch.
		if ( 'prerender' === $mode ) {
			$paths[] = '/my-account/*';
		}

		return $paths;
	},
	10,
	2
);

Here is our own production rule set, with a caveat that matters: 365i.co.uk is not a WordPress site. It is hand-built PHP, CSS and JavaScript, so these rules are hand-written in our footer template rather than generated by core. It is not evidence of how WordPress behaves. It is what we decided when we had to make the same judgement call with nothing deciding it for us:

<script type="speculationrules">
{
    "prerender": [{
        "where": {
            "and": [
                { "href_matches": "/*" },
                { "not": { "href_matches": "/news/api/*" } },
                { "not": { "href_matches": "/tools/api/*" } },
                { "not": { "selector_matches": "[target=_blank]" } }
            ]
        },
        "eagerness": "moderate"
    }]
}
</script>

Prerender at moderate, with three carve-outs. The [target=_blank] one is housekeeping: a link that opens in a new tab is a poor prediction of the next page in this one.

The two API exclusions are the transferable lesson. /news/api/* and /tools/api/* are endpoints, not pages. Prerendering does not fetch a URL politely and sit on it. It loads the page and runs its JavaScript. Point that at anything that does work when it is requested rather than just handing back a document, and the browser will do that work on a guess, before any human has decided to go there. Search handlers, anything that increments a counter, anything that queues a job, anything metered per call: none of it belongs in a prerender rule.

Nobody warns about this, because the guidance concentrates on wasted bandwidth. Wasted bandwidth is the mild version. Executed side effects are the real one, and if your site exposes endpoints under paths that also serve pages, a broad href_matches pattern will find them. That is why we wrote the rule as allow-everything-then-subtract and went looking for what to subtract, rather than trusting a wildcard to be sensible.

Does Speculative Loading Slow Down Your Server?

It can, and the answer turns entirely on eagerness and mode.

A glossy speedometer with three zones and the needle resting at the lowest position, with a clicking cursor, an open hovering hand and a lightning bolt on chips above the three zones.
WordPress still ships with the needle on the lowest notch. Raising prerender eagerness buys speed with backend requests for pages nobody has chosen to visit.

At conservative, a speculative load happens once the visitor has already begun the click, so almost every one of them gets used. At moderate, a 200ms hover is enough, and people hover over links they never click. At eager, 10ms of hover will do it, and on mobile a link merely arriving in the viewport is enough.

Every one of those is a request. If your pages are served from cache, they are cheap. If they are not, each one is a full WordPress page build: PHP, database queries, the lot. Chrome's own documentation does not soften this: "Over-speculation has a clear cost to users for bandwidth, memory, and CPU costs, but also for sites themselves", alongside the plain instruction to "only prerender when there is a high likelihood of the page being navigated to."

That line changed how I explain this to people. The instinct in performance work is that anything making the page appear faster is a win, because the metric you are watching improves. Speculation breaks the instinct, because the metric improves for the visitor while the bill lands somewhere you are not looking. It is the first performance feature I have worked with where the honest answer to "should I turn this up" starts with a question about the server rather than about the visitor.

Which is also why the traffic figure people quote about their own site stops being the useful one. Speculative loading means your origin serves page builds that no human requested, so "how many visitors do I get" and "how much load do I generate" quietly become different questions. Our WordPress hosting plan advisor asks about traffic in human visits for exactly that reason, because that is the number people actually know, and the load a site generates has to be reasoned about separately.

What Speculative Loading Doesn't Fix

Worth being clear about the boundaries, because this feature attracts more enthusiasm than it earns.

  • It is Chromium-only in practice. Chrome and Edge support it, Firefox does not, and Safari has it behind a flag. A large slice of your mobile traffic will never see any of this.
  • It does nothing for first impressions. Speculative loading speeds up the second page a visitor sees. The one they arrive on, which is the one search engines measure and the one that decides whether they stay, is untouched.
  • It is not a substitute for a fast origin. Prerendering a slow page produces a slow prerender that happened to start earlier. If your pages take four seconds to build, this buys you a head start on four seconds.
  • It does not help logged-in users at all. Core disables it for them, so your admin experience, which is where slowness is most annoying, is out of scope. That is where an object cache earns its keep instead.
  • Analytics can drift. A prerendered page runs its JavaScript. Tags that fire on load without checking for prerendering can count views nobody had.

And the honest disclosure: we have not tested WordPress 7.1 yet. Everything above comes from the shipped source, the release announcements and the browser specifications, not from a build we have run. We will report back once we have put it through the same testing we ran before 7.0, and we would rather say that now than let the phrasing imply hands-on experience we do not have.

Speculative Loading Is a WordPress Hosting Question

Strip away the constant names and this release quietly reframed the feature. From 6.8 to 7.0 it was something a site owner configured. From 7.1 it is something a host can set, a plugin can override, and a browser will merge with whatever else is on the page. The interesting question moved from "which eagerness is best" to "can this origin absorb requests for pages nobody chose to visit".

That question has a hosting answer rather than a plugin answer. It depends on whether your pages are served from cache or rebuilt on demand, whether there is an edge in front of you, and what happens on the tenth simultaneous uncached build rather than the first.

What we can point at with confidence is the platform record rather than any 7.1 claim. When WordPress 7.0 shipped in May, we let it flow to our cohort normally instead of holding the update, on the strength of release-candidate testing on two of our own sites. Hundreds of sites upgraded. Zero support tickets, zero rollbacks, zero white screens, and those three zeros still held five days later under normal production traffic. That is a WordPress 7.0 record and nothing more, but it is why we are relaxed about 7.1, and it is a real number rather than a promise. The same thinking sits behind our piece on whether hosting is ready for WordPress AI agents, which is the other place this platform-capacity question keeps surfacing.

If you want the wider performance picture rather than this one feature, our sister site has a plain-English explainer on what Core Web Vitals actually measure, and Press Forge has a practical run-through of ten ways to speed up a WordPress site covering the unglamorous work speculative loading cannot replace.

Frequently Asked Questions

What changed for speculative loading in WordPress 7.1?

Two new overrides, WP_SPECULATIVE_LOADING_DEFAULT_MODE and WP_SPECULATIVE_LOADING_DEFAULT_EAGERNESS, which can be set as environment variables or as constants in wp-config.php. They change what WordPress falls back to when nothing else has configured speculative loading. The default itself is unchanged at prefetch with conservative eagerness.

Does WordPress 7.1 switch to moderate eagerness when it detects caching?

No. That was proposed in the June roadmap and did not ship. The function producing the default in 7.1 hardcodes prefetch and conservative, and changes them only via the two new overrides. There is no object cache or page cache detection anywhere in the speculative loading code path.

Does speculative loading slow down my server?

At the WordPress default of conservative eagerness, barely, because the visitor has already begun clicking. Move to moderate or eager and your server starts building pages for visits that never happen, triggered by a 200ms hover or a link scrolling into view. On cached pages that is cheap. On uncached pages each one is a full WordPress page build.

What is the difference between prefetch and prerender?

Prefetch downloads the document and stops. Prerender loads the page in a hidden tab and runs its JavaScript, so it is close to instant on click but does real work in advance. Prerender is the one that can cause side effects, which is why endpoints and anything that changes state should be excluded from it.

Can a plugin override my host's speculative loading setting?

Yes. The host constants set the default, and the wp_speculation_rules_configuration filter overrides the default, so anything supplying an explicit mode or eagerness through that filter takes precedence. Several performance plugins expose those two settings directly. This follows from the two documented mechanisms rather than from testing on 7.1.

What happens if two plugins both add speculation rules?

Both apply. The HTML Standard appends each parsed rule set to the document's list rather than replacing the previous one, and rules delivered by the Speculation-Rules HTTP header join the same list. An exclusion in one rule set does not restrain links that another rule set is prerendering.

Which browsers support WordPress speculative loading?

Chrome and Edge, from version 109 for prerendering and 121 for the eagerness setting. Firefox does not support it and Safari has it behind an experimental flag. Visitors on unsupported browsers see the site exactly as they would have done, so there is no penalty, but there is no benefit either.

Which URLs should I exclude from speculative loading?

Anything that does work when it is requested rather than returning a document: API endpoints, search handlers, counters, anything metered per call, and basket or checkout paths on a shop. WordPress already excludes wp-admin, its own PHP files, the uploads and plugin directories, and URLs with query strings on pretty permalinks. Add your own with the wp_speculation_rules_href_exclude_paths filter.

The eagerness question has a hosting answer

Whether you can afford to prerender comes down to what happens at your origin when requests arrive for pages nobody chose. 365i WordPress hosting runs current PHP with multi-layer StackCache, one-click staging and 30 days of Timeline Backup restore points. Moving to us is free through the Migration Centre, which you run yourself, whenever you like.

Explore WordPress Hosting

Sources and further reading