Search... ⌘K
Write Log In Sign Up

Join DevSolved

Share war stories & investigate outages.

Sign Up for Free Log In to Account
ESC
NORMAL Resolved

CORS Preflight Cache Miss: The Double Traffic Phantom

Avatar Devsolved Jan 28, 2024 — 14:30 UTC MTTR: 6 hours 2 min read 195000 views
Executive Summary

An overly restrictive `Access-Control-Max-Age` header caused the browser to send a preflight OPTIONS request before EVERY single API call, artificially doubling backend traffic and latency.

The Symptom

Symptom

After migrating our frontend to a new domain, users reported the app felt sluggish. Monitoring tools showed our API Gateway traffic had exactly doubled overnight. However, Google Analytics showed our active user count remained completely flat.

Root Cause Analysis

Root Cause

Because the frontend and backend were now on different domains, the browser engaged Cross-Origin Resource Sharing (CORS) protections. Before sending a `POST` or `PUT` request with custom headers (like `Authorization`), the browser sends a preflight `OPTIONS` request to ask the server for permission. Our backend responded with `Access-Control-Allow-Origin: *`, but we failed to include an `Access-Control-Max-Age` header. By default, Chromium caches preflight responses for only 5 seconds. This meant that every time a user navigated the app, the browser was firing duplicate OPTIONS requests, doubling network latency (due to round trips) and artificially inflating our server load.

Code javascript
// The fatal flaw: Express CORS middleware defaults
app.use(cors({
  origin: 'https://app.devsolved.com',
  methods: ['GET', 'POST', 'PUT']
  // Missing maxAge!
}));

Resolution

Resolution

We updated our CORS middleware to include `Access-Control-Max-Age: 86400` (24 hours). Now, the browser makes a single OPTIONS request when the user first opens the app, caches the permission, and sends all subsequent API calls directly, instantly cutting our backend traffic by 50% and improving perceived app performance.

Preventive Action Items

high Update API Gateway CORS configurations with 24-hour Max-Age @DevOps
normal Ensure monitoring dashboards filter out OPTIONS requests from business metric calculations @Data Team
|

Discussions 0

Most recent