HTTP Caching
What It Is
HTTP caching stores a response for a request and reuses that stored response for later matching requests.
Instead of always going back to the origin server, the browser or cache can serve the saved response faster.
HTTP Caching = Reuse stored HTTP responses instead of fetching again every time
Why It Matters
HTTP caching improves performance by reducing unnecessary network and server work.
It helps with:
- faster load times
- lower latency
- reduced network traffic
- reduced server load
- better availability during network issues
- faster reuse of static resources
Cached response -> faster than origin server response
When cached content is reusable, the origin server does not need to process the request again.
That means less routing, session handling, database querying, and rendering work.
What Can Be Cached
HTTP caching is commonly used for resources that are requested repeatedly.
Common cached resources:
- CSS files
- JavaScript files
- images
- fonts
- HTML pages
- API responses
Static assets are usually the best fit for HTTP caching.
API responses can also be cached, but they need careful freshness rules.
How It Works
A browser sends a request and receives a response.
If the response is cacheable, the browser stores it.
On the next request, the browser can decide whether to:
- reuse the cached response directly
- validate the cached response with the server
- fetch a fresh response from the server
First request -> server response -> stored in cache
Next request -> cache reused or validated
The decision is controlled mainly by HTTP headers.
Main HTTP Caching Headers
HTTP caching behavior is controlled using response headers.
| Header | Purpose |
|---|---|
| Cache-Control | Controls how and where responses can be cached |
| Expires | Defines a date/time after which response becomes expired |
| Last-Modified | Tells when the resource was last changed |
| ETag | Identifies a specific version of a resource |
These headers help browsers decide whether cached data is still valid.
Cache-Control
Cache-Control is the main HTTP header used to control caching.
It contains directives that tell browsers and shared caches how to handle the response.
res.setHeader("Cache-Control", "public, max-age=86400");
This means the response can be cached publicly and considered fresh for 86400 seconds.
Cache-Control Directives
Cache-Control supports multiple directives.
| Directive | Meaning |
|---|---|
| public | Any cache can store the response |
| private | Only the user's browser can cache it |
| max-age=seconds | Resource is fresh for the given number of seconds |
| no-store | Do not cache the response anywhere |
| no-cache | Cache can store it, but must validate before reuse |
| must-revalidate | Stale response must be validated before reuse |
public
public means the response can be stored by any cache.
This includes:
- browser cache
- CDN cache
- proxy cache
Cache-Control: public, max-age=86400
Use this for public resources that are safe to cache.
Good examples:
- images
- CSS files
- JavaScript bundles
- public static assets
private
private means the response can be cached only by the user's browser.
It should not be stored by shared caches like CDNs or proxies.
Cache-Control: private, max-age=300
Use this for user-specific content.
Example:
A page showing personal user information.
max-age
max-age defines how long the response is considered fresh.
Cache-Control: public, max-age=86400
Here, the response is fresh for 86400 seconds.
86400 seconds = 1 day
Until the max age expires, the browser can reuse the cached response without asking the server again.
no-store
no-store prevents caching completely.
Cache-Control: no-store
The response should not be stored anywhere.
Use it when the response must always be fetched fresh.
This is useful for highly sensitive or constantly changing data.
no-cache
no-cache does not mean "do not store."
It means the cache may store the response, but it must validate with the origin server before using it.
Cache-Control: no-cache
Usually validation happens using ETag.
Cache stored response -> asks server if still valid -> reuse or fetch new
If the server confirms the resource has not changed, the cached version can be reused.
must-revalidate
must-revalidate means stale cached resources must be validated before reuse.
Cache-Control: public, max-age=86400, must-revalidate
Once the cached response becomes stale, the cache must check with the server before using it again.
This prevents expired resources from being used without validation.
Expires
Expires tells the browser the date and time after which the response should be considered expired.
res.setHeader("Expires", "Sat, 23 Dec 2023 11:20:39 GMT");
If the current time is before the expiry date, the response can be reused.
If the current time is after the expiry date, the response is stale.
Expires = exact expiry date for cached response
Last-Modified
Last-Modified tells the browser when the server believes the resource was last changed.
res.setHeader("Last-Modified", "Sat, 23 Dec 2023 11:20:39 GMT");
It is used as a validator.
The browser can ask the server whether the resource changed since that date.
If the resource has not changed, the server can avoid sending the full response again.
Last-Modified = timestamp-based validation
ETag
ETag identifies a specific version of a resource.
res.setHeader("ETag", "dj3958ehcxvj69237dh59");
The browser stores the ETag with the cached response.
When the user revisits the resource, the browser compares the stored ETag with the server version.
If they match, the server can respond with:
304 Not Modified
This tells the browser to use the cached version.
ETag = version token for cache validation
304 Not Modified
304 Not Modified means the cached resource is still current.
The server does not send the full resource again.
The browser reuses the cached copy.
Browser validates cache -> Server says 304 -> Browser uses cached response
This reduces bandwidth and improves performance.
Cache Busting
Cache busting means changing the resource URL when the content changes.
Example:
image.gif?hash=abcdef
Another common production example:
app.abc123.js
style.def456.css
When the URL changes, the browser treats it as a new resource and fetches it again.
Same URL -> browser may reuse cache
New URL -> browser fetches fresh resource
Cache busting is commonly used for static assets after deployment.
Avoiding Cache Usage
Sometimes you may want to avoid using cached resources.
Common methods:
| Method | Meaning |
|---|---|
| Cache Busting | Change URL when content changes |
| no-store | Prevent caching completely |
| max-age=0 | Mark resource stale immediately |
| no-cache | Require validation before reuse |
Example:
Cache-Control: max-age=0
This means the resource becomes stale immediately.
HTTP Caching Table
| Area | Explanation |
|---|---|
| Main goal | Reuse stored responses |
| Best for | Static assets and carefully managed API responses |
| Performance benefit | Faster load and lower latency |
| Server benefit | Reduced origin server work |
| Main header | Cache-Control |
| Validation headers | ETag, Last-Modified |
| Date-based expiry | Expires |
| Freshness control | max-age |
| No caching | no-store |
Basic Checklist
Cache static assets like CSS, JS, fonts, and images
Use Cache-Control for caching rules
Use public for resources safe for shared caching
Use private for user-specific browser-only caching
Use max-age to define freshness duration
Use no-store when the response must never be cached
Use no-cache when validation is required before reuse
Use ETag for version-based validation
Use Last-Modified for timestamp-based validation
Use cache busting when static asset content changes
Avoid caching sensitive data incorrectly
Interview Style Answer
HTTP caching stores responses associated with requests and reuses them for future matching requests. It improves speed, reduces latency, lowers network traffic, reduces server load, and improves availability by serving cached resources instead of always contacting the origin server. Common cached resources include CSS, JavaScript files, images, fonts, HTML pages, and sometimes API responses. Caching behavior is controlled using headers like Cache-Control, Expires, Last-Modified, and ETag. Cache-Control directives such as public, private, max-age, no-store, no-cache, and must-revalidate define how responses are cached and revalidated. ETag and Last-Modified help validate cached resources, and a 304 Not Modified response allows the browser to reuse its cached copy.
One-Line Summary
HTTP Caching = Store and reuse HTTP responses to improve speed, reduce network traffic, and lower server load.
Final Mental Model
Fresh cache -> use cached response
Stale cache -> validate with server
Changed resource -> fetch new response
Unchanged resource -> 304 and reuse cache
Sensitive data -> avoid caching or use strict rules