Cache
Add a Redis-backed, ephemeral key-value cache to your workers with optional TTL expiry.
Cache
Ploy Cache provides a fast, ephemeral key-value store backed by Redis. Unlike State, which is durable, Cache is meant for transient data such as computed results, rate-limit counters, or short-lived session data. Each entry can optionally expire after a TTL.
Cache is best-effort, not durable storage. TTLs are not guaranteed and entries
may be evicted at any time — for example under memory pressure — even before
their TTL elapses. Always handle a null result from get(), and never rely
on cached data being present. For data that must persist, use
State.
Configuration
Add a cache binding in your ploy.yaml:
kind: dynamic
build: pnpm build
out: dist
cache:
CACHE: defaultThe key (CACHE) is the binding name available in your worker's env. The
value (default) is the cache store identifier.
Run ploy types to generate TypeScript types:
import type { CacheBinding } from "@meetploy/types";
export interface Env {
CACHE: CacheBinding;
}Basic Example
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/set") {
// Cache for 60 seconds
await env.CACHE.set("greeting", "hello", { ttl: 60 });
return Response.json({ success: true });
}
if (url.pathname === "/get") {
const value = await env.CACHE.get("greeting");
return Response.json({ value });
}
return new Response("Cache Worker");
},
} satisfies Ploy;API Methods
get(key) - Get a Value
Returns the stored string value, or null if the key doesn't exist or has
expired.
const value = await env.CACHE.get("my-key");
// value is string | nullset(key, value, options?) - Store a Value
Stores a string value, overwriting any existing value for the key. Pass an
optional ttl (in seconds) to make the entry expire automatically. Without a
ttl, the value is stored until it is overwritten or evicted by Redis.
// Store without expiry
await env.CACHE.set("username", "alice");
// Store for 5 minutes
await env.CACHE.set("session:abc", token, { ttl: 300 });Common Patterns
Caching Expensive Computations
async function getReport(env: PloyEnv, id: string) {
const cached = await env.CACHE.get(`report:${id}`);
if (cached) {
return JSON.parse(cached);
}
const report = await computeExpensiveReport(id);
// Cache for 10 minutes
await env.CACHE.set(`report:${id}`, JSON.stringify(report), { ttl: 600 });
return report;
}Rate Limiting
async function isRateLimited(env: PloyEnv, ip: string): Promise<boolean> {
const key = `ratelimit:${ip}`;
const seen = await env.CACHE.get(key);
if (seen) {
return true;
}
// Block repeat requests from the same IP for 1 second
await env.CACHE.set(key, "1", { ttl: 1 });
return false;
}Short-Lived Session Data
// Store a one-time token for 15 minutes
await env.CACHE.set(`otp:${userId}`, code, { ttl: 900 });
// Later, validate it
const stored = await env.CACHE.get(`otp:${userId}`);
const valid = stored !== null && stored === submittedCode;Multiple Cache Bindings
You can configure multiple cache stores for different use cases:
cache:
CACHE: default
SESSION_CACHE: sessionsawait env.CACHE.set("config", value, { ttl: 60 });
await env.SESSION_CACHE.set(`user:${id}`, sessionData, { ttl: 3600 });Next Steps
How is this guide?
Last updated on