Skip to content

Workers KV -- Key-Value Storage at the Edge

DodaTech 4 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.

Cloudflare Workers KV is a globally distributed key-value store that replicates data across Cloudflare's edge network, giving your Workers access to persistent storage with read latencies under 10 milliseconds from any location worldwide.

Why Workers KV Matters

Traditional databases place your data in a single region, forcing remote users to wait for round trips across continents. Workers KV flips this model by replicating every key-value pair to all 330+ Cloudflare data centers. Reads are served from the nearest edge location, while writes propagate globally within seconds. This architecture powers configuration storage, A/B testing flags, static asset serving, and session data for Serverless applications built with Cloudflare. Unlike traditional REST APIs that require connection pooling and query Parsing, KV offers a simple get/set/delete interface designed for edge workloads.

Real-world use: A documentation site stores translated content in Workers KV with language-based keys. A Japanese user in Tokyo reads docs/ja/welcome from the Tokyo edge node in under 5ms, while a German user reads docs/de/welcome from Frankfurt with the same speed -- both without hitting a central database.

KV Storage Architecture

flowchart LR
    W[Worker] --> KV[Workers KV]
    KV --> R[Read from nearest edge]
    W --> P[Write/Put]
    P --> Prop[Global propagation]
    Prop --> E1[Edge EU]
    Prop --> E2[Edge US]
    Prop --> E3[Edge Asia]
    Prop --> E4[Edge Oceania]
    style KV fill:#f90,color:#fff
    style Prop fill:#f90,color:#fff

Creating and Binding a KV Namespace

Before using KV, create a namespace and bind it to your Worker in wrangler.toml.

wrangler kv:namespace create MY_KV
# Creates namespace with ID: abc123def
# wrangler.toml
name = "kv-worker"
main = "src/index.js"

[[kv_namespaces]]
binding = "MY_KV"
id = "abc123def"
export default {
  async fetch(request, env) {
    await env.MY_KV.put('greeting', 'Hello from Workers KV!');
    const value = await env.MY_KV.get('greeting');
    return new Response(value, {
      headers: { 'Content-Type': 'text/plain' }
    });
  }
}

Expected output: The Worker writes the string Hello from Workers KV! to the KV namespace and then reads it back, returning it as the HTTP response. This demonstrates the fundamental put-get cycle.

Reading Values with Type Options

KV returns values as strings by default, but you can request different types.

export default {
  async fetch(request, env) {
    await env.MY_KV.put('counter', '42');
    await env.MY_KV.put('config', JSON.stringify({ theme: 'dark', lang: 'en' }));
    const str = await env.MY_KV.get('counter');
    const num = await env.MY_KV.get('counter', { type: 'text' });
    const config = await env.MY_KV.get('config', { type: 'json' });
    return new Response(JSON.stringify({
      string: str,
      numberValue: num,
      parsedConfig: config
    }), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

Expected output: str and num both return "42" as text. config is auto-parsed as JSON and returns {"theme": "dark", "lang": "en"} as a JavaScript object. The json type throws if the stored value is not valid JSON.

Listing Keys with Prefixes

You can list keys matching a prefix, useful for directory-style structures.

export default {
  async fetch(request, env) {
    await env.MY_KV.put('users/alice/name', 'Alice');
    await env.MY_KV.put('users/alice/email', 'alice@example.com');
    await env.MY_KV.put('users/bob/name', 'Bob');
    await env.MY_KV.put('users/bob/email', 'bob@example.com');
    const userList = await env.MY_KV.list({ prefix: 'users/' });
    return new Response(JSON.stringify({
      keys: userList.keys.map(k => k.name),
      count: userList.keys.length
    }), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

Expected output: Returns {"keys": ["users/alice/name", "users/alice/email", "users/bob/name", "users/bob/email"], "count": 4}. The list method supports pagination with cursor and limit parameters for large namespaces.

Common Errors

Error Cause Fix
Namespace not found Binding name does not match wrangler.toml Verify the binding name in [[kv_namespaces]] matches the Worker code
KV put value exceeds limit Value larger than 25MB Split large data into chunks or use R2 object storage
Key not found Reading a key that does not exist Check that the key was written and propagated (eventual consistency)
Operation timed out Network issue during KV operation Retry with exponential backoff; ensure the namespace ID is correct
Cannot write to KV Free plan daily write limit exceeded Upgrade to a paid plan or wait for the daily limit to reset

Practice Questions

  1. What type of consistency does Workers KV provide and why is it designed this way?
  2. How do you bind a KV namespace to a Worker in wrangler.toml?
  3. What happens when you use { type: 'json' } on a value that is not valid JSON?

FAQ

What is the maximum value size in Workers KV?

The maximum value size is 25 MB per key. For larger payloads, use Cloudflare R2 object storage which supports up to 5 TB per object with S3-compatible APIs.

How long does it take for a KV write to propagate globally?

KV writes typically propagate to all edge locations within 60 seconds. You can use the cacheTTL option or Workers Cache API to serve stale data while propagation completes, ensuring consistent reads for critical keys.

Summary

Workers KV gives your Serverless applications globally replicated key-value storage with single-millisecond reads from 330+ edge locations. The simple get/put/list/delete interface handles configuration, content, session data, and feature flags without connection pools or query languages. This technology powers Doda Browser's per-user privacy settings and Durga Antivirus Pro's threat signature distribution across global edge nodes. 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