Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

What is the difference between Cache-Control and Expires?

Quick answer

Cache-Control is the more flexible response header: its directives can set freshness as a duration, such as max-age=3600, and express other caching behavior. Expires gives a date and time after which a response is considered stale. When both Cache-Control: max-age and Expires are present, max-age takes precedence. Actual handling also depends on the directives, cache type, and HTTP rules. [S1] [S2]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

What is the practical difference between Cache-Control and Expires? I’m looking at response headers and want to know which one tells a browser how long it can reuse a response.

Geez

Both can communicate freshness, but they express it differently. Cache-Control uses directives; for example, max-age=3600 says the response is fresh for 3,600 seconds from when it was generated at the origin. Expires instead supplies a date and time after which the response is considered stale. [S1] [S2]

A useful shorthand is: max-age is a duration, while Expires is a timestamp. Cache-Control can also carry directives for other caching behavior, so it does more than provide a freshness value. How a response is handled depends on the directives, the kind of cache, and HTTP rules. [S1]

For example, if an origin generates a response at 12:00 and includes Cache-Control: max-age=3600, that directive expresses one hour of freshness from that generation time. This is an illustration of the stated duration rule, not a guarantee that every cache will handle the response identically.

Follow-up question

If a response includes both headers, should I expect them to agree? Which value should I use when checking why a response seems fresh or stale?

Geez

They do not have to agree, but it is clearer to configure them consistently when you include both. When Cache-Control: max-age and Expires are both present, max-age takes precedence for freshness. So, if the duration and date imply different freshness periods, do not treat Expires as overriding max-age. [S2]

A simple example, with placeholders for the origin’s actual generation time and corresponding date, is:

Cache-Control: max-age=3600 Expires: [date and time corresponding to one hour after generation]

Here both values express a one-hour freshness period. If the Expires placeholder instead represents a later time, the documented precedence still means max-age governs when both are present. This example shows the relationship between the headers; it does not establish how a particular browser or intermediary handled a specific response.

Follow-up question

Is Expires just an older spelling of max-age? Should I remove it whenever I use Cache-Control?

Geez

They are related, but they are not interchangeable in every circumstance. Expires was used for freshness in HTTP/1.0, while Cache-Control provides directives such as max-age and can specify other caching behavior. [S2] You can read an Expires date as an absolute freshness cutoff, and a max-age value as a freshness duration.

Whether to include both depends on the policy you want to express and the systems that need to interpret the response. The available information establishes that max-age takes precedence over Expires when both are present; it does not establish which header is required for your particular application, deployment, or audience. Avoid assuming that adding Expires changes behavior when a controlling max-age is also present.

Follow-up question

I’m reviewing a response from an origin that may also be served through a shared cache. What should I check so I don’t confuse browser freshness with shared-cache freshness?

Geez

Read the directives and identify the cache context before drawing a conclusion. In particular, s-maxage applies to shared caches and, when present, overrides max-age or Expires there. [S1] That means a response can have one freshness instruction relevant to shared caches and another general freshness value, rather than one number that answers every caching question.

A practical review might look like this:

  1. Record the complete Cache-Control value, including any max-age or s-maxage directive.
  2. Record Expires, if present, and note that it supplies a date and time.
  3. Identify whether you are asking about a browser or a shared cache.
  4. Apply the documented precedence for that context: max-age over Expires when both are present; s-maxage over max-age or Expires for shared caches when present. [S1] [S2]
  5. If the observed behavior remains unclear, gather the response headers and relevant request context for a qualified HTTP or platform specialist to review.

These headers explain freshness policy, but the excerpts do not establish the behavior of a particular cache product or explain every HTTP caching rule. Use the actual response and cache context rather than inferring a complete diagnosis from one header.

A practical checklist

  • Copy the full Cache-Control header value, not only the max-age number.

  • Note the Expires date and time if that header is present.

  • Check whether max-age and Expires express different freshness periods; max-age takes precedence when both are present.

  • If reviewing a shared cache, check for s-maxage, which overrides max-age or Expires there when present.

  • Record whether the question concerns a browser or shared cache before interpreting the headers.

A few more useful answers

Does Expires take precedence over Cache-Control: max-age?

No. When both are present, max-age takes precedence over Expires. [S2]

What does s-maxage change?

It applies to shared caches and, when present, overrides max-age or Expires there. [S1]

Does seeing these headers prove exactly how a specific cache behaved?

No. The directives, cache type, and HTTP rules matter, and these general facts do not establish the behavior of a particular cache product. [S1]

Sources

References used for this guide.

  1. [S1] Cache-Control header — HTTP | MDN
    developer.mozilla.org · Checked
  2. [S2] HTTP caching — HTTP | MDN
    developer.mozilla.org · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work