HeliosProxy Configuration Reference
This page covers the proxy.toml settings you need to run HeliosProxy in front of HeliosDB Lite. The HeliosProxy configuration reference documents every key, including the optional sections for caching, routing hints, rate limiting, multi-tenancy, plugins and the gateways.
Configuration File Format
HeliosProxy reads a TOML file:
heliosdb-proxy --config /path/to/config.tomlWhen --config is given, the file drives the whole configuration. HeliosProxy warns about unknown keys and ignores them. Set strict_config = true to make an unknown key, or a subsystem this build cannot deliver, a startup error.
Top-Level Options
| Option | Type | Default | Description |
|---|---|---|---|
listen_address | string | "0.0.0.0:5432" | Address for client connections. Required in a config file. |
admin_address | string | "127.0.0.1:9090" | Address for the admin API. Loopback by default. Required in a config file. |
admin_token | string | (none) | Bearer token for the admin API. Required when admin_address is not a loopback address. |
admin_allow_insecure | bool | false | Explicit opt-in to a non-loopback admin bind without a token. Use it only behind your own authenticating proxy or network policy. |
strict_config | bool | false | Fail at startup on unknown keys or on subsystems this build cannot deliver. |
tr_enabled | bool | true | Transaction Replay master switch. Required in a config file. |
tr_mode | string | "session" | Transaction Replay mode (see below). Required in a config file. |
write_timeout_secs | u64 | 30 | One deadline for a whole session recovery: waiting for a primary, reconnecting, restoring session state and replaying. |
If admin_address is a non-loopback address, admin_token is unset and admin_allow_insecure is false, the proxy refuses to start. To fix it, set admin_token, bind the admin API to 127.0.0.1, or set admin_allow_insecure = true only when another layer authenticates admin requests.
Transaction Replay Modes (tr_mode)
| Mode | Behaviour when the backend fails mid-request |
|---|---|
none | The client receives one error and the connection is closed. |
session | The session stays open. Session settings are restored, and a statement that never reached the backend (outside a transaction) is re-run. |
select | session, plus side-effect-free reads are re-run. |
transaction | select, plus an uncommitted explicit transaction is replayed and verified on the new primary. |
A COMMIT whose outcome is unknown is never retried in any mode. See Transaction Replay for the exact rules.
Pool Mode Configuration ([pool_mode])
Optional. Controls when backend connections return to the pool.
HeliosDB Lite backends: use session pooling (the default). Transaction and statement pooling reset each connection with
DISCARD ALLwhen it returns to the pool, andDISCARD ALLis planned for Lite; until then the reset fails, HeliosProxy closes the backend connection instead of reusing it, and pooling gives no benefit.
[pool_mode]mode = "session"max_pool_size = 100min_idle = 10idle_timeout_secs = 600max_lifetime_secs = 3600acquire_timeout_secs = 5reset_query = "DISCARD ALL"prepared_statement_mode = "track"| Option | Type | Default | Description |
|---|---|---|---|
mode | string | "session" | Pooling mode: session, transaction, statement |
max_pool_size | u32 | 100 | Maximum backend connections per node |
min_idle | u32 | 10 | Minimum idle connections |
idle_timeout_secs | u64 | 600 | Idle connection timeout |
max_lifetime_secs | u64 | 3600 | Maximum connection lifetime |
acquire_timeout_secs | u64 | 5 | Connection acquire timeout |
reset_query | string | "DISCARD ALL" | SQL run when a connection returns to the pool |
prepared_statement_mode | string | "disable" | Prepared statement handling: disable, track, named |
Pooling Modes
| Mode | Connection Returns | Best For |
|---|---|---|
session | On client disconnect | Legacy apps, prepared statements |
transaction | After COMMIT/ROLLBACK | Web apps, microservices (with Lite, once DISCARD ALL is available) |
statement | After each statement | Simple queries, high concurrency (with Lite, once DISCARD ALL is available) |
Prepared Statement Modes
| Mode | Behavior |
|---|---|
disable | Not tracked (safest for transaction and statement pooling) |
track | Track PREPARE/DEALLOCATE and recreate on a new connection |
named | Protocol-level named statements |
Connection Pool Configuration ([pool])
Required section. Every key must be present.
[pool]min_connections = 2max_connections = 100idle_timeout_secs = 300max_lifetime_secs = 1800acquire_timeout_secs = 30test_on_acquire = true| Option | Type | Typical value | Description |
|---|---|---|---|
min_connections | usize | 2 | Minimum connections per node |
max_connections | usize | 100 | Maximum connections per node (must be >= min_connections) |
idle_timeout_secs | u64 | 300 | Idle connection timeout |
max_lifetime_secs | u64 | 1800 | Maximum connection lifetime |
acquire_timeout_secs | u64 | 30 | Connection acquire timeout |
test_on_acquire | bool | true | Health-check a connection before handing it out |
Load Balancer Configuration ([load_balancer])
Required section.
[load_balancer]read_strategy = "round_robin"read_write_split = truelatency_threshold_ms = 100| Option | Type | Typical value | Description |
|---|---|---|---|
read_strategy | string | "round_robin" | Read routing strategy |
read_write_split | bool | true | Route writes to the primary and reads to standbys and replicas |
latency_threshold_ms | u64 | 100 | Latency above which a node is treated as unhealthy for routing |
Routing Strategies (read_strategy)
| Strategy | Description |
|---|---|
round_robin | Rotate through nodes equally |
weighted_round_robin | Rotate in proportion to each node’s weight |
least_connections | Route to the node with the fewest attached sessions |
latency_based | Route to the node with the lowest measured probe latency |
random | Random node selection |
power_of_two | Sample two nodes and pick the one with fewer attached sessions |
Health Check Configuration ([health])
Required section.
[health]check_interval_secs = 5check_timeout_secs = 3failure_threshold = 3success_threshold = 2check_query = "SELECT 1"| Option | Type | Typical value | Description |
|---|---|---|---|
check_interval_secs | u64 | 5 | Interval between probes (must be at least 1) |
check_timeout_secs | u64 | 3 | Probe timeout |
failure_threshold | u32 | 3 | Consecutive failures before a node is marked unhealthy |
success_threshold | u32 | 2 | Consecutive successes before it is healthy again |
check_query | string | "SELECT 1" | Query used when user is set |
user / password / database | string | (none) | Optional probe credentials. Without them the probe is a credential-less protocol check. |
Node Configuration ([[nodes]])
One entry per backend. At least one node with role = "primary" is required.
[[nodes]]host = "primary.example.com"port = 5432role = "primary"weight = 100enabled = truename = "primary-1"
[[nodes]]host = "standby-1.example.com"port = 5432role = "standby"weight = 50enabled = true
[[nodes]]host = "replica-1.example.com"port = 5432role = "replica"weight = 25enabled = true| Option | Type | Default | Description |
|---|---|---|---|
host | string | required | Node hostname or IP |
port | u16 | required | PostgreSQL wire port |
role | string | required | primary, standby or replica |
weight | u32 | required | Load-balancing weight |
enabled | bool | required | Whether the node is routable. Toggle it at runtime with the admin API. |
http_port | u16 | 8080 | HTTP API port on the backend node |
name | string | optional | Human-readable name for logs and metrics |
Node Roles
| Role | Description |
|---|---|
primary | Read/write node (at least one required) |
standby | Promotable standby. Receives reads when read_write_split is on. |
replica | Read-only replica. Not promotable. |
HeliosProxy does not promote standbys. An external HA manager performs the promotion. With HeliosDB Lite backends, use the default static topology (configured roles plus health checks).
TLS Configuration ([tls])
Optional TLS for client connections. Omit the whole section to disable TLS. When the section is present, enabled, cert_path, key_path and require_client_cert must all be set.
[tls]enabled = truecert_path = "/path/to/cert.pem"key_path = "/path/to/key.pem"ca_path = "/path/to/ca.pem"require_client_cert = false| Option | Type | Description |
|---|---|---|
enabled | bool | Enable TLS for client connections |
cert_path | string | Server certificate path (PEM) |
key_path | string | Server private key path (PEM) |
ca_path | string | Optional CA certificate for client-certificate verification |
require_client_cert | bool | Require a valid client certificate |
Complete Example
# HeliosProxy in front of a HeliosDB Lite primary, standby and replica
listen_address = "0.0.0.0:5433"admin_address = "127.0.0.1:9090"tr_enabled = truetr_mode = "session"write_timeout_secs = 30
# Connection pooling mode[pool_mode]mode = "session"max_pool_size = 100min_idle = 10
# Basic pool settings[pool]min_connections = 5max_connections = 100idle_timeout_secs = 300max_lifetime_secs = 1800acquire_timeout_secs = 30test_on_acquire = true
# Load balancing[load_balancer]read_strategy = "least_connections"read_write_split = truelatency_threshold_ms = 50
# Health checks[health]check_interval_secs = 5check_timeout_secs = 3failure_threshold = 3success_threshold = 2check_query = "SELECT 1"
# Primary node[[nodes]]host = "db-primary.internal"port = 5432role = "primary"weight = 100enabled = truename = "primary"
# Standby node[[nodes]]host = "db-standby-1.internal"port = 5432role = "standby"weight = 100enabled = truename = "standby-1"
# Read replica[[nodes]]host = "db-replica-1.internal"port = 5432role = "replica"weight = 50enabled = truename = "replica-1"
# TLS (optional): add a complete [tls] section to enable it# [tls]# enabled = true# cert_path = "/etc/heliosproxy/server.crt"# key_path = "/etc/heliosproxy/server.key"# require_client_cert = falseEnvironment Variable Substitution
HeliosProxy has no HELIOS_PROXY_* override system. Instead, before parsing, it expands ${NAME} and ${NAME:-default} references in the file text:
listen_address = "${HELIOS_LISTEN:-0.0.0.0:5433}"admin_token = "${ADMIN_TOKEN}" # startup fails if ADMIN_TOKEN is unsetA ${NAME} with no default and no value in the environment stops startup with an error that names the variable. The only environment variable the proxy reads directly is HELIOS_DRAIN_TIMEOUT_SECS, which overrides the SIGUSR2 drain timeout.
Configuration Validation
The proxy validates the configuration on startup and refuses to start with a descriptive error when, for example:
- A required key or section is missing, or no
[[nodes]]entry hasrole = "primary" max_connectionsis lower thanmin_connections[health] check_interval_secsis0admin_addressis not loopback and neitheradmin_tokennoradmin_allow_insecure = trueis set
Admin API Endpoints
The admin API listens on admin_address. When admin_token is set, send Authorization: Bearer <token> on every route except the liveness and readiness probes.
| Endpoint | Method | Description |
|---|---|---|
/health, /healthz | GET | Liveness |
/readyz | GET | Readiness: 200 when at least one backend is healthy |
/nodes | GET | Backend nodes with health |
/nodes/{addr}/disable | POST | Remove a node (host:port) from routing |
/nodes/{addr}/enable | POST | Return a node to routing |
/pools | GET | Per-node connection pool statistics |
/config | GET | Current configuration (read only; reload with SIGHUP) |
/metrics | GET | Server metrics (JSON) |
/metrics/prometheus | GET | Prometheus exposition text, wrapped in a JSON text field |
# Take a node out of routing before maintenance, then return itcurl -X POST http://127.0.0.1:9090/nodes/db-replica-1.internal:5432/disablecurl -X POST http://127.0.0.1:9090/nodes/db-replica-1.internal:5432/enableThe Admin API reference lists every route and response.