When building an e-commerce platform in the MENA region, particularly in Egypt, you quickly realize that standard web performance best practices aren't always enough. High network latency, erratic 4G connections, and geographic distance from major European data centers (where AWS/GCP usually route traffic from Frankfurt or London) mean that traditional Server-Side Rendering (SSR) can result in a crippling Time To First Byte (TTFB) of 800ms or more.
When re-architecting [CairoVolt], a fast-growing electronics and charging accessories store in Egypt, we set an ambitious goal: Achieve a near 0ms TTFB for our product pages without sacrificing real-time inventory data.
Here is the technical breakdown of how we moved from a slow SSR monolith to an edge-first architecture.
The Problem: The "Frankfurt Roundtrip"
In our legacy architecture, every time a user requested a product page (e.g., a 20W GaN Charger), the request traveled from Cairo to Frankfurt, queried the database, rendered the HTML, and traveled back.
Even with optimized database queries, physics got in the way. The raw network latency alone accounted for ~150ms roundtrip. Under load, our TTFB hovered around 800ms to 1.2 seconds. For e-commerce, where every 100ms of latency costs conversion, this was unacceptable.
The Solution: Stale-While-Revalidate at the Edge
To achieve instant loading times, we had to serve HTML directly from edge nodes located as close to the user as possible. However, e-commerce requires dynamic data (prices, stock levels).
We solved this using a combination of Edge Caching and the stale-while-revalidate (SWR) cache-control strategy.
1. Re-writing the Cache-Control Headers
Instead of blocking the request while generating the page on a distant server, we instruct our CDN to serve a stale HTML version instantly to the user, while asynchronously revalidating the page in the background for the next user.
Here is a simplified version of our Next.js API response headers for product pages:
javascript
export async function GET(request) {
const product = await fetchProductData(request.url);
return new Response(JSON.stringify(product), {
status: 200,
headers: {
'Content-Type': 'application/json',
// The Magic Sauce:
// Cache at the edge for 10 seconds.
// If a request comes in within 1 hour, serve the stale cache immediately (0ms TTFB),
// but re-fetch data in the background.
'Cache-Control': 'public, s-maxage=10, stale-while-revalidate=3600',
},
});
}
Top comments (0)