Self-host Litemetrics with ClickHouse

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 -d

Services 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.

VariableDefaultNotes
DB_ADAPTERclickhouseSet to clickhouse explicitly in production.
CLICKHOUSE_URLhttp://localhost:8123Use the internal Docker hostname (http://clickhouse:8123) inside Compose.
ADMIN_SECRETadminRequired for /api/sites CRUD. Rotate before exposing publicly.
GEOIPtrueToggles MaxMind GeoLite2 country and city enrichment.
TRUST_PROXYtrueRequired when running behind a reverse proxy or load balancer.
PORT3002Port 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 a deleted_at column.
  • 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.