Cache safely
Memoise slow calls per tenant, share a public read action with a CDN, and see why a signed-in response is never shared.
Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.
Stability The promise an interface ships with.
- Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
- Beta Usable in production; may change before it becomes stable.
- Experimental May change or go away; needs an explicit opt-in in main.yaml.
You will memoise a slow query per tenant, declare one read action as shareable, and check that nothing personal can reach a shared cache. It takes about 10 minutes and needs no account.
You need
- A project with
main.yamland an adapter (mainsdk/hono,mainsdk/nextormainsdk/express).
1. Memoise a slow call
cache:
driver: kv
timeout: 50msimport { cache } from "mainsdk/cache";
declare function loadStats(): Promise<{ orders: number }>; // your slow query
export const stats = () =>
cache.wrap("dashboard-stats", () => loadStats(), { ttl: "1m", swr: "10m", tags: ["stats"] });You should see loadStats run once per tenant a minute, and once more in the background after that while callers keep the old value. The key is stored as t:<tenant>:r:<region>:dashboard-stats, so no tenant reads another's.
2. Drop it when the data changes
import { cache } from "mainsdk/cache";
await cache.delete({ tag: "stats" }); // this tenant only, on every instance3. Share one read action
Declare http.cache on a plain GET read action and serve it with serveRead (see Cache). Nothing else makes a response shareable: a header you set by hand on a signed-in response is replaced with private, no-store and logged as MAIN-CACHE-0001.
4. Check it
pnpm mainsdk checkMAIN-CACHE-0011 names a public declaration on a write, a non-GET or a permissioned action; MAIN-CACHE-0012 names an app-scoped cache around a db read.
Ask your agent
Goal: speed up the products page without leaking one tenant's data to another.
Touch: main.yaml (cache section), the products lib, one read action, tests with the fake clock.
Rules: cache.wrap with the default tenant scope; scope "app" only for values with no person or tenant data; never set Cache-Control by hand on a signed-in response.
Verify: pnpm mainsdk check && pnpm test
Never weaken or skip a check; fix the finding it names.Next
Was this page helpful?