hq-sanity
Self-hosted Sanity Content Lake on Cloudflare Workers.
Your data. Your rules. ~$5/mo.
Every service is wired end-to-end. No stubs. No dead code.
Document store with FTS5, composite indexes, GROQ-to-SQL pushdown
Asset uploads, CAS-backed history snapshots, schema persistence
Real-time SSE listeners, scheduled publishing, per-tier rate limiting
Async webhook delivery, history writes, embedding jobs via CDC bus
SHA-256 keyed response cache with epoch-based invalidation via CDC
Semantic search embeddings, RAG chat with document context
Per-request metrics, cost-weighted billing, slow-query detection
Nightly schema refresh, ANALYZE, CAS orphan GC, retention compactor
Structured observability logs forwarded from every request
On-the-fly transforms via CfProperties — width, height, format, quality
Bot protection for public endpoints without requiring API tokens
Full Rust GROQ parser, planner, executor — 151 tests, zero clippy warnings
Single distribute() call fans out to listeners, queues, cache, embeddings
Sanity Studio (browser)
│
▼
┌─────────────────────────────────────────────────────┐
│ hq-sanity-router (CF Worker) │
│ │
│ ┌──────────┐ ┌───────────┐ ┌──────────────────┐ │
│ │ GROQ │ │ Cache API │ │ Auth + Turnstile │ │
│ │ Engine │ │ (SHA-256 │ │ + Rate Limit DO │ │
│ │ (Rust) │ │ keyed) │ │ (PermissionCell) │ │
│ └────┬─────┘ └─────┬─────┘ └──────────────────┘ │
│ │ │ │
│ ┌────▼──────────────▼───────┐ ┌────────────────┐ │
│ │ D1 (SQLite) │ │ R2 (Assets + │ │
│ │ docs, refs, webhooks, │ │ CAS History) │ │
│ │ embeddings, FTS5 │ │ │ │
│ └───────────────────────────┘ └────────────────┘ │
│ │
│ ┌──────────────── CDC Bus ──────────────────────┐ │
│ │ distribute() → Listener DO (SSE) │ │
│ │ → Events Queue → Consumer │ │
│ │ → Cache invalidation │ │
│ │ → Auto-embed (Workers AI) │ │
│ │ → Schema observe │ │
│ └──────────────────────────────────────────────-┘ │
└─────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────────┐ ┌───────────┐
│ Consumer │ │ Tail Worker │ │ Analytics │
│ (Queue) │ │ (Observ.) │ │ Engine │
└──────────┘ └──────────────┘ └───────────┘
Internal Worker timing (D1 query + GROQ eval). Network RTT not included.
Click to fire 10 queries from your browser. Measures total RTT and internal Worker time.
Run queries against the live production dataset.
Live side-by-side query from your browser. Same GROQ, two backends.
Sanity Cloud timing is full RTT (they don't expose internal ms). hq-sanity shows both.
Drag the sliders. See the difference.