Skip to main content
Cache expensive upstream responses for a few minutes. This uses the KV binding (bound as MY_KV). The binding’s expirationTtl option is a no-op today, so this example enforces expiry in code with the putWithExpiry/getWithExpiry helpers from Key Expiration. (Server-side TTL is also available over REST via ttl_secs.)
import { env } from "@telnyx/edge-runtime";

const CACHE_TTL = 300; // 5 minutes

// Application-level expiry (see Key Expiration).
async function putWithExpiry(key: string, value: string, ttlSeconds: number) {
    await env.MY_KV.put(key, JSON.stringify({ value, expires_at: Date.now() + ttlSeconds * 1000 }));
}
async function getWithExpiry(key: string): Promise<string | null> {
    const w = await env.MY_KV.get<{ value: string; expires_at: number }>(key, { type: "json" });
    if (w === null) return null;
    if (Date.now() > w.expires_at) { await env.MY_KV.delete(key); return null; }
    return w.value;
}

export async function handler(request: Request): Promise<Response> {
    const cacheKey = `cache/api${new URL(request.url).pathname}`;

    const cached = await getWithExpiry(cacheKey);
    if (cached) {
        return new Response(cached, { headers: { "X-Cache": "HIT" } });
    }

    const upstream = await fetch("https://api.example.com/data");
    const data = await upstream.text();

    await putWithExpiry(cacheKey, data, CACHE_TTL);

    return new Response(data, { headers: { "X-Cache": "MISS" } });
}
Non-TypeScript functions build the same expiry envelope on top of the raw kvGet/kvPut REST helpers — or use the native ttl_secs REST parameter. See Key Expiration.