Store key-value data globally with Cloudflare KV's edge network. Use when: caching API responses, storing configuration, managing user preferences, handling TTL expiration, or troubleshooting KV_ERROR, 429 rate limits, eventual consistency, cacheTtl errors, wrangler types issues, or remote binding configuration.
View on GitHubSelect agents to install to:
npx add-skill https://github.com/jezweb/claude-skills/blob/main/skills/cloudflare-kv/SKILL.md -a claude-code --skill cloudflare-kvInstallation paths:
.claude/skills/cloudflare-kv/# Cloudflare Workers KV
**Status**: Production Ready ✅
**Last Updated**: 2026-01-20
**Dependencies**: cloudflare-worker-base (for Worker setup)
**Latest Versions**: wrangler@4.59.2, @cloudflare/workers-types@4.20260109.0
**Recent Updates (2025)**:
- **August 2025**: Architecture redesign (40x performance gain, <5ms p99 latency, hybrid storage with R2)
- **April 2025**: Bulk reads API (retrieve up to 100 keys in single request, counts as 1 operation)
- **January 2025**: Namespace limit increased (200 → 1,000 namespaces per account for Free and Paid plans)
---
## Quick Start (5 Minutes)
```bash
# Create namespace
npx wrangler kv namespace create MY_NAMESPACE
# Output: [[kv_namespaces]] binding = "MY_NAMESPACE" id = "<UUID>"
```
**wrangler.jsonc:**
```jsonc
{
"kv_namespaces": [{
"binding": "MY_NAMESPACE", // Access as env.MY_NAMESPACE
"id": "<production-uuid>",
"preview_id": "<preview-uuid>" // Optional: local dev
}]
}
```
**Basic Usage:**
```typescript
type Bindings = { MY_NAMESPACE: KVNamespace };
app.post('/set/:key', async (c) => {
await c.env.MY_NAMESPACE.put(c.req.param('key'), await c.req.text());
return c.json({ success: true });
});
app.get('/get/:key', async (c) => {
const value = await c.env.MY_NAMESPACE.get(c.req.param('key'));
return value ? c.json({ value }) : c.json({ error: 'Not found' }, 404);
});
```
---
## KV API Reference
### Read Operations
```typescript
// Get single key
const value = await env.MY_KV.get('key'); // string | null
const data = await env.MY_KV.get('key', { type: 'json' }); // object | null
const buffer = await env.MY_KV.get('key', { type: 'arrayBuffer' });
const stream = await env.MY_KV.get('key', { type: 'stream' });
// Get with cache (minimum 60s)
const value = await env.MY_KV.get('key', { cacheTtl: 300 }); // 5 min edge cache
// Bulk read (counts as 1 operation)
const values = await env.MY_KV.get(['key1', 'key2']); // Map<string, string | null>
// With metadata
const { value, metadata