WordPress performance hinges on managing P99 latency. Learn how to implement request hedging to fire redundant REST API requests and keep your site fast.
When you’re running a high-traffic WordPress site, the "average" response time is a vanity metric. Your users don't care that your API responds in 50ms 95% of the time; they care about that one request that takes two seconds to finish. Last month, I was debugging a dashboard that would occasionally hang for nearly 1.5 seconds, causing a cascade of frontend timeouts. I realized that waiting for a single, potentially blocked worker thread was killing our user experience.
The solution isn't just scaling hardware; it’s architectural. We need to implement request hedging to fire a second, redundant request if the first one doesn't return within a specific threshold.
In a standard WordPress environment, PHP-FPM processes are finite. If one process is blocked—waiting on a slow database query or an external API—the request sits in the queue. By the time it times out, the user has already refreshed the page.
Request hedging works by sending the initial request and setting a timer. If the timer expires before the primary request returns, you fire a second request. You take the result of whichever finishes first and discard the other.
I initially tried to solve this by simply increasing the timeout on the client side, but that only exacerbated the load on the server. We also explored WordPress performance: Preventing Cache Stampedes with Request Coalescing to reduce database hits, but that didn't help with underlying process blocking. Hedging was the only way to bypass the "tail" of the latency distribution.
To implement this, you need a client-side orchestrator. Since WordPress REST API requests are typically initiated via JavaScript, we can handle the hedging logic in the frontend layer.
Here is a simplified pattern using Promise.race() to manage the requests:
JAVASCRIPTasync function hedgedFetch(url, options, delay = 200) { const controller = new AbortController(); const createRequest = async (isSecondary) => { const response = await fetch(url, { ...options, signal: controller.signal }); if (!response.ok) throw new Error(CE9178">'Request failed'); return response.json(); }; const primary = createRequest(false); // Create a timer to trigger the hedge const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error(CE9178">'Hedge triggered')), delay) ); try { return await Promise.race([primary, timeout]); } catch (err) { if (err.message === CE9178">'Hedge triggered') { // Fire the secondary request return await createRequest(true); } throw err; } }
Before you implement this across your entire site, you need to understand the cost.
POST, PUT, or DELETE requests unless they are strictly idempotent. Hedging a non-idempotent request will result in duplicate database entries or corrupted state.I’ve found that a delay threshold of 1.5x the P90 latency is usually the "sweet spot." If your P90 is 100ms, set your hedge delay to 150ms. If you set it too low, you’ll trigger redundant requests constantly, creating a self-inflicted DDoS attack.
If you want to get serious about REST API reliability, don't just guess the delay. Monitor your server response times and serve the hedge delay threshold via a configuration endpoint.
If you are already managing traffic using WordPress REST API Request Throttling: Adaptive Backpressure Patterns, you can dynamically adjust your hedging threshold based on current queue depth. When the server is under heavy load, increase the hedging threshold to prevent mass redundant requests. If the server is quiet, lower it to keep the UI snappy.
I’ve also experimented with using WordPress REST API Request Prioritization: Weighted Fair Queuing alongside hedging. The combination ensures that critical requests get handled first, while hedged requests act as a safety net for non-critical, slow-running background fetches.
Does this work with standard WP_Query?
Not directly. Hedging is a transport-layer pattern. It helps the client get a response faster, but it doesn't make the underlying WP_Query run faster. You still need to optimize your database indexes.
Is this safe for authenticated requests? Yes, but you must ensure your server-side code handles concurrent sessions gracefully. If you’re using session locks, hedging might actually make the latency worse by creating a lock contention race. Always test with high concurrency in a staging environment.
What if both requests fail?
Your logic should handle the catch block by displaying a graceful UI error rather than letting the application hang. Hedging is about performance, not error recovery.
Request hedging is a powerful tool, but it's not a silver bullet for poor code. If you have a slow API endpoint, fixing the underlying query or implementing proper object caching is always better than trying to "speed it up" by firing more requests at it.
I’m still experimenting with how to integrate this with server-side cancellation—if the primary request finishes, we should ideally signal the server to terminate the secondary request immediately. Right now, I'm just letting the secondary request complete and discarding the result, which is a bit wasteful. If you find a cleaner way to handle server-side termination, I’d love to hear how you handled the process signaling.
WordPress performance can be transformed by moving REST API logic to the edge. Learn how to use CDN workers to offload requests and slash origin latency.
Read moreWordPress REST API middleware using the proxy pattern allows for clean, transparent response transformation. Learn to architect scalable headless endpoints.