Optimize Preflight Caching with Max-Age
Reduce latency by caching CORS preflight responses. Learn how Access-Control-Max-Age works and recommended values for different scenarios.
Detailed Explanation
Preflight Caching — Reducing Round-Trips
Every non-simple cross-origin request triggers a preflight OPTIONS request. Without caching, this doubles the number of HTTP round-trips for every API call. Access-Control-Max-Age tells the browser how long to cache the preflight result.
How It Works
- The browser sends an
OPTIONSrequest withAccess-Control-Request-MethodandAccess-Control-Request-Headers. - The server responds with
Access-Control-Allow-*headers andAccess-Control-Max-Age: N. - For the next
Nseconds, the browser skips the preflight for identical requests (same URL, method, and headers).
Recommended Values
| Scenario | Max-Age | Reasoning |
|---|---|---|
| Development | 0 or 5 | Fast feedback loop when changing CORS config |
| Stable internal API | 3600 (1h) | Balance between freshness and performance |
| Public read-only API | 86400 (24h) | Minimize preflight traffic from high-volume clients |
| Browser cap | 7200 (2h) | Chromium caps at 7200s regardless of the header value |
Browser Limits
While you can set Max-Age up to 86400, note that Chromium-based browsers cap the cache at 7200 seconds (2 hours). Firefox respects up to 86400. Setting a higher value is still useful for Firefox users and doesn't hurt Chromium users.
Generated Headers
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
Vary: Origin
Measuring Impact
To see preflight requests, open DevTools > Network and filter by method OPTIONS. After the first preflight, subsequent requests within the Max-Age window should not generate another OPTIONS call.
Use Case
A single-page application that makes dozens of API calls per page load. Without preflight caching, each call generates an extra OPTIONS round-trip, adding 50-200ms of latency per request on high-latency connections.