Configure

Configuration

Settings come from a TOML file, from STREAMQL_* environment variables and from command-line flags.

Sources and precedence#

StreamQL starts with no configuration at all when you pass --upstream (or STREAMQL_UPSTREAM__URL). More settings come from layers, each overriding the one before:

  1. Built-in defaults.
  2. A TOML file given with --config or STREAMQL_CONFIG.
  3. Environment variables named STREAMQL_<SECTION>__<KEY>, with a double underscore between nesting levels.
  4. Command-line flags such as --listen, --pool-mode and --pool-size.

This is the twelve-factor layout: the same image runs everywhere and only the environment differs. Unknown keys are rejected, so a typo fails at start-up instead of being ignored.

environment
STREAMQL_UPSTREAM__URL=file:/run/secrets/upstream_url
STREAMQL_ADMIN__TOKEN=file:/run/secrets/admin_token
STREAMQL_DEFAULTS__MODE=transaction
STREAMQL_DEFAULTS__MAX_SIZE=20
STREAMQL_LOG__FORMAT=json

Validate and reload#

streamql config validate checks the effective configuration and exits non-zero on errors. streamql config show prints it as TOML. A running node reloads on SIGHUP or PUT /api/v1/config, and every change is tagged with how it takes effect:

EffectMeaningExamples
liveApplied atomically to new connections and acquisitionsMost pool, limit and policy settings
needs_drainChanges a listener or open pools; takes effect after a drain or a binary handofflisten.address, upstream.url, defaults.mode, pool[*].database, pool[*].mode
needs_restartFixed for the life of the processadmin.enabled, admin.address, admin.state_file, runtime.worker_threads, runtime.handoff_socket, log.format

The console shows the effect of every field and keeps a versioned history. Nothing is applied silently.

Secrets#

Secret settings accept a reference instead of a value, so the file and the environment can stay free of secrets: env:, file:, systemd:, k8s:, vault:, vault-logical:, aws-sm:, azure-kv: and gcp-sm:. A plain value is accepted too, and literal: forces one. References are resolved into an encrypted in-process vault, watched, and re-read every secrets.refresh_s seconds (default 60); a rotation reloads the configuration. StreamQL refuses to run as root unless secrets.allow_root is set.

listen#

KeyDefaultMeaning
listen.address0.0.0.0:6432Client listen address
listen.tls.cert, listen.tls.keyunsetCertificate and private key for client TLS
listen.require_tlsfalseReject clients that do not negotiate TLS
listen.max_client_connections10000Client connection ceiling

admin#

KeyDefaultMeaning
admin.enabledtrueServe the admin API and console
admin.address127.0.0.1:9930Admin API and console address
admin.tokenunsetBearer token for mutating endpoints (a secret reference)
admin.require_token_for_readsfalseRequire the token for read endpoints too
admin.state_fileunsetWhere changes made through the API persist across restarts

Without admin.state_file, databases and settings changed in the console last only until the next restart, and the Databases screen says so.

upstream#

KeyDefaultMeaning
upstream.urlunsetpostgres://user[:password]@host:port/database?sslmode=..., or a secret reference to one
upstream.passwordunsetPassword of the URL user (a secret reference)
upstream.host, upstream.port127.0.0.1, 5432Server address when no URL is given
upstream.sslmodepreferdisable, prefer, require, verify-ca or verify-full
upstream.sslrootcertunsetPEM CA bundle for verify-ca and verify-full; the WebPKI roots when unset
upstream.connect_timeout_ms5000Server connection timeout
upstream.readiness_checktrue/readyz reports not ready while the upstream is unreachable
upstream.readiness_grace_s5How long the upstream may be unreachable before /readyz fails

auth#

Client login uses auth.method: scram-sha-256 (default), md5 or trust. Use trust only for development; it accepts any client without a password.

KeyDefaultMeaning
auth.methodscram-sha-256Client authentication method
auth.fileunsetFile of "user" "secret" lines; create a verifier with streamql scram-verifier
auth.usersemptyInline users, each with name and secret (a password, an md5 hash or a SCRAM-SHA-256$ verifier, or a reference)
auth.auth_queryunsetLook up secrets of users missing from the file on the server

With auth_query, the lookup role defaults to streamql_auth, results are cached for cache_ttl_s (default 60), and the default query reads pg_shadow for non-superusers that are not expired. Keys: user, password, database, query, cache_ttl_s.

defaults and pools#

[defaults] applies to every pool. A [[pool]] entry overrides it for one database.

KeyDefaultMeaning
defaults.modetransactionsession, transaction or statement
defaults.max_size20Server connections per database and role
defaults.min_idle0Idle server connections kept open
defaults.queue_timeout_ms5000How long a client waits for a server connection before error 53000
defaults.server_lifetime_s3600Maximum age of a server connection
defaults.server_idle_timeout_s600Idle server connections are closed after this
defaults.server_check_delay_s30Health-check a backend on checkout after it has been idle this long
defaults.statements_per_backend500Prepared statements kept per server connection
defaults.auto_createtrueCreate pools on demand for databases without a [[pool]] entry
defaults.max_pinned_fraction0.9Maximum fraction of a pool's backends that may be pinned
defaults.max_db_connections0Server connections to one database across all users; 0 is unlimited
defaults.max_db_clients0Client connections to one database; 0 is unlimited
defaults.reservesize 0, after_wait_ms 1000, max_slowdown 2.0Extra server connections opened only after a client waited
defaults.tenantunsetPer-tenant share, with key and share
streamql.toml
[defaults]
mode = "transaction"
max_size = 20

[[pool]]
database = "shop"              # name clients connect to
upstream_database = "shop_v2"  # name on the server; defaults to database
user = "app"                   # log in to the server as this role
mode = "session"
max_size = 40
queue_timeout_ms = 2000

[pool.reserve]
size = 5
after_wait_ms = 1000

A [[pool]] entry accepts: database, upstream_database, host, port, user, mode, max_size, min_idle, queue_timeout_ms, max_db_connections, max_db_clients, reserve and tenant.

Pool groups#

A [[pool_group]] defines one set of settings for several databases at once: name, databases, host, port, user, mode, max_size, min_idle, queue_timeout_ms, max_db_connections, max_db_clients, reserve, tenant and max_group_connections. Each database still gets its own pool and server connections. max_group_connections caps the group as a shared limit.

session#

KeyDefaultMeaning
session.pin_unknown_functionstruePin a session that calls a function outside the built-in allowlist
session.attested_functionsemptyFunctions you declare free of session effects

budget and limits#

KeyDefaultMeaning
budget.max_connections0Upper bound on backend connections this member may hold; 0 probes the server
budget.reserved, budget.outside_connections0, 0Connections kept back, and connections that come from outside StreamQL
limits.max_message_bytes268435456Largest message held whole in memory
limits.stream_large_messagestrueRelay oversized row and COPY data in pieces instead of rejecting it
limits.client_idle_timeout_s0Idle client timeout; 0 disables
limits.auth_timeout_s30Time allowed to finish authentication
limits.max_user_connections0Server connections of one backend role across all databases
limits.max_user_clients0Client connections of one user; error 53300 at login
limits.max_unauthenticated1024Connections that have not finished authentication
limits.failed_loginmax_failures 20, window_s 60, block_s 60Block an address after repeated failed logins; 0 failures disables

runtime, drain and log#

KeyDefaultMeaning
runtime.worker_threads0Worker threads; 0 is one per CPU
runtime.tcp_nodelay, runtime.keepalive_sunsetSocket options
runtime.handoff_socketunsetUnix socket on which this process hands its listen sockets to a successor binary
drain.endpoint_propagation_ms2000Keep accepting for this long after readiness goes false
drain.grace_s30Time open transactions get to finish
log.levelinfoLevel or filter, for example streamql_proxy=debug
log.formattexttext or json

dataplane#

KeyDefaultMeaning
dataplane.enginetokiotokio or reactor (opt-in)
dataplane.threadingautoauto, work_stealing or per_core
dataplane.release_idle_bufferstrueRelease buffers of idle sessions
dataplane.defer_beginfalseDefer BEGIN until the first statement; changes transaction_timestamp()
dataplane.pool_handoffdirectdirect or queue
dataplane.relaycopycopy or passthrough
dataplane.clockcoarsecoarse or precise
dataplane.max_read_chunk16384Bytes read per call
dataplane.steal_after_ms5How long a waiter waits before work is stolen
dataplane.backpressure_bytes67108864Pause reading from a side whose opposite output is over this
dataplane.evidencetrueRecord one evidence record per statement for Decisions and Trace
dataplane.evidence_capacity8192Records kept in the in-memory ring

Every option here is an independent kill switch: set it back to its default to revert that behaviour.

insights#

See Insights and X-ray for [insights], and MCP access for [mcp]. Fleet settings are in Cluster, access and sign-in settings in Security.