Skip to content

Workers KV -- Read, Write and Delete Operations

DodaTech 5 min read

In this tutorial, you'll learn about Workers KV. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Workers KV provides a complete CRUD API -- put, get, delete, and list -- that lets you read and write data from Cloudflare's global edge network with simple JavaScript calls from your Worker code.

Why KV CRUD Operations Matter

Building dynamic applications at the edge requires persistent storage that works as fast as the compute layer itself. The KV CRUD API mirrors familiar database operations but is optimized for edge distribution. Every put triggers global Replication, every get reads from the nearest node, and every delete removes data worldwide. Understanding these operations in detail lets you build Caching layers, user session stores, and configuration services that work globally. Combined with Cloudflare Workers and REST APIs, KV operations form the data persistence backbone of Serverless edge applications.

Real-world use: A URL shortener service uses KV with a short code as the key and the target URL as the value. Each redirect reads from the nearest edge node in under 5ms, while new short links propagate globally within seconds.

KV Write Operation Flow

flowchart LR
    W[Worker] --> P[KV put]
    P --> C[Cache at write edge]
    C --> R[Replicate globally]
    R --> E1[Edge 1]
    R --> E2[Edge 2]
    R --> E3[Edge N]
    C --> G[KV get reads from cache]
    W --> D[KV delete]
    D --> DR[Delete propagates globally]
    style P fill:#f90,color:#fff
    style D fill:#f90,color:#fff

Writing Values with put

The put method stores a key-value pair. You can set expiration and metadata.

export default {
  async fetch(request, env) {
    const userId = 'user_42';
    const session = JSON.stringify({
      id: userId,
      loginAt: new Date().toISOString(),
      role: 'admin'
    });
    await env.MY_KV.put(`session:${userId}`, session, {
      expirationTtl: 3600,
      metadata: { source: 'login-endpoint', version: 1 }
    });
    return new Response(`Session stored for ${userId}`, {
      headers: { 'Content-Type': 'text/plain' }
    });
  }
}

Expected output: The session data is stored under key session:user_42 with a 1-hour TTL. The metadata object {source: "login-endpoint", version: 1} is attached and retrievable via getWithMetadata.

Reading Values with get and getWithMetadata

Read values back individually or with their associated metadata.

export default {
  async fetch(request, env) {
    const key = 'session:user_42';
    const value = await env.MY_KV.get(key);
    const { value: valWithMeta, metadata } = await env.MY_KV.getWithMetadata(key);
    return new Response(JSON.stringify({
      raw: value,
      withMetadata: valWithMeta,
      metadata: metadata
    }), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

Expected output: Returns the session JSON string for both raw and withMetadata, plus the metadata object previously attached. Using getWithMetadata avoids a second round trip to fetch metadata separately.

Deleting Values

Remove keys with delete. Bulk delete with a list operation.

export default {
  async fetch(request, env) {
    await env.MY_KV.put('temp_data', 'will be deleted soon');
    const beforeDelete = await env.MY_KV.get('temp_data');
    await env.MY_KV.delete('temp_data');
    const afterDelete = await env.MY_KV.get('temp_data');
    return new Response(JSON.stringify({
      beforeDelete,
      afterDelete,
      exists: afterDelete !== null
    }), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

Expected output: beforeDelete returns "will be deleted soon". afterDelete returns null because the key no longer exists. Confirms the delete operation completed.

Bulk Writes with Wrangler CLI

For large initial data loads, use wrangler kv:key bulk with a JSON file.

[
  {"key": "redirects/abc", "value": "https://example.com/page1"},
  {"key": "redirects/def", "value": "https://example.com/page2"},
  {"key": "redirects/ghi", "value": "https://example.com/page3"}
]
wrangler kv:key bulk --namespace-id=abc123def bulk-data.json
export default {
  async fetch(request, env) {
    const keys = await env.MY_KV.list({ prefix: 'redirects/' });
    const redirects = {};
    for (const key of keys.keys) {
      redirects[key.name] = await env.MY_KV.get(key.name);
    }
    return new Response(JSON.stringify(redirects), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

Expected output: All three redirect entries are preloaded. The Worker lists keys with the redirects/ prefix and returns a map of all short codes to target URLs. Bulk operations handle up to 10,000 keys per request.

Common Errors

Error Cause Fix
Key length exceeds limit Key longer than 512 bytes Shorten the key or use a hash-based naming scheme
Value size limit exceeded Value over 25MB Compress data or switch to R2 for large objects
Bulk payload too large JSON file over 100MB Split into multiple bulk files of 100MB or less
Key not found on getWithMetadata Key does not exist or not yet propagated Always check for null return value before processing metadata
Cannot delete non-existent key Deleting a key that never existed Use get first to verify existence or treat delete as idempotent

Practice Questions

  1. What is the difference between get and getWithMetadata in Workers KV?
  2. How do you set a time-to-live when writing a KV value with put?
  3. What is the maximum number of keys you can write in a single bulk operation?

FAQ

Is the delete operation in KV immediate?

Delete operations propagate globally within seconds, similar to writes. Once propagated, the key returns null from all edge locations. There is no undo -- deleted keys cannot be recovered.

Can I update metadata without rewriting the value?

No, you must use put with both the value and metadata to update metadata. There is no separate metadata-only update operation in Workers KV.

Summary

Workers KV supports the full CRUD lifecycle: put to write with optional TTL and metadata, get and getWithMetadata to read, delete to remove, and list to enumerate keys. Bulk operations via the Wrangler CLI handle large-scale data loading. These primitives power production systems like Doda Browser's redirect service and Durga Antivirus Pro's signature update distribution across the global edge network. Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro -- security-first tools for the modern web.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro