Expires Headers
title: "Expires Headers — Absolute Expiration for HTTP Caching" description: "The Expires header specifies an absolute expiration date for HTTP cached responses, providing backward compatibility with HTTP/1.0 caching systems." date: 2026-06-28 lastmod: 2026-06-28 weight: 14 tags: [apis, caching] }
The Expires header sets an absolute expiration timestamp in HTTP-date format, telling caches when a stored response becomes stale and must be revalidated.
What You'll Learn
- Expires header format and usage
- Expires vs Cache-Control max-age
- When to use Expires in modern APIs
Why It Matters
While Cache-Control is preferred, Expires provides backward compatibility with HTTP/1.0 caches. Some CDNs and proxies still rely on Expires headers.
Code Examples
# Setting Expires header
from datetime import datetime, timedelta
@app.route('/api/reports/daily')
def daily_report():
# Expires at midnight
tomorrow = datetime.utcnow().replace(hour=0, minute=0, second=0) + timedelta(days=1)
expires = tomorrow.strftime('%a, %d %b %Y %H:%M:%S GMT')
response = jsonify(generate_report())
response.headers['Expires'] = expires
response.headers['Cache-Control'] = 'public, max-age=3600'
return response
# Express.js Expires
app.get('/api/weather/forecast', (req, res) => {
const nextUpdate = new Date();
nextUpdate.setHours(24, 0, 0, 0); // Expire at next midnight
res.set({
'Expires': nextUpdate.toUTCString(),
'Cache-Control': 'public, max-age=3600'
});
res.json(forecast);
});
# Example Expires header
HTTP/1.1 200 OK
Content-Type: application/json
Expires: Mon, 29 Jun 2026 00:00:00 GMT
Cache-Control: public, max-age=3600
{"report": "data"}
Common Mistakes
1. Using Expires Without Cache-Control
Cache-Control overrides Expires. Set both for broader compatibility.
2. Wrong Date Format
Expires requires RFC 1123 format: Day, DD Mon YYYY HH:MM:SS GMT.
3. Setting Expires in the Past
Past expiration causes immediate cache invalidation.
4. Hard-Coded Expires Dates
Always compute expiration dynamically, not as a fixed string.
5. Relying Only on Expires
Expires is HTTP/1.0. Cache-Control max-age is more precise and flexible.
Practice Questions
- What HTTP-date format does Expires use?
- Does Cache-Control or Expires take precedence?
- Why set both Expires and Cache-Control?
- What happens when Expires is in the past?
- How do you compute Expires dynamically?
Answers:
- RFC 1123:
Day, DD Mon YYYY HH:MM:SS GMT. - Cache-Control max-age takes precedence over Expires.
- For backward compatibility with HTTP/1.0 caches.
- The response is immediately considered stale; no caching occurs.
- Add a duration to the current UTC time and format it.
Challenge: Audit your API responses. Add Expires headers to any responses that currently only use Cache-Control.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro