TL;DR
Aim for under 50 HTTP requests per page (under 25 is excellent), but treat the count as a clue, not a verdict—on HTTP/2, render-blocking, third-party, and render-path requests matter more than the raw number. Audit first, then work in order: Consolidate, defer, minimize external requests, and cache behind a CDN. Comfortable in code? Do it by hand. Prefer set-and-forget? An all-in-one like NitroPack automates the lot.
If your GTmetrix or Pingdom report just handed your WordPress site a low grade for “make fewer HTTP requests” and you’re a bit confused about what that means, you’re in the right place.
While it varies from site to site, there is an acceptable number of requests you should aim for. On a healthy page, we like to see requests under 50, and under 25 is excellent. However, plenty of WordPress sites drift well past that without their owners ever knowing why.
The fix for this involves four parts: Consolidating your files, deferring what blocks the render, minimizing external requests, and caching. We’ll walk through each, starting with how to tell what’s actually slowing you down.
Compare your GTmetrix grade against an optimized demo
By submitting, you agree to our Privacy Policy.
What are HTTP requests?
Every time your browser builds a page, it fetches the pieces it needs—the HTML, each stylesheet, every script, image, font, and embed—from a server. Each of those fetches is an HTTP request, unless the file is already cached, inlined into the page, or skipped altogether.
As you can see, requests are a normal part of the process, not the enemy. A modern page needs plenty of them to work, and the goal is to manage the count, not drive it to zero.
However, they definitely can pile up quietly. Your theme loads a stylesheet or two, every plugin adds its own scripts, social share buttons phone home to Twitter and LinkedIn, and an analytics tag or font library slips in on top. None feels heavy on its own, but together they stack.
Heads up: The HTTP Archive Web Almanac puts the 2025 median page at 77 requests on desktop and 72 on mobile—a typical page loads around 3 HTML, 4 fonts, 8 CSS, 13 images, and 23 JavaScript files, and 98.1% of pages make at least one JavaScript request.
Common HTTP request methods include:
- GET – This request is used to retrieve a resource or data from the server. For example, a browser fetching an image.
- POST – This request is used to send data to the server. For example, uploading a file or submitting a form.
- PUT – This request is used to update or replace an existing resource on the server.
- DELETE – This is used to remove data from the server.
Why minimize HTTP requests?
If requests are normal, why bother cutting them? Because each one can carry a cost.
A single request may involve connection setup, a DNS lookup, a TLS handshake, server response time, and the transfer itself—plus the browser’s own work deciding what to load and in what order. Not all of that happens per file: DNS lookups and handshakes usually happen once per origin or connection, not once per request. But the overhead adds up, and some requests hurt far more than others.
The real damage comes from render-blocking requests, slow third-party origins, oversized files, weak caching, and critical resources the browser discovers too late.
If you manage to get this right by cutting and reordering requests, you can improve your Largest Contentful Paint, which feeds straight into conversions and search rankings—site speed has been a Google ranking factor since 2010.
None of this makes the under-50 target gospel, though. A complex page that’s well managed will out-load a simple page that isn’t, and modern protocols have shifted which requests matter most. Before you change anything, you need to know what your page is actually loading—and that starts with a proper audit.
How to audit the HTTP requests on your site
This process runs in three tiers, each narrower than the last:
- Start with an external speed test for the headline number.
- Move to your browser’s developer tools to inspect requests one by one.
- Use a WordPress plugin to trace those requests back to the plugins creating them.
Keep one rule of thumb in mind throughout—if a visually simple page is firing off a high request count, something is quietly adding bloat. Let’s start at the top.
External speed test tools: Pingdom and GTmetrix
Most people land on this problem because a testing tool flagged it, so that’s where the audit begins.
Pingdom
Pingdom is the quickest way to get a headline read: Total requests, page size, load time, and a breakdown by content type or domain. Drop in your URL and the numbers come back in seconds—when we ran NitroPack’s own homepage through it, the report showed 22 requests in total.
Still, treat it as a fast synthetic check, not the final word.
GTmetrix
GTmetrix digs deeper. Its Page Details graph splits request count and byte size by type, and the Waterfall tab shows request-by-request loading so you can see exactly what fires when.
The Performance Score is Lighthouse-based, with GTmetrix’s own grading and a Structure Score layered on top. We recommend using this more as a lab diagnostic, not a perfect mirror of every real visitor’s experience.
⚠️ Important for Pingdom:
It scores using YSlow rules, which allow up to three JavaScript requests before docking four points for each extra one. That’s not a modern performance rule—under HTTP/2 and HTTP/3, several small JavaScript files can be fine if they’re cached, non-blocking, and not hogging the main thread. So a low Pingdom grade is a signal worth chasing, not a verdict. To chase it, you need to see the requests yourself.
Inspecting requests in Chrome DevTools
Your browser already has the best free request inspector built in. In Chrome, press F12 (or right-click the page and choose Inspect), open the Network tab, and refresh—every request the page makes appears in the table, with the running total at the bottom.
From there, a few columns do most of the work:
- Sort by Size to surface your heaviest files, or by Time to find the slowest ones.
- Use the Type column to split requests into Document, Stylesheet, Script, Image, Font, and XHR, so you can see which category is inflating the count.
- Right-click any column header and enable Protocol. It shows whether each request is served over h2, h3, or http/1.1—a detail we’ll come back to shortly.
DevTools tells you what is loading, but not always which plugin put it there. For that, there’s a tool built for exactly that job.
Mapping requests to plugins with Query Monitor
Query Monitor is a free WordPress plugin that does the one thing speed tests can’t: It ties requests back to the code responsible for them. Install it, and its HTTP API Calls panel—reachable from the admin bar—surfaces the server-side HTTP calls WordPress made while building the page.
One thing to know: It only records calls made during that specific page load, so reload the pages you’re worried about and trigger the actions where the slowdown actually shows up. Once you can see which plugin fires which request, you know where to aim.
However, before you start cutting, there’s a question worth settling…
Does request count still matter with HTTP/2?
Remember that Protocol column? What it shows changes how much any of this matters. If your requests come back as h2 or h3, you’re on HTTP/2 or HTTP/3—both still widely used, and both built around multiplexing, where many requests share one connection rather than queuing up.
DebugBear’s controlled testing found a few tens of extra requests over HTTP/2 produced no noticeable slowdown; the measurable hit only appeared around 250 requests, and even then it was 0.89 seconds—roughly 14%. The protocol absorbs much of the cost, but it doesn’t make the request count irrelevant.
What does that mean? Well, it shows that HTTP/2 changes which requests matter, not whether they matter. Three kinds still hurt on any protocol—render-blocking requests, connections to slow third-party origins, and anything bloating the render path.
🤔 Worth knowing
Page weight tracks with this. Pages of 2-3 MB pass Core Web Vitals on mobile just 53% of the time versus 70% for pages under 1 MB, per the HTTP Archive Web Almanac—and heavier pages usually carry more render-path requests too.
That’s also why a Pingdom “D” can overstate the damage: its YSlow rules predate HTTP/2. You just need to decide where to focus your efforts, and the next four sections answer exactly that.
Practical tips to cut down HTTP requests on your site
Everything from here fits into four buckets, in the order we’d tackle them: Consolidate your files, defer what blocks the render, minimize external requests, and leverage caching. Work through them top to bottom, and you’ll cut the requests that matter most first.
Consolidate: Combine and minify your CSS and JavaScript
This action shrinks the request count at the source. Combining merges multiple files into fewer bundles, so the browser fetches one stylesheet instead of eight, while minifying strips the whitespace, comments, and line breaks that make code readable for humans but mean nothing to a browser. Fewer files, smaller files, same result on screen.
The order you do it in matters, so work through it like this:
- Start with CSS. It’s the safer of the two and rarely breaks anything—a good place to build confidence.
- Move to JavaScript carefully. Combining scripts is the trickier half because files that load out of order can break layouts or functionality. It’s an active problem even for mature tools, and some still ship fixes for these issues.
- Test before and after each change. Reload the page, confirm nothing shifted or stopped working, then move to the next file.
Don’t over-combine. Under HTTP/2 and HTTP/3, a bundle re-downloads in full whenever any part of it changes—so merging everything into one mega-file means visitors re-fetch the lot after every small edit. Group files into logical bundles instead: shared vendor code in one, page-specific code where it belongs.
Encouragingly, most sites are already partway there—61-63% of pages now properly minify their CSS and JavaScript, per the HTTP Archive Web Almanac.
If managing bundles and exclusion rules by hand sounds like a chore, that’s what NitroPack automates: its Combine CSS, Combine JavaScript, and Minify Resources features handle the merging and stripping for you, with exclusion rules for the files that shouldn’t be touched.
Defer: Stop blocking the render path
Combining is about fewer files; deferring is about getting the important ones to load first and pushing everything else out of the way. Two attributes do most of the work.
Use async for independent scripts that don’t rely on other scripts or the DOM—some analytics tags are a good example. Use defer for scripts that should wait until the HTML has finished parsing and need to run in order:
<!-- Independent script: runs when ready, order not guaranteed -->
<script async src="/analytics.js"></script>
<!-- App scripts: run after HTML parsing, order preserved -->
<script defer src="/app.js"></script> Images are the other big win. Add loading="lazy" to below-the-fold images and iframes so the browser only fetches them as the reader scrolls near them. The one rule: Never lazy-load your hero or LCP image, or anything needed immediately at the top of the page—that delays the very thing you want to appear fastest.
<img loading="lazy" src="/images/example-600.jpg" width="600" height="600" alt="Descriptive text for the image"> One trade-off the listicles skip: inlining tiny images as Base64. It sounds like a free request saved, but the encoded data is larger than the original file, and dropping it inside render-blocking CSS slows down a critical resource—DebugBear has the numbers. Reserve it for very small, one-off assets, and only after testing.
NitroPack automates both halves of this bucket: Delayed JavaScript Execution holds non-critical scripts until a user interacts, and Lazy Loading handles the offscreen images for you.
Minimize external: plugins, third-party scripts, fonts, and redirects
Most bloat doesn’t come from your own code—it comes from everything you’ve bolted on over time. Here’s how to find out exactly what’s happening:
- Audit your heaviest plugins. Take the Query Monitor findings from your audit and test deactivating suspects one page at a time. Don’t assume fewer plugins automatically means fewer requests—the relationship isn’t linear, and some plugins add nothing to the front end at all.
- Unload scripts where they aren’t needed. Form builders and page builders love to inject their assets sitewide, even on pages that never use them. A dedicated script manager like Perfmatters lets you switch those assets off per post or page, so your contact-form script stops loading on every blog article.
- Tame third-party scripts. Analytics, the Facebook Pixel, YouTube embeds, chat widgets, social sharing buttons—each one reaches out to someone else’s server. Remove the ones you don’t need, defer the rest, and only self-host a script when the vendor allows it and you can keep it safely updated.
- Consolidate your fonts. A single font family can fire several requests once you count its weights, styles, and subsets. Stick to system fonts where you can, or limit yourself to one or two families in only the weights you actually use. Self-hosting WOFF2 files gives you more control, but test it against the hosted service first—especially for large international families.
- Clean up redirects. Every 301 or 302 adds a round-trip, and chains stack those trips one after another. Point your internal links straight at their final URLs so the browser skips the detour.
However, don’t fall into the trap of adding more bloat while trying to troubleshoot. Instead of running separate plugins for caching, image optimization, and a CDN, NitroPack folds the work that would normally take 3-5 plugins into one subscription—and its Delayed JavaScript Execution defers non-critical third-party scripts automatically.
Test NitroPack yourself
By submitting, you agree to our Privacy Policy.
You’ve now cut what loads and where it loads from. The last bucket makes sure you only pay that cost once.
Leverage caching: Cache aggressively and serve content from a CDN
Every fix so far reduces the cost of a page load—but without caching, the visitor’s browser pays that cost fresh every single time. Cache well, and it pays once.
The mechanism is the Cache-Control header. Set it on your static assets and browsers (and CDNs) can reuse the files they already have instead of re-fetching them while they’re still fresh. Give versioned, rarely-changing assets long lifetimes, keep HTML on shorter or revalidated caching, and never cache private or sensitive responses. Expires still works as a legacy fallback, but Cache-Control is the header that matters now.
The trick that makes aggressive caching safe is versioned URLs. When a file changes, its name changes too—styles.a1b2c3.css becomes styles.d4e5f6.css—so the browser fetches the new version automatically and keeps serving the cached copy until then.
A CDN takes this further by serving those cached files from whichever server sits closest to the visitor, cutting the distance every request has to travel. Pair it with GZIP or Brotli compression to shrink the files themselves before they’re sent.
It adds up fast: The median desktop home page could save around 303 KB through better cache lifetimes alone, per the HTTP Archive Web Almanac. Google’s web.dev guide to the HTTP cache is the reference if you want the full spec.
This is the part NitroPack was built to handle end-to-end. Its built-in CDN spans 310 endpoints with GZIP/Brotli and HTTP/3 at no extra cost on paid plans, and Smart Cache Invalidation refreshes only the resources that actually changed—so a single product-price edit doesn’t dump your whole cache. If breaking something has been the worry holding you back, that’s the fix.
Measure again to confirm the fix worked
Optimization isn’t done until you’ve proven it.
- Re-run the same page through Pingdom or GTmetrix and compare the new waterfall against your baseline—the request count should have dropped toward that under-50 mark, with under 25 the goal.
- Read the number as a clue, not a verdict: on HTTP/2, a page with 55 cached, non-blocking, same-origin requests can beat one with 20 large, blocking, third-party ones.
- Then check your Largest Contentful Paint in PageSpeed Insights—the Core Web Vital most shaped by request behavior.
If the count is still high but the page looks simple, go back to the Network waterfall first, and treat Query Monitor as a second opinion for enqueued scripts and server-side calls, not the only source.
Not sure where to start? Work in this order: Images → plugin audit → consolidate (CSS first, then JS) → defer → minimize external → cache.
Frequently asked questions
What’s the difference between async and defer?
Both stop a script from blocking the page, but they behave differently.
asyncruns a script as soon as it’s downloaded, with no guarantee of order.deferwaits until the HTML has finished parsing and preserves the order scripts appear in.
Use defer for anything that depends on the DOM or on other scripts.
Why does Pingdom still flag my HTTP requests?
Pingdom grades using YSlow rules that predate HTTP/2, so it penalizes request counts that modern protocols handle comfortably. Cross-check a low Pingdom grade against Chrome DevTools and PageSpeed Insights before acting on it.
Are CSS sprites still worth using in 2026?
Rarely. Icon fonts and inline SVG have replaced most sprite use cases, and HTTP/2 multiplexing erodes the original speed benefit of bundling images into one file. Sprites still hold niche value for icon-heavy designs, but for most sites, they’re no longer worth the effort.
How do I check if my site is on HTTP/2?
Open Chrome DevTools (F12), go to the Network tab, right-click any column header, and enable the Protocol column. Reload the page and look for h2 (HTTP/2) or h3 (HTTP/3); http/1.1 means you’re on the older protocol.
What’s the best plugin to reduce HTTP requests in WordPress?
No single tool handles every tactic. NitroPack consolidates caching, CDN, image optimization, minification, and lazy loading into one subscription, while other tools take a more modular, piece-by-piece approach. The right choice depends on how much you’d rather automate versus configure yourself.