Self-host with ClickHouse
ClickHouse is the recommended Litemetrics adapter when you expect more than a few million events per month. It handles the columnar aggregations the analytics dashboard relies on (top pages, top referrers, retention cohorts) at sub-second latency, even on a single modest VM.
1. Start the stack
The repo ships a docker-compose.yml that brings up ClickHouse and the collector together, with healthchecks and named volumes.
git clone https://github.com/metehankurucu/litemetrics.git
cd litemetrics
docker compose up -dServices exposed:
http://localhost:3002: collector + query API.http://localhost:8123: ClickHouse HTTP interface.localhost:9000: ClickHouse native protocol.
2. Configuration
The collector reads its configuration from environment variables. The defaults are sensible for local development; override these in production.
| Variable | Default | Notes |
|---|---|---|
DB_ADAPTER | clickhouse | Set to clickhouse explicitly in production. |
CLICKHOUSE_URL | http://localhost:8123 | Use the internal Docker hostname (http://clickhouse:8123) inside Compose. |
ADMIN_SECRET | admin | Required for /api/sites CRUD. Rotate before exposing publicly. |
GEOIP | true | Toggles MaxMind GeoLite2 country and city enrichment. |
TRUST_PROXY | true | Required when running behind a reverse proxy or load balancer. |
PORT | 3002 | Port the Express server binds to. |
3. Schema
Tables are created automatically on first boot. You do not run migrations.
events(MergeTree): one row per event, partitioned by month, ordered by(site_id, toDate(timestamp), timestamp).sites(ReplacingMergeTree): one row per site, soft-deletes via adeleted_atcolumn.identity: maps anonymous visitor ids to identified user ids for cross-session merging.
4. GeoIP
With GEOIP=true the collector resolves country and city per event using a bundled MaxMind GeoLite2 database. The dataset is small (~70MB) and shipped with the Docker image. Disable it with GEOIP=false if you do not need geographic breakdowns or prefer to enrich elsewhere.
5. Scaling notes
A single ClickHouse node on a 2 vCPU / 4GB instance comfortably ingests over 100M events per month with sub-second dashboard queries. When you outgrow that:
- Vertical scale ClickHouse first; analytics workloads benefit disproportionately from more RAM and fast NVMe.
- Move the collector to a separate container (or three behind a load balancer); event ingestion is stateless.
- For multi-region deployments, run a collector per region and a single ClickHouse cluster with replication. The collector is read-light, write-only.
6. Backups
Use ClickHouse's built-in BACKUP command or rely on volume snapshots from your provider (AWS EBS, GCP PD, etc.). The events table compresses extremely well (typically 10x to 30x) so backups stay small.
Switching to Postgres
If you would rather run Litemetrics on the database you already operate, the Postgres adapter has full feature parity. See Postgres setup.