Configuration

Scale settings live in Settings → Scale and in environment variables. Connection changes take effect when the process restarts.

REDIS_URL and SCALE_POSTGRES_URL in the environment override the values saved in Settings → Scale, which is usually how a container deployment configures this. Several other settings are read only from the environment — each section below says which. The screen shows each of them read-only, with the value in effect on the main instance and the variable that sets it: change the variable and restart.

Scale mode turns on when Redis is set

There is no separate switch at the process level: an instance that starts with a Redis URL is in scale mode, one that starts without is standalone. Saving a new URL takes effect at the next restart.

The scale Postgres is the same database as SYNAPSE_DB_URL

scale_postgres_url predates the store and was kept under its old name so existing deployments did not have to change. Left empty, the scale layer uses SYNAPSE_DB_URL, which is what most deployments want. If you do set it, point it at the same Postgres — two different databases means the workers and the main instance disagree about what exists. See Environment variables.


Redis connection

Redis URL

The connection string for your Redis instance. Test checks it without saving.

FormatExample
Single noderedis://hostname:6379/0
With passwordredis://:password@hostname:6379/0
TLS (rediss)rediss://hostname:6380/0
Redis Clusterredis+cluster://node1:6379,node2:6379,node3:6379

The database index at the end (/0) is optional and defaults to 0. Use a dedicated database index if you share a Redis instance across applications.

A redis+cluster:// URL is detected automatically. The job queue itself is served from the first node in the list; the cluster client is used for event streams.

For managed Redis services, use the connection string provided by your provider. Most managed services (Upstash, Redis Cloud, ElastiCache) use rediss:// (with double-s) for TLS connections.

Queued jobs are keys in Redis. Don't run it with an eviction policy that can remove them, and turn on persistence (AOF) so a Redis restart keeps the queue — see Deployment → Production checklist.

Enable scale mode

This switch does not start or stop scale mode, which depends only on the Redis URL at startup. Its one effect today is to turn off local (stdio) MCP servers, which scale mode never runs anyway.

Worker concurrency

DefaultRange
101 – 100

The number of jobs a worker process runs at once. Read only from the WORKER_CONCURRENCY environment variable, which each worker takes from its own environment — set the variable on each worker. The screen shows the main instance's value, read-only.

Workers use asyncio, so concurrent jobs run as coroutines, not threads:

  • For I/O-heavy workloads (LLM API calls, web requests, database queries), 10–20 per worker is a reasonable starting point. The worker spends most of its time waiting on external services, so concurrency translates directly to throughput.
  • For CPU-heavy workloads (local model inference, large data processing), keep concurrency lower (3–5) and run more worker instances in parallel.

Different worker pools can run with different WORKER_CONCURRENCY values.


Postgres

The main instance and the workers use one Postgres database, which is SynapseOrch's store. There is nothing to sync: a workflow, agent, tool or MCP server saved in the UI is in the database the next job reads, and each job reads its tenant's settings — model keys included — at the start.

Postgres URL

Test checks the connection without saving.

FormatExample
Standardpostgresql://user:password@host:5432/dbname
SSL requiredpostgresql://user:password@host:5432/dbname?sslmode=require
Via PgBouncerpostgresql://user:password@pgbouncer-host:6432/dbname

Left empty, the scale layer uses SYNAPSE_DB_URL. SynapseOrch converts postgresql:// and postgres:// to the postgresql+asyncpg:// driver form for you, here, in SCALE_POSTGRES_URL and in SYNAPSE_DB_URL.

PgBouncer mode

Opens and closes a connection per query instead of keeping a pool, which PgBouncer in transaction pooling mode requires. SynapseOrch does not run PgBouncer; this is for one you put in front of Postgres yourself. It is read only from the PGBOUNCER_MODE=1 environment variable; Settings → Scale shows the main instance's value, read-only. Set the variable on the main instance and on every worker when their Postgres URL points at PgBouncer, and not otherwise — it adds a connection per query.


S3 storage

When a bucket is configured, it replaces SYNAPSE_BLOB_DIR as the blob store: the vault, run logs, notifications and cached responses are written to the bucket, in the main instance, in every worker, and in the tool processes they start. Keys are <prefix>/<tenant>/… — synapse/default/vault/notes.md on a single-tenant install with the default prefix. With one bucket shared by every process, a deployment across several hosts needs no shared directory. See Scale Mode → What you need.

The bucket is read when a process starts, from S3_BUCKET or else the saved setting, so a change takes a restart. Set the S3_* variables on every process — in .env for Docker Compose — so each one uses the same bucket. Nothing already in SYNAPSE_BLOB_DIR is copied to the bucket.

S3 bucket

The name of the bucket. It must already exist, and the credentials need s3:GetObject, s3:PutObject, s3:DeleteObject and s3:ListBucket. Test checks access.

Region

Default
us-east-1

The AWS region where the bucket is located.

Key prefix

Default
synapse

All objects are stored under this prefix. Useful when sharing a bucket across deployments.

Access key ID and secret access key

IAM credentials for S3 access. Leave both blank to use the environment's AWS credentials instead — an instance profile, an ECS task role, EKS IRSA, or any other credential chain mechanism.

Endpoint URL

Leave blank for AWS S3. Set this to use an S3-compatible object store:

ProviderEndpoint format
MinIO (self-hosted)http://minio-host:9000
Cloudflare R2https://{account_id}.r2.cloudflarestorage.com
Backblaze B2https://s3.{region}.backblazeb2.com
DigitalOcean Spaceshttps://{region}.digitaloceanspaces.com

Workers

Workers lists the workers registered in the workers table — id, status, active and maximum jobs, and health address — when the main instance is itself in scale mode. It does not refresh on its own; use the refresh button. Each worker can be health-checked, which calls its /health address, or removed from the list.

A worker registers itself when it starts and on each heartbeat; there is nothing to add by hand.

The Scale screen also shows analytics for recent runs, a lookup by run or session id, the Live queue, and Failed jobs (DLQ) with a retry for each. A retry, like Resume from failure on a run a worker ran, is queued for the workers rather than run inside the API process.


Observability

OTLP endpoint — or the OTLP_ENDPOINT variable — turns on OpenTelemetry export to your own collector, from the API and every worker: ids, timings, token counts and cost, never prompts, answers or tool data. It applies on restart and needs the telemetry packages, which the Docker images carry.

Metrics token is read only from METRICS_TOKEN. With it set, the API serves Prometheus metrics at GET /api/v2/metrics, with the token as a Bearer token. The screen shows whether one is set, never the token.

See Telemetry for what is exported and how to try it locally.

Max global queue depth

Default
1,000,000

When the queue holds this many jobs, new V2 run submissions return 503 Service Unavailable with Retry-After: 60. A backpressure valve against traffic spikes. Read only from MAX_GLOBAL_QUEUE_DEPTH.

Rate limit per tenant

Default
1,000 req/s

Maximum V2 run submissions per second, per tenant. Above it, requests return 429 Too Many Requests. Read only from RATE_LIMIT_PER_TENANT_RPS.

A tenant also can't have more than 1,000 queued, running or paused runs at once; the next submission returns 429.


Environment variables reference

Pass these to the worker image with -e, --env-file, a Kubernetes Secret or ConfigMap, or a Compose environment: block. The connection, database and storage variables apply to the main instance and API replicas too.

Required

VariableDescription
REDIS_URLRedis connection URL. Examples: redis://host:6379/0, redis+cluster://h1:6379,h2:6379
SYNAPSE_DB_URLThe database the main instance uses: postgresql://user:pass@host:5432/dbname, or the postgresql+asyncpg:// form. The worker image sets no default

Optional

VariableDescription
SCALE_POSTGRES_URLA different URL for the scale layer's connection to that same database. Unset, it uses SYNAPSE_DB_URL

Worker tuning

VariableDefaultDescription
WORKER_CONCURRENCY10Maximum concurrent jobs per worker process
WORKER_JOB_TIMEOUT3600Seconds before a job is cancelled and failed. A killed worker's jobs become available again this long plus 10 seconds after they started
WORKER_MAX_RETRIES3Tries a run gets when a stopping worker cuts it off; each resumes from its checkpoint. After the last, the run is failed and dead-lettered, and Retry resumes it. A job that raises an error is not retried
WORKER_JOB_COMPLETION_WAIT45Seconds a stopping worker gives the jobs it is running to finish before cancelling them. Keep it under the orchestrator's grace period (stop_grace_period, terminationGracePeriodSeconds)
WORKER_HEALTH_PORT9000Port for the HTTP health endpoint (GET /health)
WORKER_IDworker-<hostname>-<random>The id the worker registers under
SYNAPSE_MCP_POOL_SIZE32How many tenants' MCP server sets a worker keeps open
SYNAPSE_MCP_IDLE_TTL900Seconds before an idle tenant's MCP servers are closed

Database

VariableDefaultDescription
PGBOUNCER_MODE0Set to 1 when the Postgres URL points to PgBouncer in transaction pooling mode

Storage

VariableDefaultDescription
SYNAPSE_BLOB_DIR/blobs in the worker image and Docker Compose, /data/blobs in the single-container and API imagesWhere the vault, run logs and cached responses are written when no bucket is configured. Share it between the main instance and workers
S3_BUCKET(empty)The bucket to use as the blob store instead of SYNAPSE_BLOB_DIR — see S3 storage
S3_REGIONus-east-1AWS region of the bucket
S3_PREFIXsynapseKey prefix
S3_ACCESS_KEY_ID(empty)IAM access key. Leave blank to use the environment's credentials
S3_SECRET_ACCESS_KEY(empty)IAM secret key
S3_ENDPOINT_URL(empty)Custom endpoint for S3-compatible stores (MinIO, Cloudflare R2, etc.)

Events and limits

VariableDefaultDescription
PUBSUB_EVENT_TTL3600Seconds to keep run events in Redis Streams. After this, events expire and cannot be replayed by reconnecting clients
MAX_GLOBAL_QUEUE_DEPTH1000000Queue length at which V2 run submissions return 503
RATE_LIMIT_PER_TENANT_RPS1000V2 run submissions per second per tenant before 429

OTLP_ENDPOINT and METRICS_TOKEN are described under Observability. RUNS_RETENTION_DAYS and K8S_MODE are read but currently have no effect. NUM_QUEUE_SHARDS, WORKER_QUEUE_SHARD, DEFAULT_TENANT_ID and ENABLE_TENANT_ISOLATION are not read at all; the images no longer set or use them.

On this page