cloudflare
references/kv/api.md
.md 161 lines
Content
# KV API Reference
## Read Operations
```typescript
// Single key (string)
const value = await env.MY_KV.get("user:123");
// JSON type (auto-parsed)
const config = await env.MY_KV.get<AppConfig>("config", "json");
// ArrayBuffer for binary
const buffer = await env.MY_KV.get("image", "arrayBuffer");
// Stream for large values
const stream = await env.MY_KV.get("large-file", "stream");
// With cache TTL (min 60s)
const value = await env.MY_KV.get("key", { type: "text", cacheTtl: 300 });
// Bulk get (max 100 keys, counts as 1 operation)
const keys = ["user:1", "user:2", "user:3", "missing:key"];
const results = await env.MY_KV.get(keys);
// Returns Map<string, string | null>
console.log(results.get("user:1")); // "John" (if exists)
console.log(results.get("missing:key")); // null
// Process results with null handling
for (const [key, value] of results) {
if (value !== null) {
// Handle found keys
console.log(`${key}: ${value}`);
}
}
// TypeScript with generics (type-safe JSON parsing)
interface UserProfile { name: string; email: string; }
const profile = await env.USERS.get<UserProfile>("user:123", "json");
// profile is typed as UserProfile | null
if (profile) {
console.log(profile.name); // Type-safe access
}
// Bulk get with type
const configs = await env.MY_KV.get<Config>(["config:app", "config:feature"], "json");
// Map<string, Config | null>
```
## Write Operations
```typescript
// Basic put
await env.MY_KV.put("key", "value");
await env.MY_KV.put("config", JSON.stringify({ theme: "dark" }));
// With expiration (UNIX timestamp)
await env.MY_KV.put("session", token, {
expiration: Math.floor(Date.now() / 1000) + 3600
});
// With TTL (seconds from now, min 60)
await env.MY_KV.put("cache", data, { expirationTtl: 300 });
// With metadata (max 1024 bytes)
await env.MY_KV.put("user:profile", userData, {
metadata: { version: 2, lastUpdated: Date.now() }
});
// Combined
await env.MY_KV.put("temp", value, {
expirationTtl: 3600,
metadata: { temporary: true }
});
```
## Get with Metadata
```typescript
// Single key
const result = await env.MY_KV.getWithMetadata("user:profile");
// { value: string | null, metadata: any | null }
if (result.value && result.metadata) {
const { version, lastUpdated } = result.metadata;
}
// Multiple keys (bulk)
const keys = ["key1", "key2", "key3"];
const results = await env.MY_KV.getWithMetadata(keys);
// Returns Map<string, { value, metadata, cacheStatus? }>
for (const [key, result] of results) {
if (result.value) {
console.log(`${key}: ${result.value}`);
console.log(`Metadata: ${JSON.stringify(result.metadata)}`);
// cacheStatus field indicates cache hit/miss (when available)
}
}
// With type
const result = await env.MY_KV.getWithMetadata<UserData>("user:123", "json");
// result: { value: UserData | null, metadata: any | null, cacheStatus?: string }
```
## Delete Operations
```typescript
await env.MY_KV.delete("key"); // Always succeeds (even if key missing)
```
## List Operations
```typescript
// List all
const keys = await env.MY_KV.list();
// { keys: [...], list_complete: boolean, cursor?: string }
// With prefix
const userKeys = await env.MY_KV.list({ prefix: "user:" });
// Pagination
let cursor: string | undefined;
let allKeys = [];
do {
const result = await env.MY_KV.list({ cursor, limit: 1000 });
allKeys.push(...result.keys);
cursor = result.cursor;
} while (!result.list_complete);
```
## Performance Considerations
### Type Selection
| Type | Use Case | Performance |
|------|----------|-------------|
| `stream` | Large values (>1MB) | Fastest - no buffering |
| `arrayBuffer` | Binary data | Fast - single allocation |
| `text` | String values | Medium |
| `json` | Objects (parse overhead) | Slowest - parsing cost |
### Parallel Reads
```typescript
// Efficient parallel reads with Promise.all()
const [user, settings, cache] = await Promise.all([
env.USERS.get("user:123", "json"),
env.SETTINGS.get("config:app", "json"),
env.CACHE.get("data:latest")
]);
```
## Error Handling
- **Missing keys:** Return `null` (not an error)
- **Rate limit (429):** Retry with exponential backoff (see gotchas.md)
- **Response too large (413):** Values >25MB fail with 413 error
See [gotchas.md](./gotchas.md) for detailed error patterns and solutions.