Ploy
Ploy
Features

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:

ploy.yaml
kind: dynamic
build: pnpm build
out: dist
cache:
  CACHE: default

The 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:

env.d.ts
import type { CacheBinding } from "@meetploy/types";

export interface Env {
	CACHE: CacheBinding;
}

Basic Example

src/index.ts
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 | null

set(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:

ploy.yaml
cache:
  CACHE: default
  SESSION_CACHE: sessions
await env.CACHE.set("config", value, { ttl: 60 });
await env.SESSION_CACHE.set(`user:${id}`, sessionData, { ttl: 3600 });

Next Steps

  • State - Durable key-value storage
  • Databases - Add persistent SQLite databases
  • Workers - Learn about Ploy workers

How is this guide?

Last updated on