Configuration
Variables several services share. Set the same values in each.
A service validates its environment at start and refuses to boot on an invalid value. Leave an optional variable out rather than empty: KEY= sets an empty string, which fails validation.
| Group | api | api-ingest | mcp | worker-errors | worker-jobs |
|---|---|---|---|---|---|
| PostgreSQL | ✓ | ✓ | ✓ | ✓ | ✓ |
| ClickHouse | ✓ | ✓ | ✓ | ✓ | ✓ |
| Redis | ✓ | ✓ | ✓ | ✓ | |
| Object storage | ✓ | ✓ | ✓ | ||
| Ingest queue | ✓ | ✓ | |||
| Proxies | ✓ | ✓ | ✓ | ||
| Integrations | ✓ | ✓ | |||
| ✓ | |||||
| Logging | ✓ | ✓ | ✓ | ✓ | ✓ |
PostgreSQL
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
yes | Connection string, such as postgresql://openperf:openperf@localhost:5432/openperf. |
|
DATABASE_STATEMENT_TIMEOUT_MS |
no | 60000 |
Statement timeout, 1000 to 600000. Workers only. |
ClickHouse
| Variable | Required | Default | Description |
|---|---|---|---|
CLICKHOUSE_URL |
yes | HTTP endpoint, such as http://localhost:8123. |
|
CLICKHOUSE_USER |
yes | User name. | |
CLICKHOUSE_PASSWORD |
yes | Password. | |
CLICKHOUSE_DATABASE |
yes | Database name. | |
CLICKHOUSE_MAX_EXECUTION_TIME_SECONDS |
no | 60 |
Query timeout. |
CLICKHOUSE_MAX_MEMORY_USAGE |
no | 1073741824 |
Memory per query, in bytes. |
CLICKHOUSE_EXTERNAL_GROUP_BY_BYTES |
no | 536870912 |
GROUP BY memory before spilling to disk, in bytes. |
CLICKHOUSE_EXTERNAL_SORT_BYTES |
no | 536870912 |
Sort memory before spilling to disk, in bytes. |
CLICKHOUSE_MAX_CONCURRENT_READS |
no | no limit | Concurrent queries per process; the rest wait. |
Redis
| Variable | Required | Description |
|---|---|---|
REDIS_STATE_URL |
yes | Ingest queues, rate limits and idempotency keys. Run it with maxmemory-policy noeviction, or queued telemetry is lost. |
REDIS_CACHE_URL |
yes | Query and project key cache. Eviction is fine. Not read by worker-errors. |
Object storage
An S3-compatible bucket for source maps, logos and avatars. Without STORAGE_S3_BUCKET uploads are refused, browser stacks stay minified and project cleanup skips the bucket.
| Variable | Description |
|---|---|
STORAGE_S3_BUCKET |
Bucket name. Turns object storage on. |
STORAGE_S3_ENDPOINT |
Endpoint of a non-AWS store, such as RustFS or MinIO. |
STORAGE_S3_REGION |
Region. |
STORAGE_S3_ACCESS_KEY_ID |
Access key. |
STORAGE_S3_SECRET_ACCESS_KEY |
Secret key. |
All are optional. The local RustFS from docker compose uses endpoint http://localhost:9000, bucket openperf, region us-east-1, key openperf and secret openperf-secret.
Ingest queue
How Redis queues drain into ClickHouse: logs and spans in api-ingest, errors in worker-errors. All optional.
| Variable | Default | Description |
|---|---|---|
INGEST_QUEUE_LIMIT |
10000 |
Undelivered entries per table above which intake answers 429. api-ingest only. |
INGEST_REQUEST_MAX_BYTES |
33554432 |
Size of the rows of one request above which intake answers 413. api-ingest only. |
INGEST_BATCH_MAX_ENTRIES |
256 |
Entries per insert, up to 1000. |
INGEST_BATCH_MAX_BYTES |
16777216 |
Bytes per insert. |
INGEST_DRAIN_IDLE_MS |
100 |
Sleep when the queue is empty. |
INGEST_INSERT_ATTEMPTS |
3 |
Fast retries of one insert. |
INGEST_RETRY_BASE_MS |
250 |
Delay before the first fast retry. |
INGEST_OUTAGE_BACKOFF_MS |
1000 |
First pause while ClickHouse is unreachable. |
INGEST_OUTAGE_MAX_BACKOFF_MS |
30000 |
Longest pause while ClickHouse is unreachable. |
INGEST_RETRY_BACKOFF_MS |
5000 |
First delay before retrying a batch ClickHouse rejected. |
INGEST_RETRY_MAX_BACKOFF_MS |
300000 |
Longest delay before retrying a rejected batch. |
INGEST_DEAD_LETTER_AFTER_MS |
86400000 |
Time a batch may keep failing before it moves to ingest:dead:<table>. |
INGEST_DEAD_LETTER_LIMIT |
10000 |
Dead letter capacity. When full, rejected batches stay queued. |
Proxies
| Variable | Default | Description |
|---|---|---|
TRUSTED_PROXIES |
loopback |
Comma-separated IPs, CIDRs, loopback, linklocal or uniquelocal trusted for x-forwarded-for and x-request-id. |
List every proxy and load balancer in front of the service, and web for api. Otherwise all clients share one address and one rate limit.
Sign-in codes, alerts and invitations go through Resend. Without a key, emails are skipped. Unless NODE_ENV of worker-jobs is production, skipped emails, sign-in codes included, are written to its log. In production, set up Resend or GitHub or Google sign-in.
| Variable | Description |
|---|---|
RESEND_API_KEY |
Resend API key. |
EMAIL_FROM |
Sender, such as OpenPerf <alerts@example.com>. Required with RESEND_API_KEY. |
Logging
Services log JSON lines to stdout. See Logs.
| Variable | Default | Description |
|---|---|---|
LOG_LEVEL |
info |
Lowest level: trace, debug, info, warn, error or fatal. |