Skip to content
Get started

Edge caching

Vega’s cache lives in the same process as your handlers, in every region. A cache hit is a memory read — no network hop, no serialization round trip. The default strategy is stale-while-revalidate (SWR), which keeps responses fast even while the underlying data changes.

cache.swr(key, fetcher) resolves in one of three ways:

  1. Fresh hit — the value is within its TTL. Returned immediately.
  2. Stale hit — the TTL has passed but the value is inside its stale window. The stale value is returned immediately, and the fetcher runs in the background to refresh it.
  3. Miss — no value exists. The fetcher runs inline and the result is stored.

Requests almost never wait on your data source twice: after the first request, users see cached data while revalidation happens off the critical path.

api/index.ts
api.get('/products/:id', async ({ params, cache }) => {
const product = await cache.swr(`product:${params.id}`, () =>
db.products.find(params.id),
);
return Response.json(product);
});

With no options, values are fresh for 60 seconds and servable-while-stale for 10 minutes.

Pass ttl and stale (both in seconds) as the third argument:

const rates = await cache.swr('fx:rates', fetchRates, {
ttl: 300, // fresh for 5 minutes
stale: 3600, // then servable-while-revalidating for 1 hour
});

Short TTLs with long stale windows are the usual sweet spot: data stays current without ever exposing users to cold-fetch latency.

Tag entries when you write them, then purge by tag when the source data changes:

const user = await cache.swr(`user:${id}`, () => db.users.find(id), {
tags: ['users', `user:${id}`],
});
api.post('/users/:id', async ({ params, cache }) => {
await db.users.update(params.id, /* ... */);
await cache.purge({ tags: [`user:${params.id}`] });
return Response.json({ ok: true });
});

Purges can also be issued from the CLI, which is handy after out-of-band data changes:

Terminal window
vega cache purge --tag users

Every response carries a vega-cache header:

ValueMeaning
hitServed a fresh value from cache
staleServed a stale value; revalidation running in background
missNo cached value; fetcher ran inline
bypassRequest did not touch the cache

vega logs --follow includes the same value per request, and the traces view shows each cache operation as a span with its outcome and duration.

Cache storage is per-region: a value cached in fra is not visible in sin. Purges are global — a purge issued anywhere propagates to all 28 regions in under 300ms. This is the right default for response caching; for shared mutable state, use a database.

Full method signatures, including cache.get, cache.set, and cache.delete, are in the cache reference.