This site is not affiliated with or endorsed by Cloudflare, Inc. It showcases deployable experiments across most Cloudflare products.

Blog19 min read

Build a link shortener with D1 and KV on Cloudflare

Deep D1 + KV link shortener guide - schema, hot cache redirects, uniqueness, abuse controls, analytics, and the Link Shortener experiment.

Macro photo of a circuit board with electronic components
Photo by Alexandre Debiève on Unsplash

URL shorteners look trivial until you care about correctness under load: unique codes, fast redirects, analytics, and abuse controls. A proven Cloudflare pattern is:

  • D1 as the source of truth for mappings
  • KV as a hot cache for redirects
  • A Worker that creates links and resolves them at the edge

The Link Shortener experiment implements that split so you can deploy a working shortener instead of reinventing the schema.

Cloudflare products in this pattern

ProductRoleDocs
D1Durable mappings, uniqueness, listingsSQL database
D1 Workers APIenv.DB.prepareWorker binding
Workers KVHot redirect cacheKV
KV Workers APIget / put with TTLAPI
WorkersCreate + redirect routesRuntime
Durable Objects (optional)Strongly consistent click countersState
TurnstileBot protection on public createsTurnstile
Analytics Engine (optional)Click analyticsAnalytics
Queues (optional)Async analytics fan-outQueues

Why D1 + KV together

ConcernStoreDocs
Durable mapping, uniqueness, listingsD1D1
Ultra-hot redirectsKV cache of D1 rowsKV
Click counters with strong consistencyOptional Durable ObjectDurable Objects

KV alone is awkward for “list my links” and uniqueness constraints. D1 alone is fine for low QPS, but KV shines when the same slug is hit constantly worldwide. Official primers: D1 get started, KV get started.

Request flows

Create

POST { url } → validate → insert D1 → optionally warm KV → return code

Use transactions / unique constraints in D1 so two creates cannot race the same custom code (D1 API).

Resolve

GET /:code → KV get → on miss, D1 select → fill KV → 302 Location

Always validate destination URLs (http/https only) to avoid open redirects into dangerous schemes - same discipline as other catalog URL APIs.

Schema sketch

Minimum viable tables:

  • links(code PRIMARY KEY, url TEXT NOT NULL, created_at, expires_at, owner_id)
  • Optional clicks(code, ts, colo, asn) or push clicks to Analytics Engine / Queues

Explore SQL interactively with D1 SQL Playground while you iterate. For simpler key/value notes without SQL, see KV Notes.

Abuse and product extras

Consistency notes

KV is eventually consistent (KV consistency). After create:

  • Warm KV immediately from the create path
  • Accept that a redirect MISS may hit D1 briefly after write
  • On update/delete, delete the KV key explicitly

D1 read replicas and latency characteristics are covered in D1 read replication - design list UIs accordingly.

  1. Provision D1 + KV (bindings)
  2. Deploy Link Shortener
  3. Create a link, resolve it twice, confirm cache behavior
  4. Add Turnstile / auth before exposing create publicly
  5. Add analytics when product metrics matter

You get a real two-storage edge pattern - not a toy in-memory map - that matches how many production Cloudflare apps actually split durability (D1) and speed (KV).

Production checklist

  1. Unique constraint on codes in D1.
  2. Warm KV on create; delete KV keys on update/delete.
  3. Validate destinations (http/https only).
  4. Protect create with auth + Turnstile.
  5. Align KV TTLs with link expiration columns.
  6. Decide analytics path (D1 rows vs Analytics Engine vs Queues).

FAQ

KV said miss right after create - is D1 wrong?

KV is eventually consistent. Warm on write and tolerate a brief D1 fallback.

Related experiments

These deployable references implement the patterns in this article. Open the docs for API details, then Deploy or clone the source.

  • Link Shortener - URL shortener with Cloudflare D1 + KV - create short links, redirect with edge caching, and track clicks
  • D1 SQL Playground - Read-only SQL playground over a seeded Cloudflare D1 database with safe SELECT validation - learn D1 at the edge
  • KV Notes - Simple note CRUD with Workers KV at the edge - minimal key-value storage reference for Cloudflare Workers
  • Durable Counter - Canonical Durable Objects counter - globally consistent increment/decrement with strong consistency at the edge
  • Rate Limiter Demo - Native Workers Rate Limiting binding with 429 responses and usage visualization - protect APIs at the edge without Redis
  • Turnstile Verify - Verify Cloudflare Turnstile tokens via the siteverify API - bot protection for forms and APIs on Workers

Cloudflare Experiments is an independent open-source catalog - not affiliated with Cloudflare, Inc.