Operate
Self-Hosted State Backends
Persist dashboards, per-user connections, and conversations in your own ClickHouse or Postgres instead of Cloudflare D1 — env vars and resolution order for Docker and Kubernetes deployments.
Self-hosted (Docker / Kubernetes) deployments can persist UI-monitoring state —
saved dashboards, per-user connections, and agent conversations —
in a database you operate, instead of Cloudflare D1 (which only exists on the
hosted Workers deployment). Without a backend, dashboards fall back to browser
localStorage and conversations to memory.
ClickHouse
Reuse or dedicate an instance via CHM_STATE_CLICKHOUSE_*. Tables are created lazily (CREATE TABLE IF NOT EXISTS, ReplacingMergeTree) — no migrations.
Postgres
DATABASE_URL / POSTGRES_URL. Tables are also created lazily on first use. One string serves dashboards, connections, and conversations.
Resolution order
Each store resolves its backend at runtime, fail-open and OSS-first:
Per-user rows need auth
Server-side dashboard and connection storage also requires the per-user feature
gates (CHM_FEATURE_CONVERSATION_DB / CHM_FEATURE_USER_CONNECTIONS_DB) and an
auth provider — rows are keyed by user id. See
Environment variables.
ClickHouse state backend
CHM_STATE_CLICKHOUSE_URL=http://clickhouse:8123
# Optional
CHM_STATE_CLICKHOUSE_USER=default # default: default
CHM_STATE_CLICKHOUSE_PASSWORD= # default: empty
CHM_STATE_CLICKHOUSE_DATABASE=chmonitor # default: chmonitor
CHM_STATE_CLICKHOUSE_TABLE_PREFIX=chm_state_ # default: chm_state_The user needs CREATE DATABASE / CREATE TABLE, INSERT, SELECT, and
lightweight DELETE permissions on the state database. Tables
(chm_state_dashboards, chm_state_user_connections) use
ReplacingMergeTree(updated_at) with FINAL reads, so updates are plain
inserts and no mutations are required for normal operation.
Monitoring users are often read-only
This can be the same ClickHouse you monitor, but a monitoring user is often
read-only — point CHM_STATE_CLICKHOUSE_USER at a writable account (or a
separate small instance) if so.
Postgres state backend
DATABASE_URL=postgres://user:pass@host:5432/chmonitor
# or POSTGRES_URL / POSTGRES_PRISMA_URLOne connection string serves all three stores (user_connections,
dashboards, and the conversation tables).