Fix CORS Max-Age Preflight Cache Duration
In this tutorial, you'll learn about Fix CORS Max. We cover key concepts, practical examples, and best practices.
Each CORS preflight adds an extra round trip before the real request. Without Access-Control-Max-Age, browsers send a preflight on every request, doubling latency. Setting a proper max-age caches the preflight response and eliminates this overhead for subsequent requests.
Wrong
The server either omits Access-Control-Max-Age or sets it to a very low value.
app.use(cors({
origin: 'https://app.example.com',
}));
Response headers (no max-age):
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
The browser sends a preflight OPTIONS before every POST request. Each API call takes two round trips instead of one.
OPTIONS /api/data 204 (preflight)
POST /api/data 200 (actual)
... two seconds later, same API call ...
OPTIONS /api/data 204 (preflight again)
POST /api/data 200 (actual)
Right
Set Access-Control-Max-Age to cache the preflight response, measured in seconds.
app.use(cors({
origin: 'https://app.example.com',
maxAge: 86400, // cache for 24 hours
}));
Response headers:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
The browser caches the preflight result for 24 hours. Only the first request triggers a preflight:
OPTIONS /api/data 204 (preflight — first request only)
POST /api/data 200 (actual)
POST /api/data 200 (no preflight — cached)
POST /api/data 200 (no preflight — cached)
Manual implementation:
app.options('*', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', 'https://app.example.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.setHeader('Access-Control-Max-Age', '86400');
res.sendStatus(204);
});
Prevention
- Set
Access-Control-Max-Ageto at least 3600 (1 hour) for development and 86400 (24 hours) for production. - The maximum value most browsers support is 86400 (Firefox caps at 86400, Chrome caps at 86400).
- Values above 86400 are silently clamped by browsers. There is no benefit to setting higher values.
- If you update CORS configuration frequently during development, use a lower value like 600 (10 minutes).
- Remember that
Access-Control-Max-Ageonly affects preflight caching, not the actual response caching. - Invalidate the preflight cache by changing the URL or method if you need to force a new preflight.
DodaTech Tools
Doda Browser shows the cached preflight status in its network panel with a badge indicating cache hit or miss. DodaZIP's performance audit reports include CORS preflight frequency metrics to help identify APIs without max-age configured. Durga Antivirus Pro's API gateway uses a 24-hour preflight cache across all its microservice endpoints.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro