--- title: Environment Variables | Formbricks Hub description: Runtime configuration for the Hub API, worker, database pool, webhooks, embeddings, and observability. --- ## Required | Variable | Used by | Default | Description | | -------------- | ---------- | ----------------------- | ----------------------------------------------------------------------- | | `API_KEY` | API | - | Bearer token required for authenticated `/v1/*` API requests. | | `DATABASE_URL` | API/worker | Local test database URL | PostgreSQL connection string. Set explicitly outside local development. | `hub-worker` requires an explicit `DATABASE_URL`; it does not use the local test default. ## Server | Variable | Default | Description | | -------------------------- | ------- | ------------------------------------------------------------------------------------------------------ | | `PORT` | `8080` | HTTP port used inside the API process/container. | | `PUBLIC_BASE_URL` | - | Public API root advertised in runtime OpenAPI specs when Hub is behind ingress, TLS, or a path prefix. | | `LOG_LEVEL` | `info` | Log level, such as `debug`, `info`, `warn`, or `error`. | | `SHUTDOWN_TIMEOUT_SECONDS` | `30` | Graceful shutdown timeout in seconds. | The Quick Start Docker Compose file also supports `HUB_PORT`, `POSTGRES_PORT`, and `HUB_IMAGE_TAG` as Compose conveniences. They are compose variables, not Hub runtime settings. `PUBLIC_BASE_URL` must be an absolute `http` or `https` URL. It may include a path prefix, such as `https://example.com/hub`, but must not include query strings, fragments, or credentials. Hub serves runtime OpenAPI specs at `/openapi.yaml` and `/openapi.json`. ## Database Pool | Variable | Default | Description | | -------------------------------------- | ------- | ------------------------------------------------ | | `DATABASE_MAX_CONNS` | `25` | Maximum PostgreSQL pool connections. | | `DATABASE_MIN_CONNS` | `0` | Minimum PostgreSQL pool connections. | | `DATABASE_MAX_CONN_LIFETIME_SECONDS` | `3600` | Maximum connection lifetime. | | `DATABASE_MAX_CONN_IDLE_TIME_SECONDS` | `1800` | Maximum idle time before a connection is closed. | | `DATABASE_HEALTH_CHECK_PERIOD_SECONDS` | `60` | Pool health-check interval. | | `DATABASE_CONNECT_TIMEOUT_SECONDS` | `10` | Database connection timeout. | ## River Worker | Variable | Default | Description | | --------------------------------------- | ------- | ---------------------------------------------------------------- | | `RIVER_JOB_TIMEOUT_SECONDS` | `0` | Max job runtime before cancellation; `0` uses the River default. | | `RIVER_RESCUE_STUCK_JOBS_AFTER_SECONDS` | `0` | Stuck-job rescue interval; `0` uses the River default. | | `RIVER_COMPLETED_JOB_RETENTION_SECONDS` | `86400` | Completed job retention period; `-1` disables deletion. | | `RIVER_CLIENT_ID` | - | Optional client identifier for logs and River coordination. | ## Webhooks | Variable | Default | Description | | ------------------------------------ | ----------------------------------------- | --------------------------------------------------- | | `WEBHOOK_DELIVERY_MAX_CONCURRENT` | `100` | Max concurrent webhook delivery workers. | | `WEBHOOK_DELIVERY_MAX_ATTEMPTS` | `3` | Max delivery attempts per webhook job. | | `WEBHOOK_MAX_FAN_OUT_PER_EVENT` | `500` | Max webhook jobs inserted for a single event batch. | | `WEBHOOK_MAX_COUNT` | `500` | Max total webhook endpoints allowed. | | `WEBHOOK_HTTP_TIMEOUT_SECONDS` | `15` | Outbound webhook request timeout. | | `WEBHOOK_ENQUEUE_MAX_RETRIES` | `3` | Retries when enqueueing webhook jobs fails. | | `WEBHOOK_ENQUEUE_INITIAL_BACKOFF_MS` | `100` | Initial enqueue retry backoff in milliseconds. | | `WEBHOOK_ENQUEUE_MAX_BACKOFF_MS` | `2000` | Maximum enqueue retry backoff in milliseconds. | | `WEBHOOK_BLACKLIST` | `localhost,127.0.0.1,::1,169.254.169.254` | Comma-separated hostnames blocked for webhook URLs. | ## Event Publisher | Variable | Default | Description | | --------------------------------------------- | ------- | ------------------------------------- | | `MESSAGE_PUBLISHER_QUEUE_MAX_SIZE` | `16384` | In-memory event channel buffer size. | | `MESSAGE_PUBLISHER_PER_EVENT_TIMEOUT_SECONDS` | `10` | Per-event publish timeout in seconds. | ## Embeddings | Variable | Default | Description | | --------------------------------- | ------- | ------------------------------------------------------------------ | | `EMBEDDING_PROVIDER` | - | Embedding provider. One of `openai`, `google`, or `google-vertex`. | | `EMBEDDING_PROVIDER_API_KEY` | - | API key for the embedding provider. | | `EMBEDDING_MODEL` | - | Embedding model name. | | `EMBEDDING_MAX_CONCURRENT` | `5` | Max concurrent embedding jobs. | | `EMBEDDING_MAX_ATTEMPTS` | `3` | Max embedding attempts. | | `EMBEDDING_NORMALIZE` | `false` | Whether to normalize embeddings before storage. | | `EMBEDDING_GOOGLE_CLOUD_PROJECT` | - | Google Cloud project for supported providers. | | `EMBEDDING_GOOGLE_CLOUD_LOCATION` | - | Google Cloud location for supported providers. | ## Observability | Variable | Default | Description | | ----------------------- | ------- | ------------------------------- | | `OTEL_METRICS_EXPORTER` | - | OpenTelemetry metrics exporter. | | `OTEL_TRACES_EXPORTER` | - | OpenTelemetry traces exporter. | ## MCP Client Package These variables are used by MCP client package flows. They are not read by the Hub API or worker processes. | Variable | Default | Description | | ------------------------- | ------- | ---------------------------------------------------------------------------------- | | `HUB_API_KEY` | - | API key used by MCP clients; usually the same value as Hub’s `API_KEY`. | | `FORMBRICKS_HUB_BASE_URL` | - | Hub API root reachable from the MCP server, for example `https://hub.example.com`. | See [Connect Hub to AI Clients via MCP](/guides/hub-mcp/index.md) for client setup.