ClickHouse is a great database and a poor API. WaveHouse is the API.
The open-source real-time API gateway for ClickHouse β schema-aware ingest, async batching, real-time SSE streaming, and tiered query caching in a single binary.
git clone https://github.com/Wave-RF/WaveHouse.git && cd WaveHouse
docker compose -f deployments/compose/standalone.yaml up -d # ClickHouse + WaveHouse (ships a dev policy)
# create a table (Bring Your Own Schema)
docker compose -f deployments/compose/standalone.yaml exec clickhouse \
clickhouse-client --query "CREATE TABLE IF NOT EXISTS events (kind String, user String, received_timestamp DateTime64(3,'UTC') DEFAULT now64(3,'UTC')) ENGINE=MergeTree ORDER BY kind"
# stream live events in one terminal, then ingest one in another and watch it arrive
curl -N "http://localhost:8080/v1/stream?table=events" & sleep 1
# in another terminal, ingest an event (no auth needed with the dev policy)
# (a 404 "unknown table" here just means schema discovery hasn't seen the new table yet β retry; worst case 60s)
curl -sX POST "http://localhost:8080/v1/ingest?table=events" \
-H 'content-type: application/json' -d '{"kind":"click","user":"u_42"}'
ClickHouse is a phenomenal OLAP database, but pointing a frontend straight at it has sharp edges: one-row inserts trigger Too many parts, there's no backpressure or edge validation, no real-time push, and no row/column security. You end up building custom APIs, a Kafka queue, a batch consumer, a cache tier, and an auth service. WaveHouse is that whole stack as one binary β the only external dependency is ClickHouse.
If you're building user-facing analytics, WaveHouse is like Supabase for ClickHouse β or an open-source Tinybird that pushes data to the frontend in real time over SSE, not just pull-based REST.
Ingest β async durable WAL (embedded NATS JetStream), 200 OK instantly, background batch-flush; schema-validated against system.columns; optional ID-based dedup (idempotent ingest); dead-letter queue for failed inserts.
Pick whichever fits β each ends with WaveHouse listening on http://localhost:8080.
A. Docker Compose (recommended first run)
git clone https://github.com/Wave-RF/WaveHouse.git && cd WaveHouse
docker compose -f deployments/compose/standalone.yaml up -d
The stack ships a permissive dev policy, so you can ingest without a token. Create a table in ClickHouse (Bring Your Own Schema), then ingest β see the getting-started walkthrough for the full ingest β query β stream tour.
go install github.com/Wave-RF/WaveHouse/cmd/wavehouse@latest
You'll still need ClickHouse reachable β point WaveHouse at it via WH_CH_ADDR (defaults to localhost:9000).
See Configuration.
π¦ Project status
WaveHouse is in alpha β built in the open, Apache-2.0-licensed, no vendor lock-in. See SUPPORT.md for where to ask what, the alpha-stage response cadence (best-effort, 1β2 business days), and what's in vs. out of scope right now.
Track what's shipped, in progress, and planned on the project board.
Alpha β expect change. WaveHouse is pre-1.0: APIs, configuration, wire formats, and on-disk state can change between releases without a migration path, and some capabilities are still hardening. Pin a version and don't rely on stability guarantees until a tagged GA release.
π» Local Development
You'll need Go 1.26+, GNU Make 4+, Docker (Compose v2), Node.js 22 LTS, and pnpm 11+. See development docs for the authoritative source of truth with the full list, version requirements, and gotchas.
make tools # one-time bootstrap
docker compose -f deployments/compose/dependencies.yaml up -d clickhouse
make dev # hot-reload on .go save
π€ Working with Claude Code
AI-assisted, human-reviewed. Much of WaveHouse β code and docs alike β is written with AI assistance (Claude Code). Every change, whether AI- or human-authored, goes through the same review gates, tests, and CI before it lands. We note it for transparency: treat the docs as the source of truth, and please open an issue if anything reads as off or out of date.
The repo ships minimal team-wide Claude Code configuration β safety guardrails, a couple of slash commands / subagents, an auto-format hook, and worktrunk project hooks for parallel agent workflows. Personal preferences (status line, model, allow lists) stay user-level. See Claude Code & AI agents for setup + reference. AGENTS.md at the repo root is the canonical source of truth for project conventions.
π€ Contributing
Issues, pull requests, and feedback welcome! See our CONTRIBUTING.md guidelines on how to structure your code and run the integration test suites.
π‘οΈ Security
Found a vulnerability? Don't open a public issue. Email security@wave-rf.com per SECURITY.md β we acknowledge within 48 hours and aim for an initial assessment in 5 business days.
Package auth handles authentication: it validates JWT Bearer tokens and records the caller's role, claims, and any token-validation error in the request context.
Package auth handles authentication: it validates JWT Bearer tokens and records the caller's role, claims, and any token-validation error in the request context.
Package stream holds the SSE fan-out primitives shared by the streaming API: the Subscriber connection handle (subscriber.go), the Bucket fan-out primitive (bucket.go), the Heartbeater keepalive wheel (heartbeat.go) that nudges idle GET /v1/stream connections, and the event Hub (hub.go).
Package stream holds the SSE fan-out primitives shared by the streaming API: the Subscriber connection handle (subscriber.go), the Bucket fan-out primitive (bucket.go), the Heartbeater keepalive wheel (heartbeat.go) that nudges idle GET /v1/stream connections, and the event Hub (hub.go).