Skip to main content

Module cache

Module cache 

Source
Expand description

Caching: read-through values in Workers KV, HTTP Cache-Control/ETag and 304 responses.

Two opt-in tools, both chosen for the Workers free plan.

Values (fetch, read, write, delete) are JSON in the CACHE KV namespace (ocre g cache adds the binding to cloudflare.config.ts; ocre deploy creates the namespace). Use them for results that are slow or costly to compute and read far more often than they change: an external API call, a D1 aggregate over many rows. fetch is Rails’ Rails.cache.fetch; the other three are the explicit forms.

use std::time::Duration;

use axum::{Json, extract::State};
use ocre::{Ctx, Result};

async fn stats(State(ctx): State<Ctx>) -> Result<Json<Stats>> {
    // One KV read; a miss runs the closure and costs one KV write.
    let stats: Stats = ocre::cache::fetch(&ctx, "stats:v1", Duration::from_secs(3600), || async {
        Stats::compute(&ctx).await
    })
    .await?;
    Ok(Json(stats))
}

Free plan (September 2026): 100,000 KV reads and 1,000 writes a day (writes and deletes to different keys; one write per second per key), 1 GB stored. Each fetch costs one read; a miss adds one write. A key refreshed every ttl seconds costs up to 86,400 / ttl writes a day: a one-hour TTL is 24 writes per key, so about 40 hot keys fit in the budget. KV accepts TTLs of MIN_TTL (60 seconds) or more. KV is eventually consistent: other locations may see an old value for up to 60 seconds after a write or delete. Past a daily limit, KV operations fail; fetch then logs the failure (prefixed with LOG_PREFIX) and computes the value, so pages keep working.

Values are the JSON of the type; put a version in the key (stats:v1) and change it when the type changes. A stored value that no longer decodes is logged and treated as a miss.

HTTP: CacheControl and ETag are response parts, and Conditional answers 304 Not Modified without rendering when the browser’s copy is current, like Rails’ fresh_when. That saves CPU (no template rendering) and bandwidth, never KV operations; the database query still runs.

The Workers Cache API (caches.default) is not wrapped: it is a no-op on *.workers.dev, where Ocre apps deploy by default, and still runs the Worker on every request. To have Cloudflare serve whole pages without running the Worker, see “Workers Cache” in the README: it honors the CacheControl::public header (hits still count toward the 100,000 requests a day).

Structs§

CacheControl
A Cache-Control response header, built from one of four policies.
Cleared
What clear deleted.
Conditional
Extractor for the request’s If-None-Match, to answer 304 Not Modified without rendering.
ETag
An entity tag naming the version of what a page shows: weak (W/"<hash>", the default) or strong ("<hash>").
Fragment
A cached piece of HTML, from fragment or fragments.

Constants§

CACHE_BINDING
Name of the KV namespace binding holding cached values: CACHE.
FRAGMENT_PREFIX
Prefix of the KV keys holding fragments: views/, as in Rails.
LOG_PREFIX
Prefix of every line Ocre logs about the cache: [ocre cache].
MIN_TTL
Shortest TTL KV accepts (expirationTtl): 60 seconds.
STORE_VAR
Name of the Worker variable choosing the cache store: CACHE_STORE.

Functions§

clear
Deletes up to limit cached values whose key starts with prefix (Rails’ Rails.cache.clear, bounded): "" for everything, "views/" for fragments, "posts/" for one family of keys. Call it again while Cleared::more is true, e.g. from a scheduled task after a deploy that changed the cached data’s shape.
delete
Removes key, e.g. after the data behind it changed (Rails’ Rails.cache.delete).
fetch
Read-through cache, like Rails’ Rails.cache.fetch: the value under key in KV, or else the result of compute.
fragment
Fragment caching, like Rails’ <% cache post do %>: the HTML stored under key, or else the template build returns, rendered and stored.
fragments
Collection caching, like Rails’ render collection:, cached: true: one Fragment per item, read from KV in bulk.
key
Builds a cache key from its parts joined by /, like Rails’ cache_key_with_version.
read
The value under key, or None when it is absent, expired, unreadable as T, or when KV fails.
write
Stores value as JSON under key for ttl, replacing any previous value.