Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/kv/api.md
1# KV API Reference23## Read Operations45```typescript6// Single key (string)7const value = await env.MY_KV.get("user:123");89// JSON type (auto-parsed)10const config = await env.MY_KV.get<AppConfig>("config", "json");1112// ArrayBuffer for binary13const buffer = await env.MY_KV.get("image", "arrayBuffer");1415// Stream for large values16const stream = await env.MY_KV.get("large-file", "stream");1718// With cache TTL (min 60s)19const value = await env.MY_KV.get("key", { type: "text", cacheTtl: 300 });2021// Bulk get (max 100 keys, counts as 1 operation)22const keys = ["user:1", "user:2", "user:3", "missing:key"];23const results = await env.MY_KV.get(keys);24// Returns Map<string, string | null>2526console.log(results.get("user:1")); // "John" (if exists)27console.log(results.get("missing:key")); // null2829// Process results with null handling30for (const [key, value] of results) {31if (value !== null) {32// Handle found keys33console.log(`${key}: ${value}`);34}35}3637// TypeScript with generics (type-safe JSON parsing)38interface UserProfile { name: string; email: string; }39const profile = await env.USERS.get<UserProfile>("user:123", "json");40// profile is typed as UserProfile | null41if (profile) {42console.log(profile.name); // Type-safe access43}4445// Bulk get with type46const configs = await env.MY_KV.get<Config>(["config:app", "config:feature"], "json");47// Map<string, Config | null>48```4950## Write Operations5152```typescript53// Basic put54await env.MY_KV.put("key", "value");55await env.MY_KV.put("config", JSON.stringify({ theme: "dark" }));5657// With expiration (UNIX timestamp)58await env.MY_KV.put("session", token, {59expiration: Math.floor(Date.now() / 1000) + 360060});6162// With TTL (seconds from now, min 60)63await env.MY_KV.put("cache", data, { expirationTtl: 300 });6465// With metadata (max 1024 bytes)66await env.MY_KV.put("user:profile", userData, {67metadata: { version: 2, lastUpdated: Date.now() }68});6970// Combined71await env.MY_KV.put("temp", value, {72expirationTtl: 3600,73metadata: { temporary: true }74});75```7677## Get with Metadata7879```typescript80// Single key81const result = await env.MY_KV.getWithMetadata("user:profile");82// { value: string | null, metadata: any | null }8384if (result.value && result.metadata) {85const { version, lastUpdated } = result.metadata;86}8788// Multiple keys (bulk)89const keys = ["key1", "key2", "key3"];90const results = await env.MY_KV.getWithMetadata(keys);91// Returns Map<string, { value, metadata, cacheStatus? }>9293for (const [key, result] of results) {94if (result.value) {95console.log(`${key}: ${result.value}`);96console.log(`Metadata: ${JSON.stringify(result.metadata)}`);97// cacheStatus field indicates cache hit/miss (when available)98}99}100101// With type102const result = await env.MY_KV.getWithMetadata<UserData>("user:123", "json");103// result: { value: UserData | null, metadata: any | null, cacheStatus?: string }104```105106## Delete Operations107108```typescript109await env.MY_KV.delete("key"); // Always succeeds (even if key missing)110```111112## List Operations113114```typescript115// List all116const keys = await env.MY_KV.list();117// { keys: [...], list_complete: boolean, cursor?: string }118119// With prefix120const userKeys = await env.MY_KV.list({ prefix: "user:" });121122// Pagination123let cursor: string | undefined;124let allKeys = [];125do {126const result = await env.MY_KV.list({ cursor, limit: 1000 });127allKeys.push(...result.keys);128cursor = result.cursor;129} while (!result.list_complete);130```131132## Performance Considerations133134### Type Selection135136| Type | Use Case | Performance |137|------|----------|-------------|138| `stream` | Large values (>1MB) | Fastest - no buffering |139| `arrayBuffer` | Binary data | Fast - single allocation |140| `text` | String values | Medium |141| `json` | Objects (parse overhead) | Slowest - parsing cost |142143### Parallel Reads144145```typescript146// Efficient parallel reads with Promise.all()147const [user, settings, cache] = await Promise.all([148env.USERS.get("user:123", "json"),149env.SETTINGS.get("config:app", "json"),150env.CACHE.get("data:latest")151]);152```153154## Error Handling155156- **Missing keys:** Return `null` (not an error)157- **Rate limit (429):** Retry with exponential backoff (see gotchas.md)158- **Response too large (413):** Values >25MB fail with 413 error159160See [gotchas.md](./gotchas.md) for detailed error patterns and solutions.161