CachingCDN Cache
CDN Cache
Cache API responses at the edge. When this works, your function doesn't run at all.
Maximum Savings
CDN caching is the outermost cache layer. When a response is cached at the edge, your function doesn't run at all - that's zero compute cost.
User Request → CDN: "Have I seen this?"
→ Yes: Return cached (FREE)
→ No: Call function, cache, returnSetting Cache Headers
export async function GET() {
const products = await db.products.findMany();
return Response.json(products, {
headers: {
'Cache-Control': 'public, s-maxage=300',
'Stale-While-Revalidate': '3600',
},
});
}Key Headers
| Header | Purpose |
|---|---|
s-maxage=300 | Cache at CDN for 5 minutes |
stale-while-revalidate=3600 | Serve stale while fetching fresh |
public | Allow CDN caching |
private | Prevent CDN caching (user data) |
The Auth Gotcha
Reading cookies or auth headers busts the cache:
// ❌ Won't cache - reads cookies
export async function GET(request: Request) {
const session = request.cookies.get('session');
// ...
}Fix: Separate public and private endpoints:
export async function GET() {
return Response.json(await getPublicProducts(), {
headers: { 'Cache-Control': 'public, s-maxage=300' },
});
}
// app/api/products/mine/route.ts - Not cached
export async function GET(request: Request) {
const user = await getUser(request);
return Response.json(await getUserProducts(user.id));
}Debugging
Check Vercel Dashboard → Analytics → Cache for hit rates.
Low hit rate? You're probably reading cookies/headers somewhere.
Next: Route Cache for caching entire pages.