Operate
Cluster
Run one primary as the control plane and add workers that serve clients.
Model#
A primary StreamQL node (fleet.enabled = true) is the control plane. Workers run anywhere, join the primary, and serve PostgreSQL clients. The primary distributes configuration, shares the connection budget, and shows every worker in the console.
The primary is a single node today. Primary high availability is not implemented yet.
Enable the primary#
| Key | Default | Meaning |
|---|---|---|
fleet.enabled | false | Run the control plane on this node |
fleet.listen | 0.0.0.0:9931 | Control-plane address (mutual TLS) |
fleet.advertise | unset | Address workers use to reach the primary |
fleet.state_dir | /var/lib/streamql/fleet | CA, certificates and fleet state |
fleet.ca_ttl_days, fleet.cert_ttl_s | 365, 604800 | CA and worker certificate lifetimes |
fleet.heartbeat_ms, fleet.lease_ms | 2000, 10000 | Worker heartbeat and budget lease |
fleet.max_workers | 16 | Workers the budget is divided for |
fleet.control_reserve | 1 | Connections reserved per worker for control |
fleet.budget_total | 0 | Total connections across workers; otherwise [budget] is used |
fleet.tokens.* | default_ttl_s 3600, max_ttl_s 86400, max_uses 10 | Join token limits |
fleet.balancer.* | disabled, 0.0.0.0:6433 | Optional TCP balancer, see Load balancing |
Join a worker#
Create a one-time join token from the console (Gateways, Join tokens) or with the CLI, then start a worker with it:
# on the primary side
streamql worker token create --admin http://primary:9930 --ttl 3600 --uses 1 --group eu
# on any server
STREAMQL_WORKER_TOKEN=sqlw1.... streamql worker --join https://primary:9931 \
--advertise 10.0.0.12:6432 --admin-advertise 10.0.0.12:9930 --zone eu-1- A join token pins the fingerprint of the primary CA, so the worker verifies the primary before it sends the token. The primary stores only a digest of the secret.
- The worker generates its own key, which never leaves its state directory, and the primary signs a certificate for it. Certificates renew automatically after two thirds of their lifetime.
- Prefer the
STREAMQL_WORKER_TOKENvariable or--token-fileover--token, which is visible in the process list.
Worker flags are listed in the CLI reference.
Groups, zones and weights#
Workers carry a name, a group, a zone and a weight (1 to 10000). Groups place workers for routing and for staged rollouts. Edit them in Gateways, Workers or with PUT /api/v1/fleet/workers/{id}.
Configuration generations and rollouts#
The primary publishes its own configuration, minus [fleet], admin.state_file and runtime.handoff_socket, at start-up and on every applied change. A changed hash is a new generation. Workers store it as their configuration file, so STREAMQL_* variables and flags on the worker still override it, and the console reports these as local overrides.
Rollouts are all at once or staged. A staged policy has waves (by group or by a stable percentage of worker ids), a bake_s pause, and optional automatic advance. A rollout pauses by itself when a worker rejects the generation. You can advance, pause, resume or abort it from Gateways, Config rollout.
Shared connection budget#
The primary divides the total connection budget between workers so that the sum of shares never exceeds what PostgreSQL allows. Every registered worker keeps a static share reserved, so a primary outage cannot oversubscribe, and workers keep serving on their last configuration. A worker clamps its pool sizes to its share. Extra capacity above the static share goes to active workers by weight, first up to demand.
The budget controller and its transitions are implemented and tested, and workers clamp pool sizes to their share. A hard per-connection bound inside the pool is not wired yet.
Drain, revoke and remove#
- Drain a worker (
POST /api/v1/fleet/workers/{id}/drainor the Drain button) to take it out of load balancing while it keeps serving open connections. - Revoke a worker to refuse its certificates. It drains and exits at its next heartbeat. A revoked worker keeps its static share reserved until you remove it with
confirm_stopped=true. - Rotate the CA with
POST /api/v1/fleet/ca/rotate; the old CA is retired once every online worker confirmed the new bundle.
Deploying workers from the console#
Gateways, Workers, Deploy worker is a guided flow for an SSH server, Hetzner Cloud, DigitalOcean, AWS EC2, Azure VM and Google Compute Engine. It creates the machine and a firewall that opens only the pooler port, installs the checksum-verified binary as the streamql-worker systemd service under a non-root user, and joins it with a one-time token. Provider credentials and SSH keys are sealed or kept as secret references, host keys are confirmed, and every step is audited.