# Configuration Options

The Hatchet server and engine are configured through environment variables, grouped by prefix. This page documents the available options by component.

## Environment Variable Prefixes

Hatchet uses the following environment variable prefixes:

- **`SERVER_`** - main server configuration: runtime, authentication, encryption, monitoring, and integrations
- **`DATABASE_`** - PostgreSQL connection and connection pooling
- **`READ_REPLICA_`** - read replica database configuration
- **`ADMIN_`** - administrator user for initial seeding
- **`DEFAULT_`** - default tenant configuration
- **`SCHEDULER_`** - scheduler concurrency and polling intervals
- **`CACHE_`** - cache duration for repository lookups

## Required Environment Variables

The following variables are **absolutely required** for Hatchet to start successfully:

### Encryption Keys

**Option A: Local Encryption Keys**

```bash
SERVER_ENCRYPTION_MASTER_KEYSET="<base64-encoded-keyset>"
SERVER_ENCRYPTION_JWT_PUBLIC_KEYSET="<base64-encoded-jwt-public>"
SERVER_ENCRYPTION_JWT_PRIVATE_KEYSET="<base64-encoded-jwt-private>"
```

**Option B: File-based Keys**

```bash
SERVER_ENCRYPTION_MASTER_KEYSET_FILE="/path/to/master.keyset"
SERVER_ENCRYPTION_JWT_PUBLIC_KEYSET_FILE="/path/to/jwt-public.keyset"
SERVER_ENCRYPTION_JWT_PRIVATE_KEYSET_FILE="/path/to/jwt-private.keyset"
```

**Option C: Google Cloud KMS**

```bash
SERVER_ENCRYPTION_CLOUDKMS_ENABLED=true
SERVER_ENCRYPTION_CLOUDKMS_KEY_URI="gcp-kms://your-key-uri"
SERVER_ENCRYPTION_CLOUDKMS_CREDENTIALS_JSON="<credentials-json>"
```

### Authentication Secrets (Required)

```bash
SERVER_AUTH_COOKIE_SECRETS="<secret1> <secret2>"
```

### Database Connection

**Option A: Connection String**

```bash
DATABASE_URL="postgresql://user:password@host:port/dbname"
```

**Option B: Individual Parameters** (each falls back to its default if not set)

```bash
DATABASE_POSTGRES_HOST=127.0.0.1
DATABASE_POSTGRES_PORT=5432
DATABASE_POSTGRES_USERNAME=hatchet
DATABASE_POSTGRES_PASSWORD=<your-password>
DATABASE_POSTGRES_DB_NAME=hatchet
DATABASE_POSTGRES_SSL_MODE=disable
```

## Minimal Configuration Example

> **Warning:** This example is for local development when Hatchet connects to PostgreSQL
>   running on the same host. For Docker Compose deployments, use your database
>   service name, such as `postgres`, instead of `127.0.0.1`. See the [Docker
>   Compose deployment guide](/self-hosting/docker-compose).

```bash
# Database
DATABASE_URL='postgresql://hatchet:hatchet@127.0.0.1:5431/hatchet'

# Encryption (using key files - recommended for development)
SERVER_ENCRYPTION_MASTER_KEYSET_FILE=./keys/master.key
SERVER_ENCRYPTION_JWT_PRIVATE_KEYSET_FILE=./keys/private_ec256.key
SERVER_ENCRYPTION_JWT_PUBLIC_KEYSET_FILE=./keys/public_ec256.key

# Authentication
SERVER_AUTH_COOKIE_SECRETS="your-secret-key-1 your-secret-key-2"
SERVER_AUTH_SET_EMAIL_VERIFIED=true

# Basic server config
SERVER_PORT=8080
SERVER_URL=http://localhost:8080

# Development settings (optional but recommended)
SERVER_GRPC_INSECURE=true
SERVER_INTERNAL_CLIENT_BASE_STRATEGY=none
SERVER_LOGGER_LEVEL=error
SERVER_LOGGER_FORMAT=console
DATABASE_LOGGER_LEVEL=error
DATABASE_LOGGER_FORMAT=console
```

Generate encryption keys with the `hatchet-admin` image. This writes `master.key`, `private_ec256.key` and `public_ec256.key` into `./keys`:

```bash
docker run --rm -v "$(pwd)/keys:/keys" \
  ghcr.io/hatchet-dev/hatchet/hatchet-admin:latest \
  /hatchet/hatchet-admin keyset create-local-keys --key-dir /keys
```

## Runtime Configuration

Variables marked with ⚠️ are conditionally required when specific features are enabled.

Variable, Description, Default Value

`SERVER_PORT`, Port for the core server, `8080`
`SERVER_URL`, Full server URL, including protocol, `http://localhost:8080`
`SERVER_GRPC_PORT`, Port for the GRPC service, `7070`
`SERVER_GRPC_BIND_ADDRESS`, GRPC server bind address, `127.0.0.1`
`SERVER_GRPC_BROADCAST_ADDRESS`, GRPC server broadcast address, `127.0.0.1:7070`
`SERVER_GRPC_INSECURE`, Controls if the GRPC server is insecure, `false`
`SERVER_ENFORCE_LIMITS`, Enforce tenant limits, `false`
`SERVER_ALLOW_SIGNUP`, Allow new tenant signups, `true`
`SERVER_ALLOW_INVITES`, Allow new invites, `true`
`SERVER_ALLOW_CREATE_TENANT`, Allow tenant creation, `true`
`SERVER_ALLOW_CHANGE_PASSWORD`, Allow password changes, `true`
`SERVER_HEALTHCHECK`, Enable healthcheck endpoint, `true`
`SERVER_HEALTHCHECK_PORT`, Healthcheck port, `8733`
`SERVER_GRPC_MAX_MSG_SIZE`, gRPC max message size, `4194304`
`SERVER_GRPC_RATE_LIMIT`, gRPC rate limit, `1000`
`SCHEDULER_CONCURRENCY_RATE_LIMIT`, Scheduler concurrency rate limit, `20`
`SCHEDULER_CONCURRENCY_POLLING_MIN_INTERVAL`, Minimum concurrency polling interval, `500ms`
`SCHEDULER_CONCURRENCY_POLLING_MAX_INTERVAL`, Maximum concurrency polling interval, `5s`
`SCHEDULER_ADVISORY_LOCK_TIMEOUT`, Timeout for in-memory advisory lock, `5s`
`SERVER_SERVICES`, Services to run, `["all"]`
`SERVER_PAUSED_CONTROLLERS`, Paused controllers
`SERVER_ENABLE_DATA_RETENTION`, Enable data retention, `true`
`SERVER_ENABLE_WORKER_RETENTION`, Enable worker retention, `false`
`SERVER_MAX_PENDING_INVITES`, Max pending invites, `100`
`SERVER_DISABLE_TENANT_PUBS`, Disable tenant pubsub
`SERVER_MAX_INTERNAL_RETRY_COUNT`, Max internal retry count, `10`
`SERVER_PREVENT_TENANT_VERSION_UPGRADE`, Prevent tenant version upgrades, `false`
`SERVER_REPLAY_ENABLED`, Enable task replay, `true`
`SERVER_FRONTEND_URL`, Frontend URL used for links in emails and notifications (defaults to `SERVER_URL`)
`SERVER_ALLOWED_ORIGINS`, Space-separated CORS origin patterns (e.g. `https://*.example.com`); empty allows all origins, `*`
`SERVER_GRPC_WORKER_MAX_LOCK_ACQUISITION_TIME`, Max time the dispatcher waits to send a message to a worker, `250ms`
`SERVER_GRPC_STATIC_STREAM_WINDOW_SIZE`, gRPC static stream window size, in bytes, `10485760`
`SERVER_GRPC_SHUTDOWN_TIMEOUT`, Max time to drain in-flight gRPC requests on graceful shutdown, `10s`
`SERVER_GRPC_TRIGGER_WRITES_ENABLED`, Perform writes from the gRPC API, falling back to RabbitMQ when slots are exhausted, `true`
`SERVER_GRPC_TRIGGER_WRITE_SLOTS`, Number of slots for gRPC writes, `5`
`SERVER_OPTIMISTIC_SCHEDULING_ENABLED`, Enable optimistic scheduling, `true`
`SERVER_OPTIMISTIC_SCHEDULING_SLOTS`, Slots to allocate for optimistic scheduling, `5`
`SERVER_CONCURRENCY_IN_MEMORY_INDEX_ENABLED`, Use the in-memory index + outbox approach for concurrency strategies, `false`
`SERVER_API_RATE_LIMIT`, API rate limit per IP, `10`
`SERVER_API_RATE_LIMIT_WINDOW`, API rate limit window, `300s`
`SERVER_INCOMING_WEBHOOK_RATE_LIMIT`, Incoming webhook rate limit per second, per webhook, `50`
`SERVER_INCOMING_WEBHOOK_RATE_LIMIT_BURST`, Incoming webhook rate limit burst size, `100`
`SERVER_WORKFLOW_RUN_BUFFER_SIZE`, Workflow run event batch size in the dispatcher, `1000`
`SERVER_STREAM_EVENT_BUFFER_TIMEOUT`, How long the stream event buffer waits for out-of-order events before flushing, `5s`
`SCHEDULER_CHECK_ACTIVE_MIN_INTERVAL`, Minimum interval for the scheduler check-active loop, `30s`
`SCHEDULER_CHECK_ACTIVE_MAX_INTERVAL`, Maximum interval for the scheduler check-active loop, `60s`

## Database Configuration

> **Info:** In Docker Compose deployments, use the database service name in `DATABASE_URL`
>   rather than `127.0.0.1`. Inside a container, `127.0.0.1` refers to the
>   container itself. The localhost defaults shown in this section are intended
>   for local development on the same host.

Variable, Description, Default Value

`DATABASE_URL`, PostgreSQL connection string constructed from database settings if unset
`DATABASE_POSTGRES_HOST`, PostgreSQL host, `127.0.0.1`
`DATABASE_POSTGRES_PORT`, PostgreSQL port, `5431`
`DATABASE_POSTGRES_USERNAME`, PostgreSQL username, `hatchet`
`DATABASE_POSTGRES_PASSWORD`, PostgreSQL password, `hatchet`
`DATABASE_POSTGRES_DB_NAME`, PostgreSQL database name, `hatchet`
`DATABASE_POSTGRES_SSL_MODE`, PostgreSQL SSL mode, `disable`
`DATABASE_MAX_CONNS`, Max database connections, `50`
`DATABASE_MIN_CONNS`, Min database connections, `1`
`DATABASE_MAX_CONN_LIFETIME`, Max lifetime of a connection, `15m`
`DATABASE_MAX_CONN_IDLE_TIME`, Max time a connection can be idle before being closed, `1m`
`DATABASE_LOG_QUERIES`, Log database queries, `false`
`DATABASE_PGBOUNCER_URL`, Optional PgBouncer connection string. When set, most queries route through PgBouncer while DDL statements use the direct pool (`DATABASE_URL`). See [Using PgBouncer](/self-hosting/using-pgbouncer).
`DATABASE_DDL_POOL_MAX_CONNS`, Max connections for the direct (DDL) pool that bypasses PgBouncer, `5`
`DATABASE_DDL_POOL_MIN_CONNS`, Min connections for the direct (DDL) pool that bypasses PgBouncer, `1`
`DATABASE_ENFORCE_UTC_TIMEZONE`, Panic on startup if the database instance timezone is not UTC, `true`
`CACHE_DURATION`, Cache duration, `5s`
`ADMIN_EMAIL`, Admin email for seeding, `admin@example.com`
`ADMIN_PASSWORD`, Admin password for seeding, `Admin123!!`
`ADMIN_NAME`, Admin name for seeding, `Admin`
`DEFAULT_TENANT_NAME`, Default tenant name, `Default`
`DEFAULT_TENANT_SLUG`, Default tenant slug, `default`
`DEFAULT_TENANT_ID`, Default tenant ID, `707d0855-80ab-4e1f-a156-f1c4546cbf52`
`READ_REPLICA_ENABLED`, Enable read replica, `false`
`READ_REPLICA_DATABASE_URL`, Read replica database URL
`READ_REPLICA_MAX_CONNS`, Read replica max connections, `50`
`READ_REPLICA_MIN_CONNS`, Read replica min connections, `10`
`DATABASE_LOGGER_LEVEL`, Database logger level, `warn`
`DATABASE_LOGGER_FORMAT`, Database logger format, `console`
`K8S_POD_NAMESPACE`, Prefix added to the Postgres `application_name` (e.g. `<namespace>:<service>`) so connections can be attributed in `pg_stat_activity`; also sets the `k8s.namespace.name` OpenTelemetry resource attribute. Typically populated from the pod namespace via the downward API

## Security Check Configuration

Variable, Description, Default Value

`SERVER_SECURITY_CHECK_ENABLED`, Enable security check, `true`
`SERVER_SECURITY_CHECK_ENDPOINT`, Security check endpoint, `https://security.hatchet.run`

## Limit Configuration

Variable, Description, Default Value

`SERVER_LIMITS_DEFAULT_TENANT_RETENTION_PERIOD`, Default tenant retention period, `720h`
`SERVER_LIMITS_CORE_PARTITION_RETENTION`, Core partition retention period, Tenant default
`SERVER_LIMITS_OLAP_PARTITION_RETENTION`, OLAP partition retention period, Tenant default
`SERVER_LIMITS_DEFAULT_WORKER_LIMIT`, Default worker limit, `3`
`SERVER_LIMITS_DEFAULT_WORKER_ALARM_LIMIT`, Default worker alarm limit, `2`
`SERVER_LIMITS_DEFAULT_EVENT_LIMIT`, Default event limit, `1000`
`SERVER_LIMITS_DEFAULT_EVENT_ALARM_LIMIT`, Default event alarm limit, `800`
`SERVER_LIMITS_DEFAULT_EVENT_WINDOW`, Default event window, `24h`
`SERVER_LIMITS_DEFAULT_TASK_RUN_LIMIT`, Default task run limit, `2000`
`SERVER_LIMITS_DEFAULT_TASK_RUN_ALARM_LIMIT`, Default task run alarm limit, `1600`
`SERVER_LIMITS_DEFAULT_TASK_RUN_WINDOW`, Default task run window, `24h`
`SERVER_LIMITS_DEFAULT_WORKER_SLOT_LIMIT`, Default worker slot limit, `2000`
`SERVER_LIMITS_DEFAULT_WORKER_SLOT_ALARM_LIMIT`, Default worker slot alarm limit, `1600`
`SERVER_LIMITS_DEFAULT_INCOMING_WEBHOOK_LIMIT`, Default incoming webhook limit, `5`

## Alerting Configuration

Variable, Description, Default Value

`SERVER_ALERTING_SENTRY_ENABLED`, Enable Sentry for alerting
`SERVER_ALERTING_SENTRY_DSN`, Sentry DSN
`SERVER_ALERTING_SENTRY_ENVIRONMENT`, Sentry environment, `development`
`SERVER_ALERTING_SENTRY_SAMPLE_RATE`, Sentry sample rate, `1.0`
`SERVER_ANALYTICS_POSTHOG_ENABLED`, Enable PostHog analytics
`SERVER_ANALYTICS_POSTHOG_API_KEY`, PostHog API key
`SERVER_ANALYTICS_POSTHOG_ENDPOINT`, PostHog endpoint
`SERVER_ANALYTICS_POSTHOG_FE_API_HOST`, PostHog frontend API host
`SERVER_ANALYTICS_POSTHOG_FE_API_KEY`, PostHog frontend API key
`SERVER_ANALYTICS_AGGREGATE_ENABLED`, Aggregate analytics events before sending, `false`
`SERVER_ANALYTICS_AGGREGATE_FLUSH_INTERVAL`, Interval to flush aggregated analytics, `60m`
`SERVER_ANALYTICS_AGGREGATE_MAX_KEYS`, Max number of aggregation keys held in memory, `500`
`SERVER_PYLON_ENABLED`, Enable Pylon
`SERVER_PYLON_APP_ID` ⚠️, Pylon app ID (required if Pylon enabled)
`SERVER_PYLON_SECRET`, Pylon secret

## Encryption Configuration

Variable, Description, Default Value

`SERVER_ENCRYPTION_MASTER_KEYSET`, Raw master keyset, base64-encoded JSON string
`SERVER_ENCRYPTION_MASTER_KEYSET_FILE`, Path to the master keyset file
`SERVER_ENCRYPTION_JWT_PUBLIC_KEYSET`, Public JWT keyset, base64-encoded JSON string
`SERVER_ENCRYPTION_JWT_PUBLIC_KEYSET_FILE`, Path to the public JWT keyset file
`SERVER_ENCRYPTION_JWT_PRIVATE_KEYSET`, Private JWT keyset, base64-encoded JSON string
`SERVER_ENCRYPTION_JWT_PRIVATE_KEYSET_FILE`, Path to the private JWT keyset file
`SERVER_ENCRYPTION_CLOUDKMS_ENABLED`, Whether Google Cloud KMS is enabled, `false`
`SERVER_ENCRYPTION_CLOUDKMS_KEY_URI`, URI of the key in Google Cloud KMS
`SERVER_ENCRYPTION_CLOUDKMS_CREDENTIALS_JSON`, JSON credentials for Google Cloud KMS

## Authentication Configuration

Variable, Description, Default Value

`SERVER_AUTH_RESTRICTED_EMAIL_DOMAINS`, Restricted email domains
`SERVER_AUTH_BASIC_AUTH_ENABLED`, Whether basic auth is enabled, `true`
`SERVER_AUTH_SET_EMAIL_VERIFIED`, Whether the user's email is set to verified automatically, `false`
`SERVER_AUTH_COOKIE_NAME`, Name of the cookie, `hatchet`
`SERVER_AUTH_COOKIE_DOMAIN`, Domain for the cookie
`SERVER_AUTH_COOKIE_SECRETS`, Cookie secrets
`SERVER_AUTH_COOKIE_INSECURE`, Whether the cookie is insecure, `false`
`SERVER_AUTH_GOOGLE_ENABLED`, Whether Google auth is enabled, `false`
`SERVER_AUTH_GOOGLE_CLIENT_ID` ⚠️, Google auth client ID (required if Google auth enabled)
`SERVER_AUTH_GOOGLE_CLIENT_SECRET` ⚠️, Google auth client secret (required if Google auth enabled)
`SERVER_AUTH_GOOGLE_SCOPES`, Google auth scopes, `["openid", "profile", "email"]`
`SERVER_AUTH_GITHUB_ENABLED`, Whether GitHub auth is enabled, `false`
`SERVER_AUTH_GITHUB_CLIENT_ID` ⚠️, GitHub auth client ID (required if GitHub auth enabled)
`SERVER_AUTH_GITHUB_CLIENT_SECRET` ⚠️, GitHub auth client secret (required if GitHub auth enabled)
`SERVER_AUTH_GITHUB_SCOPES`, GitHub auth scopes, `["read:user", "user:email"]`

## Task Queue Configuration

Variable, Description, Default Value

`SERVER_MSGQUEUE_KIND`, Message queue kind (`rabbitmq` or `postgres`), `rabbitmq`
`SERVER_MSGQUEUE_RABBITMQ_URL`, RabbitMQ URL
`SERVER_MSGQUEUE_RABBITMQ_QOS`, RabbitMQ QoS (prefetch count), `100`
`SERVER_MSGQUEUE_RABBITMQ_MAX_PUB_CHANS`, Max RabbitMQ publish channels, `20`
`SERVER_MSGQUEUE_RABBITMQ_MAX_SUB_CHANS`, Max RabbitMQ subscribe channels, `100`
`SERVER_MSGQUEUE_RABBITMQ_COMPRESSION_ENABLED`, Enable gzip compression of messages, `false`
`SERVER_MSGQUEUE_RABBITMQ_COMPRESSION_THRESHOLD`, Byte size above which messages are compressed, `5120`
`SERVER_MSGQUEUE_RABBITMQ_ENABLE_MESSAGE_REJECTION`, Reject (rather than requeue) messages past the max death count, `false`
`SERVER_MSGQUEUE_RABBITMQ_MAX_DEATH_COUNT`, Max redeliveries before a message is dead-lettered, `1000`
`SERVER_MSGQUEUE_PUBSUB_KIND`, Pub/sub kind: `rabbitmq`, `postgres`, or `nats` (inherits `SERVER_MSGQUEUE_KIND` when unset)
`SERVER_MSGQUEUE_PUBSUB_RABBITMQ_URL`, Pub/sub RabbitMQ URL (inherits `SERVER_MSGQUEUE_RABBITMQ_URL` when unset; always uses its own connections)
`SERVER_MSGQUEUE_PUBSUB_RABBITMQ_MAX_PUB_CHANS`, Pub/sub RabbitMQ max publish channels, `10`
`SERVER_MSGQUEUE_PUBSUB_RABBITMQ_MAX_SUB_CHANS`, Pub/sub RabbitMQ max subscribe channels, `20`
`SERVER_MSGQUEUE_PUBSUB_POSTGRES_MAX_CONNS`, Pub/sub Postgres pool max connections (pool is built from the direct `DATABASE_URL`), `5`
`SERVER_MSGQUEUE_PUBSUB_POSTGRES_MIN_CONNS`, Pub/sub Postgres pool min connections, `1`
`SERVER_MSGQUEUE_PUBSUB_NATS_URL`, Pub/sub NATS seed URL(s), comma-separated for a cluster
`SERVER_MSGQUEUE_PUBSUB_NATS_USERNAME`, Pub/sub NATS username (sent as a connect option, so reconnects also authenticate)
`SERVER_MSGQUEUE_PUBSUB_NATS_PASSWORD`, Pub/sub NATS password (see username)
`SERVER_MSGQUEUE_PUBSUB_NATS_SUBJECT_PREFIX`, Pub/sub NATS subject prefix, joined to topic names with `.`, `hatchet.pubsub`
`SERVER_SINGLE_QUEUE_LIMIT`, Single queue limit, `100`

### NATS Pub/Sub

NATS is available for the best-effort pub/sub only; durable task queues stay on
RabbitMQ or Postgres. It uses core NATS (no JetStream), so delivery is
at-most-once.

The NATS server must be configured with `max_payload: 16777216` (16MiB). Task
stream events routinely exceed the NATS default of 1MiB, and Hatchet refuses to
start against a server advertising a smaller limit rather than failing later on
an oversized publish.

Prefer bare hosts in `SERVER_MSGQUEUE_PUBSUB_NATS_URL` and set the username and
password separately. Credentials embedded in the URL are not reapplied when the
client reconnects to a cluster peer it learned about through gossip.

Unlike the other backends, which isolate installations at the connection level
(a RabbitMQ vhost, a Postgres database), NATS isolates by subject. Set
`SERVER_MSGQUEUE_PUBSUB_NATS_SUBJECT_PREFIX` to keep installations that share a
NATS server from seeing each other's messages.

### Message Queue Buffers

Hatchet batches message-queue writes through per-`(tenant, message)` publish and subscribe buffers. These settings apply to both buffers; see [Improving Performance](/self-hosting/improving-performance#tuning-buffer-settings) for guidance.

Variable, Description, Default Value

`SERVER_DEFAULT_BUFFER_SIZE`, Max messages a buffer accumulates before flushing early, `10`
`SERVER_DEFAULT_BUFFER_FLUSH_INTERVAL`, How long a buffer waits before flushing, `10ms`
`SERVER_DEFAULT_BUFFER_CONCURRENCY`, Max concurrent in-flight flushes, `1` (publish) / `10` (subscribe)

## TLS Configuration

Variable, Description, Default Value

`SERVER_TLS_STRATEGY`, TLS strategy, `tls`
`SERVER_TLS_CERT`, TLS certificate
`SERVER_TLS_CERT_FILE`, Path to the TLS certificate file
`SERVER_TLS_KEY`, TLS key
`SERVER_TLS_KEY_FILE`, Path to the TLS key file
`SERVER_TLS_ROOT_CA`, TLS root CA
`SERVER_TLS_ROOT_CA_FILE`, Path to the TLS root CA file
`SERVER_TLS_MIN_VERSION`, Minimum TLS version (1.2, 1.3), `1.3`
`SERVER_INTERNAL_CLIENT_BASE_STRATEGY`, Internal client TLS strategy, `tls`
`SERVER_INTERNAL_CLIENT_BASE_INHERIT_BASE`, Inherit base TLS config, `true`
`SERVER_INTERNAL_CLIENT_TLS_BASE_CERT`, Internal client TLS cert
`SERVER_INTERNAL_CLIENT_TLS_BASE_CERT_FILE`, Internal client TLS cert file
`SERVER_INTERNAL_CLIENT_TLS_BASE_KEY`, Internal client TLS key
`SERVER_INTERNAL_CLIENT_TLS_BASE_KEY_FILE`, Internal client TLS key file
`SERVER_INTERNAL_CLIENT_TLS_BASE_ROOT_CA`, Internal client TLS root CA
`SERVER_INTERNAL_CLIENT_TLS_BASE_ROOT_CA_FILE`, Internal client TLS root CA file
`SERVER_INTERNAL_CLIENT_TLS_SERVER_NAME`, Internal client TLS server name
`SERVER_INTERNAL_CLIENT_INTERNAL_GRPC_BROADCAST_ADDRESS`, Internal gRPC broadcast address

## Logging Configuration

Variable, Description, Default Value

`SERVER_LOGGER_LEVEL`, Logger level, `warn`
`SERVER_LOGGER_FORMAT`, Logger format, `console`
`SERVER_LOG_INGESTION_ENABLED`, Enable log ingestion, `true`
`SERVER_ADDITIONAL_LOGGERS_QUEUE_LEVEL`, Queue logger level, `warn`
`SERVER_ADDITIONAL_LOGGERS_QUEUE_FORMAT`, Queue logger format, `console`
`SERVER_ADDITIONAL_LOGGERS_PGXSTATS_LEVEL`, PGX stats logger level, `warn`
`SERVER_ADDITIONAL_LOGGERS_PGXSTATS_FORMAT`, PGX stats logger format, `console`

## OpenTelemetry Configuration

For how to enable and use internal trace export with these settings, see [Internal OpenTelemetry traces](/self-hosting/opentelemetry).

Variable, Description, Default Value

`SERVER_OTEL_SERVICE_NAME`, Service name for OpenTelemetry, `server`
`SERVER_OTEL_COLLECTOR_URL`, Collector URL for OpenTelemetry
`SERVER_OTEL_INSECURE`, Whether to use an insecure connection to the collector URL, `false`
`SERVER_OTEL_TRACE_ID_RATIO`, OpenTelemetry trace ID ratio, `1`
`SERVER_OTEL_COLLECTOR_AUTH`, OpenTelemetry Collector Authorization header value
`SERVER_OTEL_METRICS_ENABLED`, Enable OpenTelemetry metrics collection, `false`
`SERVER_OBSERVABILITY_ENABLED`, Enable the worker→engine OTel collector gRPC service and REST trace endpoints, `false`
`SERVER_OBSERVABILITY_MAX_BATCH_SIZE`, Max spans accepted per Export RPC call, `1000`
`K8S_POD_NAME`, Sets the `k8s.pod.name` OpenTelemetry resource attribute; typically populated from the pod name via the downward API
`SERVER_PROMETHEUS_ENABLED`, Enable Prometheus, `false`
`SERVER_PROMETHEUS_ADDRESS`, Prometheus address, `:9090`
`SERVER_PROMETHEUS_PATH`, Prometheus metrics path, `/metrics`
`SERVER_PROMETHEUS_SERVER_URL`, Prometheus server URL
`SERVER_PROMETHEUS_SERVER_USERNAME`, Prometheus server username
`SERVER_PROMETHEUS_SERVER_PASSWORD`, Prometheus server password
`SERVER_PROMETHEUS_SERVER_TENANT_SCOPED`, Gate the per-tenant metrics endpoint on each tenant's Prometheus metrics entitlement; when `false`, metrics are served for all tenants, `false`

## Tenant Alerting Configuration

Variable, Description, Default Value

`SERVER_TENANT_ALERTING_SLACK_ENABLED`, Enable Slack for tenant alerting
`SERVER_TENANT_ALERTING_SLACK_CLIENT_ID`, Slack client ID
`SERVER_TENANT_ALERTING_SLACK_CLIENT_SECRET`, Slack client secret
`SERVER_TENANT_ALERTING_SLACK_SCOPES`, Slack scopes, `["incoming-webhook"]`
`SERVER_EMAIL_KIND`, Email integration kind, `postmark`
`SERVER_EMAIL_POSTMARK_ENABLED`, Enable Postmark
`SERVER_EMAIL_POSTMARK_SERVER_KEY`, Postmark server key
`SERVER_EMAIL_POSTMARK_FROM_EMAIL`, Postmark from email
`SERVER_EMAIL_POSTMARK_FROM_NAME`, Postmark from name, `Hatchet Support`
`SERVER_EMAIL_POSTMARK_SUPPORT_EMAIL`, Postmark support email
`SERVER_EMAIL_SMTP_ENABLED`, Enable SMTP
`SERVER_EMAIL_SMTP_SERVER_ADDR`, SMTP server address
`SERVER_EMAIL_SMTP_FROM_EMAIL`, SMTP from email
`SERVER_EMAIL_SMTP_FROM_NAME`, SMTP from name, `Hatchet Support`
`SERVER_EMAIL_SMTP_SUPPORT_EMAIL`, SMTP support email
`SERVER_EMAIL_SMTP_AUTH_USERNAME`, SMTP authentication username
`SERVER_EMAIL_SMTP_AUTH_PASSWORD`, SMTP authentication password
`SERVER_MONITORING_ENABLED`, Enable monitoring, `true`
`SERVER_MONITORING_PERMITTED_TENANTS`, Permitted tenants for monitoring
`SERVER_MONITORING_PROBE_TIMEOUT`, Monitoring probe timeout, `30s`
`SERVER_MONITORING_TLS_ROOT_CA_FILE`, Monitoring TLS root CA file
`SERVER_SAMPLING_ENABLED`, Enable sampling, `false`
`SERVER_SAMPLING_RATE`, Sampling rate, `1.0`
`SERVER_OPERATIONS_JITTER`, Operations jitter in milliseconds, `0`
`SERVER_OPERATIONS_POLL_INTERVAL`, Operations poll interval in seconds, `2`

## Cron Operations Configuration

Variable, Description, Default Value

`SERVER_CRON_OPERATIONS_TASK_ANALYZE_CRON_INTERVAL`, Interval for running ANALYZE on task-related tables, `3h`
`SERVER_CRON_OPERATIONS_OLAP_ANALYZE_CRON_INTERVAL`, Interval for running ANALYZE on OLAP/analytics tables, `3h`

## OLAP Database Configuration

Variable, Description, Default Value

`SERVER_OLAP_STATUS_UPDATE_DAG_BATCH_SIZE_LIMIT`, Batch size limit for running DAG status updates, `1000`
`SERVER_OLAP_STATUS_UPDATE_TASK_BATCH_SIZE_LIMIT`, Batch size limit for running task status updates, `1000`
`SERVER_OLAP_MQ_QOS`, Prefetch count (QoS) for the OLAP controller's message queue consumer, `100`

## Payload Store Configuration

Controls how task payloads are stored and offloaded to the external payload store.

Variable, Description, Default Value

`SERVER_PAYLOAD_STORE_EXTERNAL_CUTOVER_PROCESS_INTERVAL`, Interval between external-cutover offload passes, `15s`
`SERVER_PAYLOAD_STORE_EXTERNAL_CUTOVER_BATCH_SIZE`, Rows processed per external-cutover pass, `1000`
`SERVER_PAYLOAD_STORE_EXTERNAL_CUTOVER_NUM_CONCURRENT_OFFLOADS`, Concurrent offloads during external cutover, `10`
`SERVER_PAYLOAD_STORE_INLINE_STORE_TTL_DAYS`, Days to retain payloads in the inline store (must be > 0), `2`
`SERVER_PAYLOAD_STORE_ENABLE_WINDOW_SIZE_OPTIMIZATION`, Enable window-size optimization for payload reads, `true`
