Vercel
Quick start
Section titled “Quick start”Or deploy manually:
- Import the repo at vercel.com/new.
- Set environment variables in the Vercel dashboard (Project → Settings → Environment Variables).
- Deploy.
Build settings
Section titled “Build settings”| Setting | Value |
|---|---|
| Framework preset | Next.js |
| Build command | bun run build (or npm run build) |
| Output directory | .next |
| Install command | bun install |
| Node.js version | 22.x or later |
Configure
Section titled “Configure”Set environment variables in Vercel dashboard → Project → Settings → Environment Variables.
Client vs server vars on Vercel
Section titled “Client vs server vars on Vercel”On Vercel (Next.js), client-side vars use NEXT_PUBLIC_*. These are inlined at build time. Server-side vars are plain names. This differs from the TanStack app which uses VITE_*.
| TanStack (current app) | Next.js / Vercel | Purpose |
|---|---|---|
VITE_AUTH_PROVIDER | NEXT_PUBLIC_AUTH_PROVIDER | Auth provider (client) |
VITE_CLERK_PUBLISHABLE_KEY | NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | Clerk publishable key (client) |
VITE_TITLE_SHORT | NEXT_PUBLIC_TITLE_SHORT | Branding (client) |
ClickHouse connection
Section titled “ClickHouse connection”| Variable | Required | Default | Description |
|---|---|---|---|
CLICKHOUSE_HOST | Yes | — | ClickHouse URL(s), comma-separated |
CLICKHOUSE_USER | No | default | Username(s), same count as HOST |
CLICKHOUSE_PASSWORD | No | "" | Password(s), same count as HOST |
CLICKHOUSE_NAME | No | — | Friendly label(s) for host switcher |
Multiple hosts
Section titled “Multiple hosts”All four variables must have the same count:
CLICKHOUSE_HOST=https://ch1:8443,https://ch2:8443CLICKHOUSE_USER=monitoring,monitoringCLICKHOUSE_PASSWORD=pass1,pass2CLICKHOUSE_NAME=primary,replicaQuery / pool tuning
Section titled “Query / pool tuning”| Variable | Default | Description |
|---|---|---|
CLICKHOUSE_MAX_EXECUTION_TIME | 60 | Query timeout in seconds |
CLICKHOUSE_TZ | — | Timezone for queries |
CLICKHOUSE_DATABASE | system | Default database |
CLICKHOUSE_POOL_SIZE | 10 | Connection pool size |
CLICKHOUSE_POOL_TIMEOUT | 300000 | Pool acquire timeout (ms) |
CLICKHOUSE_POOL_CLEANUP_INTERVAL | 60000 | Pool cleanup interval (ms) |
Feature permissions
Section titled “Feature permissions”Add to Vercel env vars:
CHM_DISABLED_FEATURES=peerdb,actionsCHM_AUTH_REQUIRED_FEATURES=agent,settings,mcpCHM_FEATURE_AGENT_ACCESS=authenticatedCHM_FEATURE_SETTINGS_ENABLED=falseFor a config file, set CHM_CONFIG_FILE to a path readable by the Vercel function runtime and include the file in the repo.
Feature ids: overview, agent, insights, health, queries, tables, metrics, dashboard, security, logs, settings, cluster, operations, actions, mcp, docs, about.
Authentication
Section titled “Authentication”None (default):
CHM_AUTH_PROVIDER=noneAPI key layer:
CHM_API_KEY_SECRET=a-long-random-secretClerk:
## Server-side (plain var)CHM_AUTH_PROVIDER=clerkCLERK_SECRET_KEY=sk_live_...
## Client-side (NEXT_PUBLIC_ prefix; inlined at build)NEXT_PUBLIC_AUTH_PROVIDER=clerkNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_...Proxy — Cloudflare Access:
CHM_AUTH_PROVIDER=proxyCHM_CF_ACCESS_TEAM_DOMAIN=https://yourteam.cloudflareaccess.comCHM_CF_ACCESS_AUD=<audience-tag>Proxy — trusted header:
CHM_AUTH_PROVIDER=proxyCHM_PROXY_AUTH_HEADER=X-Forwarded-UserCHM_PROXY_AUTH_SECRET=a-long-random-secretPut chmonitor behind a Vercel Edge Middleware or an upstream proxy that sets the header. See Authentication.
AI agent
Section titled “AI agent”LLM_API_KEY=sk-...LLM_API_BASE=https://openrouter.ai/api/v1LLM_MODEL=openrouter/freeAGENT_API_TOKEN=bearer-token-for-agent-apiAGENT_ENABLE_CONTROL_TOOLS=falseNever use NEXT_PUBLIC_LLM_API_KEY — keep the key server-side only.
Conversation store
Section titled “Conversation store”Default: browser localStorage — no server config needed.
On Vercel (Next.js v0.2), use postgres for server-side persistence. D1 and Durable Object stores are Cloudflare-only.
Postgres (recommended on Vercel):
CONVERSATION_STORE_BACKEND=postgresDATABASE_URL=postgresql://user:pass@host:5432/dbnameVercel Postgres, Neon, and Supabase all work. Add DATABASE_URL in the Vercel dashboard.
Health alerting
Section titled “Health alerting”The health sweep endpoint is GET /api/cron/health-sweep. Trigger it from a Vercel Cron Job or an external cron:
In vercel.json:
{ "crons": [ { "path": "/api/cron/health-sweep", "schedule": "*/5 * * * *" } ]}HEALTH_ALERT_ENABLED=trueHEALTH_ALERT_WEBHOOK_URL=https://hooks.slack.com/services/...HEALTH_ALERT_MIN_SEVERITY=warningCRON_SECRET=a-random-secretBranding
Section titled “Branding”NEXT_PUBLIC_TITLE_SHORT=MyClusterNEXT_PUBLIC_LOGO=/logo.pngNEXT_PUBLIC_MEASUREMENT_ID=G-XXXXXXXXXXNEXT_PUBLIC_POSTHOG_KEY=phc_...Upgrading
Section titled “Upgrading”- Push to
main(or merge a PR). Vercel auto-deploys. - For environment variable changes, update them in the dashboard and trigger a redeploy (Deployments → Redeploy).
For breaking changes between major versions, see Migrating to v0.3.
Limitations
Section titled “Limitations”- No D1 / Durable Objects: Cloudflare-only. Use postgres or clickhouse for conversation store.
- Function timeout: Vercel Hobby plan limits function duration to 10 s. Use Pro or set
CLICKHOUSE_MAX_EXECUTION_TIMEbelow that limit. - Cold starts: Vercel serverless functions have cold starts. Set
CLICKHOUSE_POOL_SIZEappropriately.