Back to Blog
Lesson 41 of the Cloudflare: Cloudflare for Developers: DNS to CDN course
Cloud NativeAugust 19, 20263 min read

Working with KV Storage: Fast Global State for Cloudflare Workers

Learn how to implement Workers KV for high-performance, low-latency state management. Master namespace creation, CRUD operations, and choosing the right storage.

CloudflareWorkersKVStorageServerlessPerformance
Two workers manage inventory in a spacious warehouse aisle.

Previously in this course, we covered handling CORS in Workers to ensure your API remains secure and accessible. This lesson introduces KV (Key-Value) Storage, a powerful tool for maintaining state at the edge, distinct from the relational databases and object storage we've used previously.

Understanding KV Storage from First Principles

Workers KV is a globally distributed key-value store. Unlike a traditional database that lives in one physical location, KV replicates your data to Cloudflare’s entire global network. When you write a value, it eventually propagates to every edge location; when you read it, you are hitting a cache local to the user, providing sub-millisecond response times.

Think of it as a "global dictionary" for your application. It is perfect for data that is read frequently but written infrequently, such as session tokens, user preferences, or site-wide configuration flags.

When to use KV vs. D1 vs. R2

Choosing the right storage is critical for architectural performance. Here is how they compare:

FeatureKV StorageD1 (SQL)R2 (Object)
Data ModelKey-Value (String)Relational (SQL)Binary (Files/Blobs)
ConsistencyEventualStrongStrong
Best ForRead-heavy stateComplex queriesLarge assets/media
LatencyExtremely lowMedium (Regional)Medium

Implementing KV in Your Project

To start using KV, we first need to create a namespace. A namespace is essentially a container for your keys.

1. Create the Namespace

Using the Wrangler CLI, run the following command in your terminal:

Bash
npx wrangler kv:namespace create "MY_APP_KV"

Wrangler will return a binding configuration. Copy this and add it to your wrangler.toml:

TOML
[[kv_namespaces]]
binding = "MY_APP_KV"
id = "your-namespace-id-here"

2. Writing and Reading Values

Now that the binding exists, you can access it inside your Worker via env.MY_APP_KV. Here is a practical example of a counter that tracks how many times an endpoint has been hit:

JAVASCRIPT
export default {
  async fetch(request, env) {
    const key = "hit_count";
    
    // Read the current value
    let count = await env.MY_APP_KV.get(key);
    count = parseInt(count || "0") + 1;
    
    // Write the new value
    await env.MY_APP_KV.put(key, count.toString());
    
    return new Response(CE9178">`Total hits: ${count}`);
  },
};

Hands-on Exercise

  1. Initialize: Create a new KV namespace in your local project as shown above.
  2. Implement: Update your existing worker to store a "last_visited" timestamp for users. Use new Date().toISOString() as the value.
  3. Verify: Deploy your worker and check the Cloudflare Dashboard under Workers & Pages > KV to see the keys being generated in your namespace.

Common Pitfalls

  • Eventual Consistency: Remember that KV is "eventually consistent." If you update a value and immediately read it from a different global location, you might see the old value for a few seconds. Do not use KV for data that requires strictly atomic transactions (use D1 for that).
  • Key Limits: While you can store millions of keys, ensure your key naming convention is hierarchical (e.g., user:123:profile) to keep organization clean.
  • Write Throughput: KV is optimized for reads. If you need to perform thousands of writes per second, you might hit rate limits. For high-write scenarios, consider handling background tasks to batch updates.

FAQ

Can I store JSON in KV? Yes, but you must stringify it before put() and parse it after get(). KV only stores strings.

Is KV free? Cloudflare offers a generous free tier, but check the Cloudflare Pricing page for current limits on read/write operations and total storage volume.

Can I delete keys? Yes, use await env.MY_APP_KV.delete(key).

Recap

We've explored how KV provides high-performance, global state management for your edge applications. You now know how to provision a namespace, integrate it into your Worker code, and differentiate its use case from R2 and D1.

Up next: We will look at Queueing Tasks to handle complex, asynchronous workflows in your serverless stack.

Similar Posts