Storage & Data
KV Notes
Simple note CRUD with Workers KV at the edge - minimal key-value storage reference for Cloudflare Workers
Store and retrieve small text notes using a dedicated Workers KV namespace.
API Reference
POST /notes
Create or update a note.
Prop
Type
Example Request
curl -X POST "https://your-worker.workers.dev/notes" \
-H "Content-Type: application/json" \
-d '{"id":"todo-1","content":"Ship the experiment"}'Success Response
{
"id": "todo-1",
"content": "Ship the experiment",
"updatedAt": "2025-06-20T12:00:00.000Z"
}GET /notes
Fetch a note by id.
id string (required)
Example Request
curl "https://your-worker.workers.dev/notes?id=todo-1"DELETE /notes
Delete a note by id.
id string (required)
Error Codes
400- Invalid id or content (INVALID_ID,INVALID_CONTENT,INVALID_BODY)404- Note not found (NOT_FOUND)
Use Cases
- Learn KV read/write/delete patterns without D1
- Store small configuration blobs at the edge
- Prototype simple key-value APIs before adding auth
Limitations
- Note IDs are capped at 64 characters; content at 4,000 characters
- No authentication; any client can read, write, or delete by ID
- KV is eventually consistent across edge locations
Use in your project
Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/kv-notes.
DependenciesNoneBindingsKVPlatformWorkers runtime
import { MAX_CONTENT_LENGTH, MAX_NOTE_ID_LENGTH, NOTE_ID_PATTERN, NOTE_KEY_PREFIX,} from "../constants/defaults";export function validateNoteId(input: string | undefined): string | null { if (!input || typeof input !== "string") return null; const trimmed = input.trim(); if (!trimmed || trimmed.length > MAX_NOTE_ID_LENGTH) return null; if (!NOTE_ID_PATTERN.test(trimmed)) return null; return trimmed;}export function validateContent(input: string | undefined): string | null { if (!input || typeof input !== "string") return null; const trimmed = input.trim(); if (!trimmed || trimmed.length > MAX_CONTENT_LENGTH) return null; return trimmed;}export function noteKey(id: string): string { return `${NOTE_KEY_PREFIX}${id}`;}export async function getNote(kv: KVNamespace, id: string): Promise<string | null> { return kv.get(noteKey(id));}export async function saveNote(kv: KVNamespace, id: string, content: string): Promise<void> { const record = { id, content, updatedAt: new Date().toISOString(), }; await kv.put(noteKey(id), JSON.stringify(record));}export async function deleteNote(kv: KVNamespace, id: string): Promise<void> { await kv.delete(noteKey(id));}export function parseNoteRecord( raw: string, id: string): { id: string; content: string; updatedAt: string } | null { try { const parsed = JSON.parse(raw) as { id?: string; content?: string; updatedAt?: string }; if (!parsed.content || typeof parsed.content !== "string") return null; return { id: parsed.id ?? id, content: parsed.content, updatedAt: parsed.updatedAt ?? new Date(0).toISOString(), }; } catch { return null; }}Deployment
Configure KV
Create a KV namespace and bind it as NOTES in wrangler.json.
Local Development
cd apps/experiments/kv-notes
npm install
npm run devCloudflare Features Used
- Workers - Edge compute runtime
- Workers KV - Global key-value storage