Frontend Development 12 min read

Understanding Browser Cache Mechanisms and HTTP Header Controls

This article explains how browsers cache resources, the role of HTTP response headers such as Expires, Cache‑Control, ETag and Last‑Modified, and how conditional requests and different refresh actions affect caching behavior to improve web performance.

Art of Distributed System Architecture Design
Art of Distributed System Architecture Design
Art of Distributed System Architecture Design
Understanding Browser Cache Mechanisms and HTTP Header Controls

During web development, developers often encounter browser caching issues. This article explains the mechanisms behind browser cache, helping readers gain a deeper understanding of how browsers store and validate resources.

Process

When a resource is requested for the first time, the browser sends a typical HTTP request header:

(Request-Line)  GET /a.html HTTP/1.1
host    127.0.0.1
User-Agent  Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
Accept              text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language     zh-cn,zh;q=0.5
Accept-Encoding     gzip,deflate
Accept-Charset      gb2312,utf-8;q=0.7,;q=0.7
Keep-Alive          300
Connection          keep-alive

The server responds with a 200 status and includes descriptive headers such as:

(Status-Line) HTTP/1.1 200 OK
date                Thu, 26 Nov 2009 13:50:54 GMT
Server              Apache/2.2.11 (Unix) PHP/5.2.9
Last-Modified       Thu, 26 Nov 2009 13:50:19 GMT
Etag                "8fb8b-14-4794674acdcc0"
Accept-Ranges       bytes
Content-Length      20
Keep-Alive          timeout=5, max=100
Connection          Keep-Alive
Content-type        text/html

Key fields include Last-Modified (last modification time), ETag (unique entity tag), and Expires (cache expiration time). The browser stores the file in its cache directory together with these metadata.

On a subsequent request, the browser checks the cache. If the cached file has not expired according to Expires , it serves the file locally without contacting the server.

If the file is expired, the browser sends a conditional request containing the previously received values:

If-Modified-Since   Thu, 26 Nov 2009 13:50:19 GMT
If-None-Match       "8fb8b-14-4794674acdcc0"

The server validates these headers. If the resource has not changed, it returns a 304 Not Modified response, avoiding the transfer of the body:

(Status-Line) HTTP/1.1 304 Not Modified
Date Thu, 26 Nov 2009 14:09:07 GMT
Server Apache/2.2.11 (Unix) php/5.2.9
Connection Keep-Alive
Keep-Alive timeout=5, max=100
Etag "8fb8b-14-4794674acdcc0"

This greatly reduces bandwidth usage and improves user experience. If the resource has changed, the server returns the new content with updated headers.

Basic Header Fields

Pragma

The Pragma header carries implementation‑specific directives; the most common is Pragma: no-cache , which is equivalent to Cache-Control: no-cache in HTTP/1.1.

Expires

Specifies the absolute expiration time of the cached file. If the file has not expired, the browser does not send a request.

Cache-Control

Cache-Control defines the caching policy for requests and responses. Request directives include no-cache , no-store , max-age , max-stale , min-fresh , and only-if-cached . Response directives include public , private , no-cache , no-store , no-transform , must-revalidate , proxy-revalidate , and max-age . Their meanings are explained in the list below.

Public : response may be cached by any cache.

Private : response is intended for a single user and must not be stored by shared caches.

no-cache : forces caches to submit the request to the origin server for validation before releasing a cached copy.

no-store : prevents any part of the request or response from being cached.

max-age : specifies the maximum amount of time (in seconds) a resource is considered fresh.

min-fresh : indicates the client is willing to accept a response that will still be fresh for at least the specified number of seconds.

max-stale : allows the client to accept a response that has exceeded its expiration time by up to the specified number of seconds.

ETag / If-None-Match

ETag is a validator that uniquely identifies a specific version of a resource, typically generated from the file's inode, size, and modification time. The client sends If-None-Match with the previously received ETag to enable strong validation.

Last-Modified / If-Modified-Since

These headers work together to validate a resource based on its last modification timestamp.

According to RFC 2616, Expires and Cache-Control control cache freshness, while Last-Modified and ETag validate resource validity.

Last-Modified vs. ETag

ETag is used in addition to Last-Modified because multiple modifications within a single second may not be reflected in the timestamp, whereas an ETag provides a more precise change detection.

Different Scenarios

The basic caching flow changes in real‑world situations such as normal navigation, page refresh, and forced refresh.

Normal Page Navigation

Includes link clicks, window.open , or typing a URL.

Without caching, the request returns all resources.

If Expires is set and not reached, the browser does not issue a request.

If Expires has passed, the browser sends a request with Last-Modified and ETag for server validation.

Page Refresh (F5)

Browsers typically send conditional requests, resulting in many 304 responses even when the resource has not expired. The behavior differs slightly between IE and Firefox.

IE example:

If-Modified-Since   Wed, 18 Nov 2009 15:54:52 GMT
If-None-Match   "2360492659"
Pragma: no-cache    // prohibit caching

Firefox example:

If-Modified-Since   Wed, 18 Nov 2009 15:54:52 GMT
If-None-Match   "2360492659"
Cache-Control   max-age=0   // file expires immediately

Forced Refresh (Ctrl+F5)

The effect is equivalent to a no‑cache request, and the server returns a full 200 response with the resource.

Special Resource Types

IFRAME

FLASH

Asynchronously fetched data (e.g., AJAX)

Disclaimer: The content is sourced from public internet channels, presented neutrally for reference and discussion only. Copyright belongs to the original authors; please contact for removal if infringement occurs.
web performancehttp headerscache controlBrowser CacheETag
Art of Distributed System Architecture Design
Written by

Art of Distributed System Architecture Design

Introductions to large-scale distributed system architectures; insights and knowledge sharing on large-scale internet system architecture; front-end web architecture overviews; practical tips and experiences with PHP, JavaScript, Erlang, C/C++ and other languages in large-scale internet system development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.