Skip to content

Environment Variables

Full reference of every supported environment variable, grouped by category.


Browser-exposed variables are build-time inlined. The prefix depends on which app you run:

AppClient prefixExample
apps/dashboard (TanStack Start, current)VITE_*VITE_AUTH_PROVIDER
Legacy Next.js (v0.2 and earlier)NEXT_PUBLIC_*NEXT_PUBLIC_AUTH_PROVIDER

The tables below use VITE_*. If you are migrating from v0.2, substitute NEXT_PUBLIC_ wherever you see VITE_. Server-side variables (CLICKHOUSE_*, CHM_*, LLM_*, CLERK_SECRET_KEY, etc.) are the same.

Authoritative example: apps/dashboard/.env.example.


There are two categories of environment variables:

CategoryWhen resolvedHow to setExample
Build-timeWhen bun run build runsCI environment / shell before the buildVITE_FEATURE_CONVERSATION_DB, VITE_AUTH_PROVIDER, VITE_CLERK_PUBLISHABLE_KEY
RuntimeWhen the server process starts per requestwrangler.toml [vars], wrangler secret put, Docker -e, k8s ConfigMap/SecretCLICKHOUSE_HOST, CONVERSATION_STORE_BACKEND

VITE_* vars are always build-time. They are inlined into the browser bundle and cannot be changed without a rebuild. Setting a VITE_* var in wrangler.toml [vars] or as a Docker -e flag has no effect on the running app — the bundle already has the value from when it was built.

All other vars (unless noted) are runtime — read from process.env when the Worker or Node process handles a request.


Required. Set at least CLICKHOUSE_HOST.

VariableDefaultDescription
CLICKHOUSE_HOST— (required)Comma-separated ClickHouse host URLs, e.g. http://ch-1:8123,http://ch-2:8123.
CLICKHOUSE_USERdefaultComma-separated usernames, one per host.
CLICKHOUSE_PASSWORD""Comma-separated passwords, one per host.
CLICKHOUSE_NAMEComma-separated display labels shown in the host selector.

CLICKHOUSE_HOST defines the host count. CLICKHOUSE_USER and CLICKHOUSE_PASSWORD may be either a single value (applied to all hosts) or one value per host position. CLICKHOUSE_NAME is optional. Position N maps to host index N.

See Multiple Hosts and Custom Name.


VariableDefaultDescription
CLICKHOUSE_MAX_EXECUTION_TIME60Query timeout in seconds.
CLICKHOUSE_TZserver defaultTime zone for date/time display.
CLICKHOUSE_DATABASEsystemDatabase used for app-owned tables (self-tracking events, dashboards).
EVENTS_TABLE_NAMEsystem.monitoring_eventsFull table name override for self-tracking events.
VariableDefaultDescription
CLICKHOUSE_POOL_SIZE10Max concurrent ClickHouse clients per host.
CLICKHOUSE_POOL_TIMEOUT300000Idle client timeout in milliseconds (5 min).
CLICKHOUSE_POOL_CLEANUP_INTERVAL60000Stale-client cleanup interval in milliseconds (1 min).

The cron sweep (GET /api/cron/health-sweep, Cloudflare Cron Trigger every 5 minutes) runs health checks over all hosts and can post webhook alerts without a browser tab open. See Environment Variables — Health Alerting in context.

VariableDefaultDescription
CRON_SECRETShared secret guarding /api/cron/health-sweep. Send as Authorization: Bearer <secret>. When unset, the endpoint is open.
HEALTH_ALERT_ENABLEDfalseSet true to POST webhook alerts. Checks run regardless; alerts only fire when true.
HEALTH_ALERT_WEBHOOK_URLSlack- or Discord-compatible webhook URL. Required for alerts to be dispatched.
HEALTH_ALERT_MIN_SEVERITYwarningMinimum severity to alert: warning (warning + critical) or critical (critical only).
Terminal window
## Alert Slack on warning-or-worse
CRON_SECRET=a-long-random-string
HEALTH_ALERT_ENABLED=true
HEALTH_ALERT_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
HEALTH_ALERT_MIN_SEVERITY=warning

All features are public and enabled by default. Override only what needs different behavior.

VariableDefaultDescription
CHM_CONFIG_FILEPath to TOML or YAML config file for feature overrides.
CHM_DISABLED_FEATURESComma-separated feature ids to disable entirely.
CHM_AUTH_REQUIRED_FEATURESComma-separated feature ids that require authentication.
CHM_FEATURE_{ID}_ACCESSpublicPer-feature access: public, guest (alias for public), or authenticated.
CHM_FEATURE_{ID}_ENABLEDtruePer-feature enabled flag: true or false.

Replace {ID} with an uppercase feature id: OVERVIEW, AGENT, INSIGHTS, HEALTH, QUERIES, TABLES, METRICS, DASHBOARD, SECURITY, LOGS, SETTINGS, CLUSTER, OPERATIONS, ACTIONS, MCP, DOCS, ABOUT, PEERDB.

Terminal window
CHM_FEATURE_AGENT_ACCESS=authenticated
CHM_FEATURE_METRICS_ENABLED=false
CHM_DISABLED_FEATURES=settings,insights

See Feature Permissions for config-file examples and precedence details.


The active server-side auth provider is set by CHM_AUTH_PROVIDER. See Authentication for the full model.

VariableDefaultDescription
CHM_AUTH_PROVIDERnoneServer auth provider: none, clerk, proxy, or trusted.
VITE_AUTH_PROVIDERnoneClient-side mirror of CHM_AUTH_PROVIDER. Set to the same value. Build-time.
CHM_API_KEY_SECRETShared secret for chm_ API keys. When set, API-key auth is always on alongside the active provider. Issue keys at /api/v1/auth/api-key.
VariableDefaultDescription
VITE_CLERK_PUBLISHABLE_KEYClerk publishable key (pk_...). Build-time — must be set before bun run build.
CLERK_SECRET_KEYClerk secret key (sk_...). Runtime only. Never expose to the browser.
CHM_CLERK_PUBLIC_READfalseWhen true, anonymous visitors can view read-only monitoring content; writes (AI agent, control actions, arbitrary SQL) still require sign-in. Runtime only. See Clerk → Public read-only mode.

Trust a reverse proxy that already authenticated the user. Either mechanism below can authenticate a request.

Cloudflare Access JWT:

VariableDefaultDescription
CHM_CF_ACCESS_TEAM_DOMAINCloudflare Access team URL (https://<team>.cloudflareaccess.com). Enables Cf-Access-Jwt-Assertion JWT verification.
CHM_CF_ACCESS_AUDAccess application AUD tag the JWT must carry.

Trusted header (bare subject):

VariableDefaultDescription
CHM_PROXY_AUTH_SECRETShared secret. When set, the identity header is honored only if this secret is also present (constant-time compare). Without it, the trusted-header mechanism is disabled.
CHM_PROXY_SHARED_SECRET_HEADERX-Chm-Proxy-SecretHeader the proxy sends containing the shared secret.
CHM_PROXY_AUTH_HEADERX-Forwarded-UserHeader the proxy sends containing the authenticated user identity.

When CHM_PROXY_AUTH_SECRET is set, the identity header (X-Forwarded-User by default) is honored only when the request also carries a matching shared-secret header (constant-time compared). Without CHM_PROXY_AUTH_SECRET, the entire trusted-header mechanism is disabled and identity headers are ignored.

Trusted reverse proxy (CHM_AUTH_PROVIDER=trusted)

Section titled “Trusted reverse proxy (CHM_AUTH_PROVIDER=trusted)”

Use when an upstream proxy (oauth2-proxy, Authelia, Traefik ForwardAuth, nginx auth-url) forwards the user’s full identity as HTTP headers. Extracts a complete principal — name, email, avatar, groups, custom claims.

Trust gate — configure exactly one:

VariableDefaultDescription
CHM_TRUSTED_AUTH_SECRETShared secret (runtime secret). The proxy must send it in CHM_TRUSTED_SHARED_SECRET_HEADER. Constant-time compared. Recommended.
CHM_TRUSTED_ALLOW_INSECUREfalseWhen true, trusts headers with no secret check. Only safe when the service is unreachable except via the proxy (e.g. k8s ClusterIP).
CHM_TRUSTED_SHARED_SECRET_HEADERX-Chm-Proxy-SecretHeader name carrying the shared secret.

Identity headers — all optional; defaults match common proxy conventions:

VariableDefaultPopulates
CHM_TRUSTED_USER_HEADERX-Forwarded-UserSubject / user id. Falls back to the email header.
CHM_TRUSTED_EMAIL_HEADERX-Forwarded-EmailEmail address.
CHM_TRUSTED_NAME_HEADERX-Forwarded-Preferred-UsernameDisplay name.
CHM_TRUSTED_AVATAR_HEADERX-Forwarded-AvatarAvatar URL.
CHM_TRUSTED_GROUPS_HEADERX-Forwarded-GroupsComma- or space-separated groups.
CHM_TRUSTED_ROLE_HEADERX-Forwarded-RoleSingle role; merged into the groups list.
CHM_TRUSTED_CUSTOM_HEADERSExtra claims. Comma-separated field:Header-Name pairs, e.g. team:X-Forwarded-Team.

Access control:

VariableDefaultDescription
CHM_TRUSTED_ALLOWED_GROUPSComma-separated group names. When set, users whose forwarded groups do not intersect are denied 403. Case-insensitive.

See Trusted proxy for setup examples (oauth2-proxy + Dex + Traefik, nginx).


The agent uses an OpenAI-compatible API. Set LLM_API_KEY to enable it. Keep all LLM keys server-side — never prefix them with VITE_.

VariableDefaultDescription
LLM_API_KEYProvider API key (fallback when no provider-specific key is set).
LLM_API_BASEhttps://openrouter.ai/api/v1OpenAI-compatible API base URL.
LLM_MODELopenrouter:openrouter/freeModel identifier in provider:modelId form.
LLM_EXTRA_MODELSAdditional model picker entries. Format: `provider:modelId[

Provider-specific keys take priority over the generic LLM_API_KEY / LLM_API_BASE.

VariableDescription
OPENROUTER_API_KEYOpenRouter API key.
OPENROUTER_API_BASEOpenRouter base URL.
OPENROUTER_REFERERHTTP referer sent to OpenRouter (for rankings).
OPENROUTER_APP_NAMEApp name sent to OpenRouter (for rankings).
OPENROUTER_MODELS_APIOpenRouter models list endpoint (default https://openrouter.ai/api/v1/models).
NVIDIA_API_KEYNVIDIA NIM API key.
NVIDIA_API_BASENVIDIA NIM base URL.
ANYROUTER_API_KEYAnyRouter API key.
ANYROUTER_API_BASEAnyRouter base URL.
VariableDefaultDescription
AGENT_API_TOKENShared Bearer token for the agent API (POST /api/v1/agent). Accepted when CHM_FEATURE_AGENT_ACCESS=authenticated.
AGENT_ENABLE_CONTROL_TOOLSfalseEnable kill-query, optimize, and other write actions. Keep false unless users are trusted.

See AI Agent — Configuration for full details.


Agent conversations default to browser localStorage. Enable server-side persistence with two steps:

  1. Set VITE_FEATURE_CONVERSATION_DB=true at build time (this is a VITE_* variable — must be set before bun run build). Also requires Clerk auth (VITE_AUTH_PROVIDER=clerk).
  2. Configure a backend at runtime via CONVERSATION_STORE_BACKEND.
VariableDefaultDescription
VITE_FEATURE_CONVERSATION_DBfalseBuild-time. Set true to enable server-side conversation persistence. Requires Clerk. Must be set before bun run build.
CONVERSATION_STORE_BACKEND(auto)Runtime. Backend: agentstate, d1, postgres, or memory. When unset, the server auto-selects the first available backend (AgentState if key present → D1 binding → Postgres via DATABASE_URL → Memory).

AgentState backend:

VariableDefaultDescription
AGENTSTATE_API_KEYAgentState API key. Required when CONVERSATION_STORE_BACKEND=agentstate.
AGENTSTATE_BASE_URLhttps://agentstate.app/apiAgentState API base URL.
AGENTSTATE_AI_ENRICHfalseSet true to enable AI enrichment of stored conversations.

Cloudflare D1 backend:

VariableDefaultDescription
CONVERSATIONS_D1_DATABASE_IDCloudflare D1 database UUID for the CONVERSATIONS_D1 binding.
AGENT_CONVERSATIONS_D1_DATABASE_IDAlias for CONVERSATIONS_D1_DATABASE_ID.

PostgreSQL backend:

VariableDescription
DATABASE_URLPostgreSQL connection string.
POSTGRES_URLAlternative PostgreSQL connection string.
POSTGRES_PRISMA_URLPrisma-specific PostgreSQL connection string.

See Conversation History — Backends for setup and fallback behavior.


The AI Insights panel on /overview persists its findings through a pluggable store. It is additive opt-in and defaults to ClickHouse; the D1, Postgres, and AgentState backends reuse the conversation-store env above.

VariableDefaultDescription
INSIGHTS_STORE_BACKENDautoBackend: auto, clickhouse, d1, postgres, agentstate, or memory. auto and clickhouse both use the ClickHouse monitoring_findings table. auto never silently follows other env; a selected backend missing its prerequisite falls back to ClickHouse.
INSIGHTS_D1Optional dedicated D1 binding for the d1 backend. Falls back to CONVERSATIONS_D1 when unset.

postgres reuses DATABASE_URL; agentstate reuses AGENTSTATE_API_KEY (+ optional AGENTSTATE_BASE_URL).

See AI Agent — AI Insights persistence for setup and fallback behavior. GET /api/v1/insights/backend reports the active backend.


Optional. Set PEERDB_API_URL to enable the PeerDB section (Mirrors and Peers) in the sidebar.

VariableDefaultDescription
PEERDB_API_URLPeerDB REST API base URL. For the PeerDB UI (NextAuth), include /api suffix — e.g. https://peerdb.example.com/api. For the raw flow-api, use the bare origin — e.g. http://localhost:8113.
PEERDB_PASSWORDPeerDB password. Sent as HTTP Basic with an empty username. Server-side only.
PEERDB_CACHE_TTL_MS10000Server-side response cache TTL in milliseconds. Set 0 to disable.
PEERDB_CACHE_MAX_ENTRIES500Max cached PeerDB responses before oldest are evicted.
PEERDB_FETCH_TIMEOUT_MS10000Upstream PeerDB request timeout in milliseconds.

chmonitor proxies only a read-only allowlist of PeerDB endpoints; mutating operations (create/drop/pause, alert config) are rejected with 403.

Terminal window
## PeerDB UI behind NextAuth
PEERDB_API_URL=https://peerdb.example.com/api
PEERDB_PASSWORD=your-peerdb-ui-password
## Raw flow-api (no auth)
PEERDB_API_URL=http://localhost:8113

All client-side, all build-time. VITE_* for TanStack app; NEXT_PUBLIC_* for legacy Next.js.

VariableDefaultDescription
VITE_TITLE_SHORTClickHouseBrowser tab title (short form).
VITE_LOGOCustom logo URL shown in the header.
VITE_AUTOCOMPLETE_LIMITMax results in autocomplete dropdowns.
VITE_MEASUREMENT_IDGoogle Analytics measurement ID (G-...).
VITE_SELINE_ENABLEDfalseEnable Seline analytics.
VITE_VERCEL_ANALYTICSfalseEnable Vercel Analytics.
VITE_POSTHOG_KEYPostHog project API key.
VITE_POSTHOG_HOSThttps://us.i.posthog.comPostHog ingest host URL.

VariableDefaultDescription
NODE_ENVdevelopmentRuntime environment: development, production, test.
ENABLE_CLOUDFLAREfalseEnable Cloudflare-specific build configuration.
CLOUDFLARE_WORKERSSet to 1 when running on Cloudflare Workers.
CF_PAGESSet automatically by Cloudflare Pages at runtime.
MINIFLARESet to 1 when running locally with Miniflare.
DOCS_CONTENT_ROOTOverride docs content source directory.

Injected at build time for the About page.

VariableDescription
VITE_GIT_SHACurrent commit SHA.
VITE_GIT_REFCurrent git branch or tag.
VITE_BUILD_TIMESTAMPISO build timestamp.
VITE_CISet to true in CI environments.

VariableNotes
NEXT_PUBLIC_AUTH_PROVIDERRenamed to VITE_AUTH_PROVIDER in v0.3. Old name still works as a fallback.
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYRenamed to VITE_CLERK_PUBLISHABLE_KEY in v0.3.
NEXT_PUBLIC_FEATURE_CONVERSATION_DBDeprecated alias for VITE_FEATURE_CONVERSATION_DB=true.
NEXT_PUBLIC_AUTOCOMPLETE_LIMITRenamed to VITE_AUTOCOMPLETE_LIMIT in v0.3.
NEXT_PUBLIC_RUNNING_QUERIES_REFRESH_MSRenamed to VITE_RUNNING_QUERIES_REFRESH_MS in v0.3.
CLICKHOUSE_EXCLUDE_USER_DEFAULTComma-separated usernames excluded from history-queries by default.

See Migrate to v0.3 for the full rename list.