When a commerce platform rooted in a single country starts serving customers across regions with uneven infrastructure, latency stops being a CDN tuning problem and becomes an architecture problem. This walkthrough covers the cache topology, inventory partitioning, and routing decisions we made — and the failure modes that pushed us there.
1. The Regional Latency Problem
Bangladesh's network topology is unusual: a handful of well-connected data centers in Dhaka, a long tail of lower-bandwidth last-mile links into divisional cities, and mobile-first users for whom a 3-second page load is the difference between a sale and an abandoned cart. A standard single-origin deployment served from one region measured acceptably in the capital but degraded sharply elsewhere.
The naive fix — put everything behind a global CDN — helped static assets but did nothing for the dynamic catalog, inventory, and pricing calls that dominate a storefront's critical path. Those still crossed the network to a single origin on every request.
2. Why Standard CDN Configurations Fall Short
A default CDN configuration caches assets, not answers. For a storefront, the expensive work is computing the product listing for a given category, region, and stock state — not serving the product image. Three failure modes appeared repeatedly:
- Origin stampede on cache miss: a popular category page expiring simultaneously across edge nodes generated burst traffic that saturated the origin database connection pool.
- Stale inventory: edge-cached product availability diverged from real stock, leading to oversells in flash-sale scenarios.
- Personalization penalty: any user-specific element (cart count, regional price) forced a full bypass, negating the cache for the entire page.
3. Localized Edge Cache Layers
The core change was introducing a regional edge cache layer that holds computed responses, not just assets. Each edge node serves a stale-while-revalidate copy of category and product-listing responses, with a short TTL tuned per content type.
Cache key discipline
The cache key is composed of region + category + currency + variant-filter — deliberately excluding user identity. Personalized fragments (cart, account) are fetched client-side and composed in the browser, so the page shell stays cacheable.
The rule that unlocked everything: never let a user-specific value touch the server-rendered page shell. Personalization happens in the client; the cache serves the shared structure.
4. Selective Database Telemetry Queries
Inventory accuracy required a different layer. Rather than invalidating the edge cache on every stock change (which re-introduced origin stampedes), we run a small set of selective telemetry queries on a read replica, polling stock deltas every few seconds. The edge cache is invalidated only when a relevant delta appears — not on every write.
This trades a small window of staleness (a few seconds) for a dramatic reduction in invalidation chatter. For a flash-sale scenario, the edge cache serves the listing at full speed; the cart and checkout flows hit the primary database directly with accurate, realtime stock.
5. Results & Operational Notes
The combined effect was measurable: median time-to-first-byte on category pages dropped by roughly two-thirds in divisional regions, and origin database load during peak traffic fell substantially. The operational cost is complexity — two cache layers must be reasoned about, and the invalidation logic is now its own small service that must be monitored.
The lesson we keep returning to: cache the answer, not the asset. Once the architecture treats computed responses as first-class cacheable objects, the rest of the tuning is incremental.