Configure the object cache
EmDash’s per-request cache already deduplicates identical reads during one page render. The optional object cache keeps selected query results across requests, allowing a later request to avoid the same database read. It is useful when public traffic creates more database reads than the selected backend should handle.
The database remains the source of truth. Cache reads fail open to the database, and writes invalidate the affected cache namespace. The object cache is disabled by default; enable it by adding an objectCache adapter to the emdash() integration.
Overview
Section titled “Overview”| Backend | Best for | Shared across isolates |
|---|---|---|
| KV | Cloudflare Workers | Yes |
| Memory | Node.js, local development | No (per process) |
On Cloudflare, requests are served by many short-lived isolates across regions. KV is shared by all of them, so a value cached by one request is available to the next, anywhere. The memory backend caches within a single process, which suits a long-running Node.js server.
Cloudflare KV
Section titled “Cloudflare KV”Configure the KV adapter and point it at a KV binding:
import emdash from "emdash/astro";import { d1, r2, kvCache } from "@emdash-cms/cloudflare";
export default defineConfig({ integrations: [ emdash({ database: d1({ binding: "DB" }), storage: r2({ binding: "MEDIA" }), objectCache: kvCache({ binding: "CACHE" }), }), ],});Create a KV namespace and add the binding to your Wrangler configuration.
npx wrangler kv namespace create CACHEThe command prints a namespace id. Add it under the binding name used in kvCache:
{ "kv_namespaces": [ { "binding": "CACHE", "id": "<namespace-id>" } ]}[[kv_namespaces]]binding = "CACHE"id = "<namespace-id>"Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
binding |
string |
— | KV binding name from your Wrangler configuration. Required. |
defaultTtl |
number |
3600 |
Time-to-live for cached entries, in seconds. KV enforces a 60-second minimum. |
revalidate |
number |
1000 |
Isolate-local epoch-reuse window, in milliseconds. See Freshness. |
timeout |
number |
2000 |
Maximum time, in milliseconds, to wait for a KV operation before treating it as a cache miss. Guards against a stalled KV read hanging the request. Set to 0 to disable. |
keyPrefix |
string |
"em" |
Prefix for every cache key. Set a unique value when several sites share one namespace. |
Node.js (memory)
Section titled “Node.js (memory)”The memory adapter caches within the server process. It needs no external service:
import emdash, { memoryCache } from "emdash/astro";import { sqlite } from "emdash/db";
export default defineConfig({ integrations: [ emdash({ database: sqlite({ url: "file:./data.db" }), objectCache: memoryCache(), }), ],});Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
defaultTtl |
number |
3600 |
Time-to-live for cached entries, in seconds. |
revalidate |
number |
1000 |
Isolate-local epoch-reuse window, in ms. |
maxEntries |
number |
1000 |
Maximum number of cached keys before older keys evict. |
keyPrefix |
string |
"em" |
Prefix for every cache key. |
What gets cached
Section titled “What gets cached”The object cache covers the reads that run on a typical page render:
- Content queries:
getEmDashCollection,getEmDashEntry, andresolveEmDashPath. - Site settings, navigation menus, and taxonomy terms.
Admin API requests, media files, and full HTML responses are not handled here. To cache rendered HTML at the edge, see Deploy to Cloudflare.
The object cache and an HTML edge cache solve different problems. A cache miss in the HTML layer still runs the Worker; the object cache can then prevent repeated content queries. A hit in the HTML layer does not run EmDash at all.
Freshness
Section titled “Freshness”Editing content through the admin panel or the REST API invalidates the affected cache entries automatically. Creating, updating, publishing, or deleting an entry clears the cached queries for its collection; changing a byline or taxonomy term clears the entries that display it.
For anonymous visitors, a change takes time to appear across all isolates as they pick up the bumped epoch. With the in-isolate memory backend this is immediate. With Workers KV it is bounded by KV’s edge-cache propagation (eventual consistency, up to ~60 seconds) plus the isolate-local revalidate window (default one second). Lower revalidate for faster local propagation at the cost of more reads against the cache; raise it to read the cache less often.
Scheduled content
Section titled “Scheduled content”Scheduled entries become visible when their publish time passes. A cached page reflects a newly-published scheduled entry on the next change to its collection, or when the cached entry’s defaultTtl lapses. If precise scheduled publishing matters for your site, set a lower defaultTtl.