# Kv Hyperdrive

> Use Cloudflare KV for eventually consistent global cache/config and Hyperdrive for existing Postgres/MySQL access from Workers. Use when deciding cache-aside patterns, TTLs, invalidation, external DB connectivity, and Node-compatible database drivers.

- Skill: `zllovesuki/kv-hyperdrive` (Agent Skill)
- Install (CLI): `npx skillmds@latest add zllovesuki/kv-hyperdrive`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zllovesuki/kv-hyperdrive/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: zllovesuki (https://skillmd.com/u/zllovesuki)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/zllovesuki/kv-hyperdrive

---

# KV and Hyperdrive

Use this skill for globally cached key/value data and for connecting Workers to existing relational databases.

## KV: when to use

Use KV for:

- Public configuration and feature flags.
- Cached API responses.
- Denormalized read models.
- Low-frequency writes with high read fan-out.
- Values that tolerate eventual consistency.

Do not use KV for:

- Locks.
- Counters that must be correct.
- Inventory, balances, bookings, or permissions requiring immediate consistency.
- Coordination between clients.

## KV cache-aside pattern

```ts
export interface Env {
  CACHE: KVNamespace;
  DB: D1Database;
}

export async function getPublicProject(env: Env, projectId: string) {
  const key = `project:${projectId}:public:v1`;
  const cached = await env.CACHE.get<ProjectSummary>(key, "json");
  if (cached) return cached;

  const project = await env.DB.prepare(
    "SELECT id, name, description FROM projects WHERE id = ? AND public = 1"
  ).bind(projectId).first<ProjectSummary>();

  if (project) {
    await env.CACHE.put(key, JSON.stringify(project), { expirationTtl: 300 });
  }

  return project;
}
```

## KV invalidation strategy

- Use short TTLs for data that changes frequently.
- Include schema/version suffixes in keys, such as `:v1`.
- On writes, update source of truth first, then delete or replace cache.
- Design for stale reads; never rely on immediate global invalidation.

## Hyperdrive: when to use

Use Hyperdrive when:

- The source of truth is an existing Postgres/MySQL-compatible database.
- Migrating fully to D1 is not currently feasible.
- You need Workers to connect to a regional database with better connection behavior.

## Hyperdrive config sketch

```jsonc
{
  "compatibility_flags": ["nodejs_compat_v2"],
  "hyperdrive": [
    {
      "binding": "HYPERDRIVE",
      "id": "REPLACE_WITH_HYPERDRIVE_ID"
    }
  ]
}
```

## Hyperdrive code sketch

```ts
import postgres from "postgres";

export interface Env {
  HYPERDRIVE: Hyperdrive;
}

export async function listUsers(env: Env) {
  const sql = postgres(env.HYPERDRIVE.connectionString);
  try {
    return await sql`SELECT id, email FROM users ORDER BY created_at DESC LIMIT 50`;
  } finally {
    await sql.end({ timeout: 1 });
  }
}
```

Verify the recommended driver and connection pattern against current Cloudflare docs for the specific database.

## Anti-patterns

- Treating KV as a strongly consistent database.
- Infinite TTL for data that must be revoked quickly.
- Cache keys that omit tenant/user/security dimensions.
- Opening external DB connections without using Hyperdrive or a documented connection strategy.
- Migrating to D1 prematurely when the existing database remains the system of record.

