Back to skills
SKILL.md
1228 Patterns 448bef6e
ASecurity```typescript // Memory → KV → Origin (3-tier cache) const memoryCache = new Map<string, { data: any; expires: number }>()
- 9 stars
- 0 votes
- 0 copies
- 0 views
- Added October 11, 2026
Works with
Security analysis
100/100npx -y skills add tools-only/X-Skills --skill 1228-patterns_448bef6e --agent claude-codeAre you the author of 1228 Patterns 448bef6e?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-1228-patterns-448bef6e)# KV Patterns & Best Practices
## Multi-Tier Caching
```typescript
// Memory → KV → Origin (3-tier cache)
const memoryCache = new Map<string, { data: any; expires: number }>()
async function getCached(env: Env, key: string): Promise<any> {
const now = Date.now()
// L1: Memory cache (fastest)
const cached = memoryCache.get(key)
if (cached && cached.expires > now) {
return cached.data
}
// L2: KV cache (fast)
const kvValue = await env.CACHE.get(key, 'json')
if (kvValue) {
memoryCache.set(key, { data: kvValue, expires: now + 60000 }) // 1min in memory
return kvValue
}
// L3: Origin (slow)
const origin = await fetch(`https://api.example.com/${key}`).then((r) => r.json())
// Backfill caches
await env.CACHE.put(key, JSON.stringify(origin), { expirationTtl: 300 }) // 5min in KV
memoryCache.set(key, { data: origin, expires: now + 60000 })
return origin
}
```
## API Response Caching
```typescript
async function getCachedData(env: Env, key: string, fetcher: () => Promise<any>): Promise<any> {
const cached = await env.MY_KV.get(key, 'json')
if (cached) return cached
const data = await fetcher()
await env.MY_KV.put(key, JSON.stringify(data), { expirationTtl: 300 })
return data
}
const apiData = await getCachedData(env, 'cache:users', () =>
fetch('https://api.example.com/users').then((r) => r.json()),
)
```
## Session Management
```typescript
interface Session {
userId: string
expiresAt: number
}
async function createSession(env: Env, userId: string): Promise<string> {
const sessionId = crypto.randomUUID()
const expiresAt = Date.now() + 24 * 60 * 60 * 1000
await env.SESSIONS.put(`session:${sessionId}`, JSON.stringify({ userId, expiresAt }), {
expirationTtl: 86400,
metadata: { createdAt: Date.now() },
})
return sessionId
}
async function getSession(env: Env, sessionId: string): Promise<Session | null> {
const data = await env.SESSIONS.get<Session>(`session:${sessionId}`, 'json')
if (!data || data.expiresAt < Date.now()) return null
return data
}
```
## Coalesce Cold Keys
```typescript
// ❌ BAD: Many individual keys
await env.KV.put('user:123:name', 'John')
await env.KV.put('user:123:email', 'john@example.com')
// ✅ GOOD: Single coalesced object
await env.USERS.put(
'user:123:profile',
JSON.stringify({
name: 'John',
email: 'john@example.com',
role: 'admin',
}),
)
// Benefits: Hot key cache, single read, reduced operations
// Trade-off: Harder to update individual fields
```
## Prefix-Based Namespacing
```typescript
// Logical partitioning within single namespace
const PREFIXES = {
users: 'user:',
sessions: 'session:',
cache: 'cache:',
features: 'feature:',
} as const
// Write with prefix
async function setUser(env: Env, id: string, data: any) {
await env.KV.put(`${PREFIXES.users}${id}`, JSON.stringify(data))
}
// Read with prefix
async function getUser(env: Env, id: string) {
return await env.KV.get(`${PREFIXES.users}${id}`, 'json')
}
// List by prefix
async function listUserIds(env: Env): Promise<string[]> {
const result = await env.KV.list({ prefix: PREFIXES.users })
return result.keys.map((k) => k.name.replace(PREFIXES.users, ''))
}
// Example hierarchy
;('user:123:profile')
;('user:123:settings')
;('cache:api:users')
;('session:abc-def')
;('feature:flags:beta')
```
## Metadata Versioning
```typescript
interface VersionedData {
version: number
data: any
}
async function migrateIfNeeded(env: Env, key: string) {
const result = await env.DATA.getWithMetadata(key, 'json')
if (!result.value) return null
const currentVersion = result.metadata?.version || 1
const targetVersion = 2
if (currentVersion < targetVersion) {
// Migrate data format
const migrated = migrate(result.value, currentVersion, targetVersion)
// Store with new version
await env.DATA.put(key, JSON.stringify(migrated), {
metadata: { version: targetVersion, migratedAt: Date.now() },
})
return migrated
}
return result.value
}
function migrate(data: any, from: number, to: number): any {
if (from === 1 && to === 2) {
// V1 → V2: Rename field
return { ...data, userName: data.name }
}
return data
}
```
## Error Boundary Pattern
```typescript
// Resilient get with fallback
async function resilientGet<T>(env: Env, key: string, fallback: T): Promise<T> {
try {
const value = await env.KV.get<T>(key, 'json')
return value ?? fallback
} catch (err) {
console.error(`KV error for ${key}:`, err)
return fallback
}
}
// Usage
const config = await resilientGet(env, 'config:app', {
theme: 'light',
maxItems: 10,
})
```
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.