Skip to main content
KV stores values as opaque bytes. It has no server-side TTL and no per-key metadata — a value is exactly the bytes you write, and it lives until you delete it.
There are no expiration_ttl, expiration, or metadata fields on a write, and no --ttl/--metadata CLI flags. Anything you put in the request body (including JSON that looks like those fields) is stored verbatim as the value, not interpreted.

Expiring keys at the application level

To get expiry behavior, wrap your value with an expires_at timestamp and check it when you read. If it’s in the past, treat the key as missing (and optionally delete it).
// Built on the raw kvGet/kvPut from the Quick Start.

async function kvPutWithExpiry(key, value, ttlSeconds) {
    const envelope = JSON.stringify({
        value,
        expires_at: Date.now() + ttlSeconds * 1000,
    });
    await kvPut(key, envelope);
}

async function kvGetWithExpiry(key) {
    const raw = await kvGet(key);
    if (raw === null) return null;                 // key not found

    const { value, expires_at } = JSON.parse(raw);
    if (Date.now() > expires_at) {
        await kvDelete(key);                        // lazily clean up
        return null;                                // expired
    }
    return value;
}

// kvDelete helper
async function kvDelete(key) {
    await fetch(`${BASE}/${encodeURIComponent(key)}`, {
        method: "DELETE",
        headers: { "Authorization": `Bearer ${API_KEY}` },
    });
}
// Usage: a session that "expires" after one hour
await kvPutWithExpiry("session/abc", JSON.stringify({ userId: 42 }), 3600);

const session = await kvGetWithExpiry("session/abc"); // null once an hour has passed
Notes on this pattern:
  • Reads do the enforcing. An expired key still occupies storage until it’s read (and lazily deleted) or you delete it explicitly. Run a periodic sweep with cron triggers if you need eager cleanup.
  • Use a consistent clock. Date.now() on the edge node is fine for coarse expiry; don’t rely on it for sub-second precision.
  • Keep the envelope small. You pay for stored bytes, so the wrapper adds a little overhead per key.