Reference guide · http-status · Published 2026-08-15 · 3 min read

HTTP 304 Not Modified explained

Understand HTTP 304 Not Modified: how conditional requests with ETag and If-None-Match skip re-downloads and speed up repeat visits.

What 304 Not Modified means

304 Not Modified is the server's answer to a conditional request. When a client already holds a cached copy of a resource and asks "is my copy still current?", a server that still has the same version replies 304 with no response body. The client keeps its stored copy, and the expensive re-transfer of unchanged bytes is skipped.

It is a caching optimization, not an error. Seeing 304s in your logs means repeat visitors are successfully revalidating content from cache rather than re-downloading it. It belongs to the family of successful statuses that a cache-aware setup leans on heavily, and it is the mechanism behind the HTTP caching guide.

How revalidation works

The flow has three steps:

  1. A resource is stored in the browser or proxy cache with a validator (an ETag or a Last-Modified date).
  2. When the cached copy reaches staleness, the client sends a conditional request carrying the validator in If-None-Match or If-Modified-Since.
  3. The origin compares. If unchanged, it returns 304 with empty body and the same validator; if changed, it returns 200 with the new body.
GET /style.css HTTP/1.1
If-None-Match: "b6a-3f6a"
HTTP/1.1 304 Not Modified
ETag: "b6a-3f6a"

The ETag is the precise validator: the server derives it from the file content, so any change produces a new value and a fresh 200. Last-Modified is the coarse one with one-second granularity. When both are present, the client uses ETag as the stronger signal.

Why browsers see fewer 304s than proxies

A browser with a fresh max-age does not revalidate at all; it serves from cache until the age passes, so it shows zero requests rather than 304s. 304s appear when a resource is stale but unchanged, or when an HTML page uses no-cache (cache, but always revalidate). Proxy caches and the Cloudflare edge also issue 304s to the origin on miss, which is why you may see many 304s in server logs while visitors experience fast, cached page loads.

Reading 304 in logs

Prefer explicit ETag generation at the origin and a long max-age plus immutable for hash-named assets, reserving conditional revalidation for HTML pages that must pick up changes promptly. Get the headers right and 304 does the cheap revalidation work so the origin only pays bytes when content actually changes.

Need a website built, fixed, optimised, migrated or replaced?

This technical resource is written by CSMBAC, a small design and development studio. If you would rather hand the problem to a professional, the website service page explains how we build enquiry-ready websites.

Explore website services