April 2, 2026

Improve TTFB and Crawling Budget with HTTP 304 Not Modified

How HTTP 304 Not Modified reduces unnecessary traffic, reduces server load, improves TTFB, and helps crawlers better utilize their crawling budget.

When it comes to web performance, the focus often shifts to full-page caching, CDN, Brotli compression, optimized images, and frontend optimization. These are all important aspects, no doubt. However, there's a much less obvious, yet extremely useful, element that can significantly improve both the TTFB extension both to the optimization of the crawling budget: the status code HTTP 304 Not Modified.

The 304 is one of those mechanisms that work silently. It doesn't make the page more beautiful, it doesn't change the layout, and it doesn't add any features visible to the end user. Yet it allows you to avoid unnecessary transfers, reduce server and network load, improve perceived speed, and make crawlers work more efficiently. In a context where every millisecond counts and every wasted resource can become a bottleneck, the correct use of conditional requests becomes an important piece of a serious optimization strategy.

Understanding how 304s actually work, when they're returned, which headers govern them, and how they impact browsers, proxies, CDNs, and search engine bots is essential for those managing high-traffic sites, e-commerce sites, publishing portals, or any project where performance and crawling directly impact the business.

What is HTTP 304 Not Modified?

Code 304 Not Modified Indicates that the resource requested by the client has not changed from the version already in the requester's local cache. In other words, the browser or crawler asks the server, "Has this resource changed since I last downloaded it?" If the answer is no, the server doesn't resend the full content, but only returns the header with a 304 status.

304-Not-Modified

It is important to clarify one point: the 304 is not an arbitrary cache response, but the result of a conditional requestThe client sends a request with headers like If-Modified-Since or If-None-Match, and the server compares these values ​​with the current state of the resource. If the resource has not changed, it responds with 304; if it has changed, it responds normally with 200 OK and submit the new content.

This mechanism is particularly efficient because it avoids retransferring HTML, CSS, JavaScript, images, fonts, or other assets the client already owns. The benefit isn't just in terms of bandwidth. It also reduces server-side work and, in many cases, improves the time it takes to close the request.

Why 304 can improve TTFB

Il TTFB extensionTime To First Byte (TTF) measures the time between sending a request and receiving the first byte of the response. It's a metric that reflects several factors: network latency, server-side processing, database access, whether the request is passed through a proxy or CDN, and the system's ability to serve content quickly.

When a resource can be validated with a conditional request and closed with a 304 Not Modified, the server does not have to reconstruct the entire payload to send. In many scenarios, it does not even have to perform all the same operations required for a full 200. If the validation logic is implemented well, the check ETag o Last-Modified It is much cheaper than generating and delivering the entire resource.

For static assets, the advantage is clear. Instead of sending back a hundreds-kilobyte CSS file or an image, the server returns only a lightweight response, with essential headers. For the browser, this means it can immediately reuse the cached copy. For the infrastructure, it means less traffic, less I/O, less CPU usage, and less competition for resources.

However, we must be precise: the 304 doesn't magically lower TTFB in every scenarioIf the application is still forced to load PHP stacks, query the database, run heavy plugins, and only then decide that the resource hasn't changed, the benefit can be significantly reduced. The real benefit comes when validation occurs efficiently, as close as possible to the web server, reverse proxy cache, or CDN.

The relationship between cache validation and content transfer

To understand the role of 304, we must distinguish between two often confused concepts: cache expiration e cache validation.

Cache expiration is governed by directives such as Cache-Control: max-age=... o ExpiresThese headers tell the client how long it can consider a resource valid without even having to return to the server for confirmation.

Cache validation, on the other hand, comes into play when the resource needs to be verified. In this case, the client sends a conditional request and the server responds with 304 if nothing has changed, or 200 with the new content if the resource has been updated.

Both mechanisms are useful, but have different roles. Expiration alone isn't always enough, as some content needs to be checked more frequently. Validation alone, without a good caching policy, risks generating too many unnecessary requests. A well-designed configuration combines both aspects: define consistent caching times and use ETag o Last-Modified to validate resources when needed.

The headers that make 304 possible

The operation of the 304 revolves mainly around two families of headers.

The first is Last ModifiedThe server communicates the date and time the resource was last modified. On the next request, the client can send If-Modified-Since with that value. If the file hasn't changed since then, the server returns a 304.

The second is ETag, which is a unique identifier for the resource version. It can be calculated in various ways: content hash, inode plus timestamp, logical file revision, application fingerprint. The client stores this value and sends it in subsequent requests. If-None-MatchIf the ETag matches the current one, the server responds with a 304.

In general, ETag is more accurate Because it doesn't depend solely on the modification date, but on the actual state of the resource. However, in distributed environments, it must be managed carefully. If multiple nodes generate different ETags for the same resource, inconsistent invalidations and the loss of caching benefits can occur. This is a fairly common scenario in clusters with different filesystems, multiple containers, or misaligned web servers.

For this reason, in many high-performance infrastructures, it is preferable to use Last-Modified for simple static content or consistent ETags generated at the application or CDN level, avoiding uncontrollable automatic implementations.

304 and crawling budget: why it matters to technical SEO too

The concept of crawling budget In simple terms, it refers to the amount of resources a search engine is willing to dedicate to crawling a site. Not all sites have the same limitations, but in general, any inefficiency in crawling can translate into fewer URL visits, slower updates, and slower indexing of changes.

The 304 code is also useful here because it allows crawlers to quickly verify known resources without having to download the entire content each time. When a bot requests a static page or resource and receives confirmation that it hasn't changed, the process is more streamlined for both the search engine and the origin server.

Crawl Request Not modified 304

This is particularly relevant for sites with many pages, numerous assets, shared templates, and only partially updated content. If the crawler can efficiently validate what hasn't changed, the server wastes less bandwidth and machine time. This can lead to more orderly and sustainable crawling, especially for very large projects.

Of course, we must not oversimplify: the 304 It does not increase SEO rankings by itself And it doesn't automatically increase your crawling budget. However, it helps create a technically cleaner, less cluttered, and more efficient environment. In large or complex environments, this efficiency translates into a tangible advantage.

The case of static resources: where 304 excels

If there is one area where the 304 immediately shows its value, it is that of static assetsCSS, JavaScript, images, fonts, and media files are often resources that don't change continuously but are requested repeatedly, by users and bots.

Imagine a WordPress, Magento, or PrestaShop site with dozens of frontend files loaded on each page. Without proper caching and validation, the browser risks continually requesting assets it already owns, receiving 200 complete responses each time. With well-configured headers, however, it can reuse the cache and, when necessary, quickly validate resources, obtaining 304s.

The benefit is twofold. On the one hand, it reduces the burden of repeated browsing, especially for returning users. On the other, it reduces the overall load on the server. This becomes even more important during peak periods, when thousands of concurrent requests for identical files can saturate resources that should be reserved for dynamic content.

On assets versioned via fingerprint in the file name, for example app.8f3a21.css, you can even push towards very aggressive caching. In those cases, 304s can become less frequent because the file, as long as the name remains the same, is considered immutable. This is often the ideal strategy. But when the expiration isn't very long or validation remains necessary, 304s remain a valuable ally.

The case for dynamic HTML: be careful not to get confused

When moving from static assets toDynamic HTML, things get trickier. Not all HTML pages are equally suited to conditional validation. A homepage with frequently changing content, custom widgets, banners, dynamic sections, or user-specific snippets might not be a good candidate for a 304, at least not without a well-designed application caching or reverse proxy system.

In some cases, the risk is introducing more complexity than benefits. If the application still has to fully render the page to determine if it has changed, the 304 response arrives too late to be truly efficient. In other cases, logical errors can occur, with variable content mistakenly considered unchanged.

This doesn't mean 304 isn't useful for HTML. It just means you need to use it wisely. On cacheable pages, relatively stable landing pages, documentation, product pages with intermittent updates, or editorial sections well served by reverse proxies, it can work very well. On highly personalized or dynamic pages, it's best to think about the cache architecture first.

CDN, reverse proxy, and web server: 304 works even better

The 304 is at its best when its management is delegated to the most efficient layers of the infrastructure: Nginx, Varnish, reverse proxy, CDNAt these levels, validation can occur without involving the entire application each time.

NGINX Reverse Proxy Cache

A CDN, for example, can directly serve cached assets to the edges or validate their state toward the origin in an optimized way. A reverse proxy like Varnish can drastically reduce the number of requests reaching PHP or the application backend. Nginx can very efficiently handle static files with Last-Modified and eventually ETag.

The principle is simple: the closer the validation logic is to the pure HTTP layer and further away from the heavy application code, the cheaper and more useful the 304 will be. Conversely, when every request has to traverse CMSs, plugins, ORMs, sessions, and middleware before being validated, much of the benefit is lost.

Common mistakes in implementing 304

One of the most common mistakes is thinking that simply seeing 304s in the logs means the caching system is well configured. This isn't the case. 304s can be useful, but they don't have to compensate for a bad caching strategyIf an immutable resource is validated too often rather than served directly from the browser's local cache, there's still room for improvement.

Another common mistake concerns the Inconsistent eTags In multi-server environments, if two nodes return different ETags for the same file, the client will tend to redownload the resource or invalidate it unnecessarily. In clusters and distributed infrastructures, this problem is much more common than you might think.

Then there's the issue of dynamic responses served improperly with 304s. If the HTML contains parts that change based on the user, session, cart, or geolocation, naive validation can lead to incorrect behavior. In these cases, cacheable content must be carefully separated from personalized content.

Finally, beware of plugins or application layers that set conflicting headers, for example Cache-Control: no-cache along with logic that aims to promote validation. When policies are confusing, the result is often an inefficient flow of requests and responses.

How to check if your 304 is working properly

To understand whether 304 is truly useful in your stack, you need to look at the data correctly. Web server logs are the first place to start: they show how many requests are closed with 304s, on which assets, and how frequently. But they need to be interpreted in context.

It is useful to analyze the headers with curl -I, browser development tools, and headers returned by the CDN or reverse proxy. At least four things should be checked: the presence of Cache-Control, presence of Last-Modified o ETag, consistency of responses between different nodes and browser behavior upon subsequent reloads.

On a performance level, it is worth comparing the average cost of a response 200 and a 304 for the same resource type. If the server continues to spend too much time even generating 304s, it means validation is either placed too high in the stack or implemented inefficiently.

From a technical SEO perspective, you can observe crawler behavior in logs, evaluating whether bots like Googlebot are making conditional requests and which types of resources are validated most often. This allows you to understand whether the site is providing clean and consistent HTTP signals.

A smart strategy: 304 where needed, aggressive caching where possible

The best approach is not to “use 304 everywhere”, but use it well where it makes senseFor static, versioned assets, the optimal solution is often a long, aggressive cache, with files fingerprinted and downloaded only when the name changes. For assets that aren't completely immutable, 304 is a perfect validation tool. For HTML, however, it should be evaluated on a case-by-case basis based on the cache layer, content stability, and generation cost.

In essence, 304 should be seen as part of a broader strategy of HTTP efficiencyIt's not a trick, it's not a shortcut, and it's no substitute for good architecture. However, when configured correctly, it helps reduce unnecessary traffic, improves perceived responsiveness, and eases the burden on both browsers and crawlers.

Conclusions

Code HTTP 304 Not Modified It is one of those tools that rarely end up at the center of marketing discussions, but in practice it makes a difference. It helps improve the TTFB extension In many scenarios, it reduces unnecessary data transfer, lightens the load on infrastructure and applications, and makes resource scanning by bots more efficient.

Its true value emerges when it's part of a coherent strategy: well-designed headers, efficient validation, correct ETags or Last-Modified, well-managed browser cache, and carefully configured reverse proxies and CDNs. In that context, the 304 stops being a simple status code and becomes a concrete optimization tool.

Those who manage modern sites, especially those with high traffic or complex architectures, would do well not to underestimate this aspect. Because often, improving performance doesn't come only from major changes or more powerful hardware, but also from the ability to don't do useless workAnd that's exactly the principle behind 304: don't resend what the client already has, don't waste CPU, don't waste bandwidth, don't waste time.

In a web ecosystem where efficiency, speed and technical sustainability are increasingly central, the 304 Not Modified it remains a small, essential and often extremely intelligent answer.

Do you have doubts? Don't know where to start? Contact us!

We have all the answers to your questions to help you make the right choice.

Chat with us

Chat directly with our presales support.

0256569681

Contact us by phone during office hours 9:30 - 19:30

Contact us online

Open a request directly in the contact area.

DISCLAIMER, Legal Notes and Copyright. RedHat, Inc. holds the rights to Red Hat®, RHEL®, RedHat Linux®, and CentOS®; AlmaLinux™ is a trademark of the AlmaLinux OS Foundation; Rocky Linux® is a registered trademark of the Rocky Linux Foundation; SUSE® is a registered trademark of SUSE LLC; Canonical Ltd. holds the rights to Ubuntu®; Software in the Public Interest, Inc. holds the rights to Debian®; Linus Torvalds holds the rights to Linux®; FreeBSD® is a registered trademark of The FreeBSD Foundation; NetBSD® is a registered trademark of The NetBSD Foundation; OpenBSD® is a registered trademark of Theo de Raadt; Oracle Corporation holds the rights to Oracle®, MySQL®, MyRocks®, VirtualBox®, and ZFS®; Percona® is a registered trademark of Percona LLC; MariaDB® is a registered trademark of MariaDB Corporation Ab; PostgreSQL® is a registered trademark of PostgreSQL Global Development Group; SQLite® is a registered trademark of Hipp, Wyrick & Company, Inc.; KeyDB® is a registered trademark of EQ Alpha Technology Ltd.; Typesense® is a registered trademark of Typesense Inc.; REDIS® is a registered trademark of Redis Labs Ltd; F5 Networks, Inc. owns the rights to NGINX® and NGINX Plus®; Varnish® is a registered trademark of Varnish Software AB; HAProxy® is a registered trademark of HAProxy Technologies LLC; Traefik® is a registered trademark of Traefik Labs; Envoy® is a registered trademark of CNCF; Adobe Inc. owns the rights to Magento®; PrestaShop® is a registered trademark of PrestaShop SA; OpenCart® is a registered trademark of OpenCart Limited; Automattic Inc. holds the rights to WordPress®, WooCommerce®, and JetPack®; Open Source Matters, Inc. owns the rights to Joomla®; Dries Buytaert owns the rights to Drupal®; Shopify® is a registered trademark of Shopify Inc.; BigCommerce® is a registered trademark of BigCommerce Pty. Ltd.; TYPO3® is a registered trademark of the TYPO3 Association; Ghost® is a registered trademark of the Ghost Foundation; Amazon Web Services, Inc. owns the rights to AWS® and Amazon SES®; Google LLC owns the rights to Google Cloud™, Chrome™, and Google Kubernetes Engine™; Alibaba Cloud® is a registered trademark of Alibaba Group Holding Limited; DigitalOcean® is a registered trademark of DigitalOcean, LLC; Linode® is a registered trademark of Linode, LLC; Vultr® is a registered trademark of The Constant Company, LLC; Akamai® is a registered trademark of Akamai Technologies, Inc.; Fastly® is a registered trademark of Fastly, Inc.; Let's Encrypt® is a registered trademark of the Internet Security Research Group; Microsoft Corporation owns the rights to Microsoft®, Azure®, Windows®, Office®, and Internet Explorer®; Mozilla Foundation owns the rights to Firefox®; Apache® is a registered trademark of The Apache Software Foundation; Apache Tomcat® is a registered trademark of The Apache Software Foundation; PHP® is a registered trademark of the PHP Group; Docker® is a registered trademark of Docker, Inc.; Kubernetes® is a registered trademark of The Linux Foundation; OpenShift® is a registered trademark of Red Hat, Inc.; Podman® is a registered trademark of Red Hat, Inc.; Proxmox® is a registered trademark of Proxmox Server Solutions GmbH; VMware® is a registered trademark of Broadcom Inc.; CloudFlare® is a registered trademark of Cloudflare, Inc.; NETSCOUT® is a registered trademark of NETSCOUT Systems Inc.; ElasticSearch®, LogStash®, and Kibana® are registered trademarks of Elastic NV; Grafana® is a registered trademark of Grafana Labs; Prometheus® is a registered trademark of The Linux Foundation; Zabbix® is a registered trademark of Zabbix LLC; Datadog® is a registered trademark of Datadog, Inc.; Ceph® is a registered trademark of Red Hat, Inc.; MinIO® is a registered trademark of MinIO, Inc.; Mailgun® is a registered trademark of Mailgun Technologies, Inc.; SendGrid® is a registered trademark of Twilio Inc.; Postmark® is a registered trademark of ActiveCampaign, LLC; cPanel®, LLC owns the rights to cPanel®; Plesk® is a registered trademark of Plesk International GmbH; Hetzner® is a registered trademark of Hetzner Online GmbH; OVHcloud® is a registered trademark of OVH Groupe SAS; Terraform® is a registered trademark of HashiCorp, Inc.; Ansible® is a registered trademark of Red Hat, Inc.; cURL® is a registered trademark of Daniel Stenberg; Facebook®, Inc. owns the rights to Facebook®, Messenger® and Instagram®. This site is not affiliated with, sponsored by, or otherwise associated with any of the above-mentioned entities and does not represent any of these entities in any way. All rights to the brands and product names mentioned are the property of their respective copyright holders. All other trademarks mentioned are the property of their respective registrants. MANAGED SERVER® is a European registered trademark of MANAGED SERVER SRL, with registered office in Via Flavio Gioia, 6, 62012 Civitanova Marche (MC), Italy and operational headquarters in Via Enzo Ferrari, 9, 62012 Civitanova Marche (MC), Italy.

JUST A MOMENT !

Have you ever wondered if your hosting sucks?

Find out now if your hosting provider is hurting you with a slow website worthy of 1990! Instant results.

Close the CTA
Back to top