Skip to content

Run the collector

The collector is a single Fastify process that ingests events and serves the query API. You run it straight from npm — there is nothing to clone. The OSS default store is DuckDB: one .duckdb file holds both events and metadata, so the collector self-hosts in one process with no external database service.

The scaffolder generates a ready-to-run, Docker-free self-host folder — a strong secret, a local config, a tiny runner, and a client snippet for your engine:

Terminal window
npm create uptimizr@latest

Follow the prompts, then start it:

Terminal window
cd <your-folder>
npm start # runs `uptimizr serve` under the hood

The prompts also offer two optional extras so you can go from a bare collector to the full suite and test everything in one go:

  • Dashboard — adds @uptimizr/dashboard and an npm run dashboard script (analytics UI on http://localhost:3000).
  • Demo — writes a self-contained Babylon scene + tiny static server and an npm run demo script (http://localhost:5173) that generates events end-to-end.

Skip the prompts with flags — --full (collector + dashboard + demo), --dashboard, --demo, or --minimal (collector only):

Terminal window
npm create uptimizr@latest my-analytics -- --full

With the full suite, run the three processes together and watch events flow from the demo through the collector into the dashboard:

Terminal window
npm start # collector — ingestion + query API
npm run demo # demo scene — paste the projectId, then interact
npm run dashboard # dashboard — point it at the collector with your API key
  • Inspect the store directly with the DuckDB CLI (DUCKDB_PATH defaults to ./data/uptimizr.duckdb):

    Terminal window
    duckdb ./data/uptimizr.duckdb "SELECT event_type, count(*) FROM events GROUP BY 1"
  • Back up = copy the .duckdb file. Reset = delete it and re-run uptimizr init.

The collector can optionally serve the dashboard static assets at /, so a single process exposes the ingestion API, query API, UI, and the DuckDB file. See Serve the dashboard for the all-in-one and standalone options.

When you outgrow DuckDB’s single-writer model — concurrent collector instances, high-volume ingestion, or large historical ranges — switch the store to ClickHouse without changing any application code or queries:

Terminal window
export COLLECTOR_STORE=clickhouse
export CLICKHOUSE_URL=http://localhost:8123
export CLICKHOUSE_DATABASE=uptimizr
export CLICKHOUSE_USER=default
export CLICKHOUSE_PASSWORD=
npx -p @uptimizr/collector-server uptimizr serve

This is a single-tenant ClickHouse store: events and metadata (projects, API keys, scene representations) live in one ClickHouse database, so there is no separate metadata service to run. The collector creates the database and tables on first boot. Every aggregation is authored once against the dialect-agnostic query layer, so the full analytics surface — heatmaps, sessions, performance percentiles, mesh dwell, daily rollups — returns identical results to DuckDB (verified by a cross-engine parity suite).

Choose ClickHouse when you need:

  • Concurrent writers / horizontal scale — multiple collector instances against one store.
  • High-volume ingestion and large time-range queries.
  • A shared analytics database your team already operates.

Keep DuckDB (the default) for single-instance self-hosting with no service to run. Spin up a local ClickHouse with the monorepo’s infra/docker (pnpm stack:up); see Contributing.

A managed ClickHouse (ClickHouse Cloud, Aiven, or your own TLS-terminated server) works the same way — point CLICKHOUSE_URL at the HTTPS endpoint and pass the credentials. The client infers TLS from the https:// scheme, so no extra configuration is needed for publicly-trusted certificates:

Terminal window
export COLLECTOR_STORE=clickhouse
export CLICKHOUSE_URL=https://your-instance.clickhouse.cloud:8443
export CLICKHOUSE_USER=default
export CLICKHOUSE_PASSWORD="$YOUR_PASSWORD"
export CLICKHOUSE_DATABASE=uptimizr

The collector creates the CLICKHOUSE_DATABASE on first boot, so the connecting user needs the CREATE DATABASE privilege (the default ClickHouse Cloud user has it) — or pre-create the database and grant the user access to it. Custom CA bundles and mutual-TLS client certificates are not currently exposed through env vars.

Key environment variables (the CLI writes a starter .env; see the repo’s .env.example for the full list):

VariablePurpose
COLLECTOR_STOREduckdb (default), clickhouse (scale tier), or memory (dev/E2E).
DUCKDB_PATHPath to the DuckDB file (default ./data/uptimizr.duckdb).
CLICKHOUSE_URLClickHouse HTTP endpoint when COLLECTOR_STORE=clickhouse (default http://localhost:8123).
CLICKHOUSE_DATABASEClickHouse database name (default uptimizr; created on first boot).
CLICKHOUSE_USER / CLICKHOUSE_PASSWORDClickHouse credentials (default default / empty).
COLLECTOR_PORTPort the collector listens on (default 4318).
VISITOR_HASH_SECRETSecret for the daily-rotating, server-side visitor hash.
COLLECTOR_CORS_ORIGINSAllowed browser origins for ingestion/query (comma-separated).
ENABLE_RAW_SESSION_RETENTIONOpt-in raw per-session event retention, required for replay.

See Privacy & configuration for the privacy-relevant settings.