Bird
Raised Fist0
Expressframework~10 mins

HTTP caching headers (ETag, Cache-Control) in Express - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - HTTP caching headers (ETag, Cache-Control)
Client sends request
↓
Server checks cache headers
↓
Generate ETag for resource
↓
Compare ETag with If-None-Match header
↓
Send 304
↓
Client caches resource
↓
Next request uses cached data if valid
The server uses ETag and Cache-Control headers to tell the client if the resource changed. If not, it sends a 304 status to save bandwidth.
Execution Sample
Express
app.get('/data', (req, res) => {
  const data = JSON.stringify({ message: "cached data" });
  const etag = '"etag123"';
  res.set('Cache-Control', 'private, max-age=10');
  if (req.headers['if-none-match'] === etag) {
    res.status(304).end();
  } else {
    res.set('ETag', etag).send(data);
  }
});
This Express route sends data with ETag and Cache-Control headers, responding 304 if the client's ETag matches.
Execution Table
StepRequest Header If-None-MatchETag GeneratedCondition (If-None-Match === ETag)Response StatusResponse HeadersResponse Body
1none"etag123"false200Cache-Control: private, max-age=10; ETag: "etag123"{"message":"cached data"}
2"etag123""etag123"true304Cache-Control: private, max-age=10none
3"etag999""etag123"false200Cache-Control: private, max-age=10; ETag: "etag123"{"message":"cached data"}
💡 When If-None-Match matches ETag, server sends 304 to avoid resending data.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3
req.headers['if-none-match']undefinednone"etag123""etag999"
etagundefined"etag123""etag123""etag123"
res.statusundefined200304200
res.bodyundefined{"message":"cached data"}none{"message":"cached data"}
Key Moments - 3 Insights
Why does the server send a 304 status instead of the data sometimes?
When the client's If-None-Match header matches the server's ETag (see execution_table step 2), the server knows the client has the latest data and sends 304 to save bandwidth.
What happens if the client sends no If-None-Match header?
The server treats it as no cache and sends the full data with status 200 and ETag header (see execution_table step 1).
Why is Cache-Control header important here?
Cache-Control tells the client how long it can keep the cached data before checking again. It works with ETag to optimize caching (see response headers in all steps).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the response status when the If-None-Match header equals the ETag?
A304
B200
C404
D500
💡 Hint
Check the row where Condition is true in the execution_table.
At which step does the server send the full data with ETag header?
AStep 2
BStep 3
CStep 1
DNo step
💡 Hint
Look for response status 200 with ETag in the execution_table.
If the Cache-Control max-age was set to 0, how would the client behavior change?
AClient caches data indefinitely
BClient would never cache the data
CClient caches data for 10 seconds
DClient caches data only if ETag changes
💡 Hint
Refer to Cache-Control header meaning in key_moments and execution_table.
Concept Snapshot
HTTP caching uses ETag and Cache-Control headers.
ETag is a unique ID for resource version.
Client sends If-None-Match with ETag to check freshness.
Server replies 304 if unchanged, saving bandwidth.
Cache-Control sets how long client can keep cached data.
Together they improve web performance and reduce load.
Full Transcript
This visual trace shows how HTTP caching headers work in an Express server. The server generates an ETag for the data and sends it with Cache-Control headers. When the client requests the same resource again, it sends the ETag in the If-None-Match header. The server compares this with the current ETag. If they match, the server sends a 304 Not Modified status without the data, telling the client to use its cached copy. If they don't match or no ETag is sent, the server sends the full data with a 200 status and the current ETag. Cache-Control tells the client how long to keep the cached data before checking again. This process saves bandwidth and speeds up loading by avoiding unnecessary data transfer.

Practice

(1/5)
1. What is the main purpose of the ETag header in Express HTTP responses?
easy
A. To redirect the client to a different URL
B. To specify how long the browser should cache the resource
C. To identify a specific version of a resource for caching validation
D. To indicate the content type of the response

Solution

  1. Step 1: Understand the role of ETag

    The ETag header provides a unique identifier for a specific version of a resource, allowing the server to tell if the resource has changed.
  2. Step 2: Compare with other headers

    Cache-Control sets caching duration, redirects use Location header, and content type is set by Content-Type header, so these are not related to ETag.
  3. Final Answer:

    To identify a specific version of a resource for caching validation -> Option C
  4. Quick Check:

    ETag = version ID for caching [OK]
Hint: ETag tags resource versions to avoid unnecessary downloads [OK]
Common Mistakes:
  • Confusing ETag with Cache-Control duration
  • Thinking ETag redirects clients
  • Mixing ETag with content type headers
2. Which of the following is the correct way to set a Cache-Control header in Express to cache a response for 1 hour?
easy
A. res.set('Cache-Control', 'max-age=3600')
B. res.header('Cache-Control', 'no-cache')
C. res.cache('max-age=3600')
D. res.setHeader('Cache-Control', 'max-age=60')

Solution

  1. Step 1: Identify Express method to set headers

    Express uses res.set() or res.header() to set headers. Both work, but res.set() is common and correct here.
  2. Step 2: Check Cache-Control value for 1 hour

    1 hour = 3600 seconds, so max-age=3600 is correct. res.header('Cache-Control', 'no-cache') uses 'no-cache' which disables caching. res.cache('max-age=3600') is invalid method. res.setHeader('Cache-Control', 'max-age=60') sets max-age to 60 seconds, not 1 hour.
  3. Final Answer:

    res.set('Cache-Control', 'max-age=3600') -> Option A
  4. Quick Check:

    Cache-Control max-age=3600 sets 1 hour caching [OK]
Hint: Use res.set with 'max-age=seconds' for caching time [OK]
Common Mistakes:
  • Using wrong method like res.cache
  • Confusing seconds with minutes in max-age
  • Setting no-cache when caching is needed
3. Given this Express code snippet, what will the client receive if the request includes header If-None-Match matching the ETag?
app.get('/data', (req, res) => {
  const data = { message: 'Hello' };
  const etag = '12345';
  res.set('ETag', etag);
  if (req.headers['if-none-match'] === etag) {
    res.status(304).end();
  } else {
    res.json(data);
  }
});
medium
A. A 500 Internal Server Error
B. A 304 Not Modified status with no body
C. A 404 Not Found error
D. A JSON response with { message: 'Hello' }

Solution

  1. Step 1: Check If-None-Match header against ETag

    If the request's If-None-Match header equals the ETag '12345', the server responds with status 304 and no body.
  2. Step 2: Understand 304 response meaning

    304 means Not Modified, telling the client to use cached data without sending the body again.
  3. Final Answer:

    A 304 Not Modified status with no body -> Option B
  4. Quick Check:

    If-None-Match matches ETag = 304 response [OK]
Hint: If ETag matches If-None-Match, send 304 no body [OK]
Common Mistakes:
  • Sending JSON body with 304 status
  • Confusing 304 with 404 or 500 errors
  • Ignoring If-None-Match header
4. Identify the bug in this Express code that tries to set Cache-Control and ETag headers:
app.get('/resource', (req, res) => {
  const content = 'data';
  res.setHeader('Cache-Control', 'max-age=600');
  res.set('ETag', 'abc123');
  res.send(content);
});
medium
A. Using both res.setHeader and res.set causes header conflicts
B. ETag header value must be a number, not a string
C. Cache-Control max-age should be in milliseconds, not seconds
D. No bug; code sets headers correctly

Solution

  1. Step 1: Check header setting methods

    In Express, res.setHeader and res.set both set headers correctly; using both is allowed and does not conflict.
  2. Step 2: Validate header values

    ETag can be any string value. Cache-Control max-age is in seconds, so '600' is valid for 10 minutes.
  3. Final Answer:

    No bug; code sets headers correctly -> Option D
  4. Quick Check:

    res.setHeader and res.set both valid; ETag string OK [OK]
Hint: res.set and res.setHeader both valid for headers [OK]
Common Mistakes:
  • Thinking ETag must be numeric
  • Confusing max-age units (seconds vs milliseconds)
  • Assuming res.setHeader and res.set conflict
5. You want to implement HTTP caching in Express so that clients cache a JSON response for 5 minutes, but also use ETag to validate changes. Which code snippet correctly combines Cache-Control and ETag headers to achieve this?
hard
A. res.set({ 'Cache-Control': 'max-age=300', ETag: 'xyz789' }); res.json(data);
B. res.set('Cache-Control', 'no-store'); res.set('ETag', 'xyz789'); res.json(data);
C. res.set('Cache-Control', 'max-age=300'); res.removeHeader('ETag'); res.json(data);
D. res.set('Cache-Control', 'max-age=300, no-cache'); res.set('ETag', 'xyz789'); res.json(data);

Solution

  1. Step 1: Set Cache-Control for 5 minutes

    5 minutes = 300 seconds, so max-age=300 is correct to allow caching for that duration.
  2. Step 2: Include ETag header for validation

    Setting ETag allows clients to check if the cached version is still valid before using it.
  3. Step 3: Analyze other options

    res.set('Cache-Control', 'no-store'); res.set('ETag', 'xyz789'); res.json(data); disables caching with 'no-store'. res.set('Cache-Control', 'max-age=300'); res.removeHeader('ETag'); res.json(data); removes ETag, losing validation. res.set('Cache-Control', 'max-age=300, no-cache'); res.set('ETag', 'xyz789'); res.json(data); uses conflicting directives 'max-age=300, no-cache' which disables caching despite max-age.
  4. Final Answer:

    res.set({ 'Cache-Control': 'max-age=300', ETag: 'xyz789' }); res.json(data); -> Option A
  5. Quick Check:

    Cache-Control max-age + ETag = proper caching [OK]
Hint: Combine max-age with ETag for caching plus validation [OK]
Common Mistakes:
  • Using no-store disables caching
  • Removing ETag loses validation benefits
  • Combining max-age with no-cache cancels caching
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard