Getting started
This guide walks through adding Cache to a Layeron backend application. You will declare a cache instance, register it, cache a route response, attach tags, read stats, and purge entries after data changes.
Define the Cache
Section titled “Define the Cache”Import cache from @layeron/modules. Declare the cache with a stable logical
name, then register it with app.use(...).
import { backend } from "@layeron/core"import { cache } from "@layeron/modules"
const app = backend({ project: "store-api",})
const apiCache = cache({ name: "public-api", namespace: "storefront", ttlSeconds: 60, staleWhileRevalidateSeconds: 30, vary: ["accept-language"], tags: ["public-api"],})
app.use(apiCache)The cache instance identity is storefront/public-api. See
Namespaces for platform namespace defaults and naming rules.
Cache a Route Response
Section titled “Cache a Route Response”Use match(request) at the start of a read-heavy route. Use put(request, response) after generating the response.
app.get("/api/products", async (request) => { const cached = await apiCache.match(request)
if (cached) { return cached }
const products = await listProducts() const response = Response.json({ products })
await apiCache.put(request, response.clone(), { tags: ["products"], ttlSeconds: 60, })
return response})Clone the response before put when the same response object will also be
returned from the route.
Add Item-Level Tags
Section titled “Add Item-Level Tags”Tags are invalidation metadata. They help you purge groups of entries after a write.
app.get("/api/products/:id", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const id = pathSegments[3] const cached = await apiCache.match(request)
if (cached) { return cached }
const product = await findProduct(id) const response = Response.json({ product })
await apiCache.put(request, response.clone(), { tags: ["products", `product:${id}`], ttlSeconds: 120, })
return response})Tags stay outside cache-key partitioning. The cache key comes from the request, method, namespace, and vary headers.
Purge After Writes
Section titled “Purge After Writes”After a write updates data, purge the affected tags:
app.post("/api/products/:id", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const id = pathSegments[3] const input = await request.json()
await updateProduct(id, input)
await apiCache.purge({ tags: ["products", `product:${id}`], })
return Response.json({ ok: true })})purge returns the number of entries Layeron attempted to remove from
Cloudflare Cache:
const result = await apiCache.purge({ tags: ["products"],})
return Response.json(result)Delete One Request
Section titled “Delete One Request”Use delete(request) when a route knows the exact request URL to remove:
await apiCache.delete("https://api.example.com/api/products")The request must produce the same key as the original write, including method and vary headers.
Read Stats
Section titled “Read Stats”stats() returns runtime counters for the cache instance:
app.get("/internal/cache/stats", async () => { const stats = await apiCache.stats()
return Response.json(stats)})Example response:
{ "hits": 1204, "misses": 97, "puts": 97, "deletes": 4, "purges": 12}Next Steps
Section titled “Next Steps”- Core concepts: Understand instances, keys, TTLs, stale windows, tags, route rules, and state.
- Keys and vary: Design stable cache keys for routes, queries, headers, and per-call options.
- Route rules: Attach cache policy to backend routes.
- Invalidation: Delete one entry or purge by request, tag, or prefix.
- Stats and observability: Read counters and emit product metrics for cache behavior.