Release History
Release-by-release changes and upgrade notes for HeliosProxy. The repository
CHANGELOG is the
complete record, and GitHub Releases
carries the release binaries. The container image
ghcr.io/heliosdatabase/hdb-heliosdb-proxy has a tag for each release version, its
major.minor line and latest.
The reference pages of this documentation describe the 2.0 release line. 2.1.0 changes several defaults: read its upgrade notes below before moving to it.
2.1.0
Released 2026-10-15. Read offload to standbys works as documented and is on by default. Session settings
(SET, RESET, DISCARD ALL, SET ROLE) are tracked statement by statement on both wire
protocols, so offloaded reads and Transaction Replay re-homes carry them, and a failover
that cannot restore them exactly is refused instead of continuing without them. A Patroni
leader counts only while it holds the DCS leader lock, under a lease no longer than
Patroni’s own, and a session whose home stops being the leader is re-homed. Reconnect
waves, backend connections per node and client sessions per tenant can be capped; the
query cache can follow logical replication; Transaction Replay covers prepared statements
and portals from earlier cycles.
Upgrade notes (behaviour changes):
- Reads go to standbys by default. With
[load_balancer] read_write_split = true(the default), a side-effect-free read outside a transaction runs on a standby (standby_reads = "async"); a session reads its own writes from the primary forread_your_writes_ms(1000).standby_reads = "primary"keeps the 2.0 routing. Standbys that require a password need[auth] mode = "scram"with anauth_file; otherwise those reads fall back to the primary. - A failover can refuse a session with
08006when the proxy cannot restore its settings exactly (set_config(..., false), a cycle it cannot read statement by statement, or more distinct variables than[limits] tr_max_session_set_statements) until the session sendsDISCARD ALL, instead of re-homing it without them. - Reconnects are metered:
[limits] max_concurrent_reconnects_per_node = 16by default (0= unlimited, the 2.0 behaviour). - Patroni:
[topology] patroni_confirm_leader_lock = trueby default (the leader’s own REST API must answerGET /primarywith 200), and startup rejects alease_timeout_secsthat is not belowpatroni_ttl_secs - patroni_loop_wait_secs(defaults 30 and 10): set those to the cluster’s Patroni values. - Admin token: an empty or whitespace-only
admin_tokenis a startup error. Command-line deployments can now pass--admin-tokenor explicitly opt into--admin-allow-insecure; neither flag can be combined with--config. - Shorter configuration files: omitted sections and keys, including partial
[pool],[health]and[load_balancer]sections, take the same defaults as the command line; a node’sport,weightandenableddefault to 5432, 100 andtrue. Each node still needshostandrole. - Gateways (HTTP SQL, GraphQL, MCP) now apply
[rate_limit],[query_rewrite]and[circuit_breaker]. - Library users only:
JournalOpgains aPreparedCommittedvariant and several public structs gain fields; see the CHANGELOG. The daemon’s configuration, command line, wire protocol and admin API stay compatible.
Upgrading to 2.0
HeliosProxy 2.0.0 keeps the 1.x configuration format: a 1.9 proxy.toml loads unchanged.
The major version marks behaviour changes you should review before rolling it out:
- Gateways have a concurrency cap by default.
[graphql_gateway],[mcp]and[http_gateway]admit at mostmax_concurrent_requests = 64requests at once. Beyond that the HTTP and GraphQL gateways answer503withRetry-After, and MCP answers a JSON-RPC error (-32000) fortools/call; health checks and MCPinitialize/ping/tools/listare never gated. Raise the key if you run more concurrent gateway requests.query_timeout_ms(default30000) replaces the fixed 30-second gateway timeout. - Unknown config keys are reported at any nesting depth. A typo inside a section
(
[cache] l1_max_byts) now logsWARN unknown config key 'cache.l1_max_byts' ignoredat startup, and fails startup whenstrict_config = true. Previously only top-level keys were checked, so check your startup log after upgrading. - Conflicting primaries fail closed with
[topology] provider = "postgres". When several nodes are writable, the node on the strictly highest timeline wins; a tie or an unreadable timeline authorizes nothing (1.9 took the first writable node probed). The probe role needs permission to callpg_control_checkpoint(). See Topology Providers. - Query cache (only if you enabled it). Writes on the extended protocol now
invalidate it, a stale entry is refused on every tier (L1 and L3 used to be served
until TTL), and DDL,
TRUNCATE,COPY ... FROM,EXECUTE,CALLandDOinvalidate the whole cache. Expect a lower hit rate on write-heavy workloads in exchange for read-your-commits correctness. The transaction-journal capture now also runs whentr_enabled = falsebut the cache is on. The cache stays off by default; see why. - Library users only: the
TopologyProvidertrait gains defaultedconflicts_total()andleader_timeline()methods (existing implementations keep compiling), andQueryCache::purge_tablesno longer removes L2 entries itself.
New in 2.0 that you may want to turn on: [topology] provider = "patroni"
(Topology Providers),
and the Prometheus counters heliosdb_proxy_topology_conflicting_primaries_total,
heliosdb_proxy_backend_capacity_waits_total and
heliosdb_proxy_backend_capacity_refusals_total.
Coming from 1.7 or earlier, also note the 1.8 change (ha-tr is a no-op; Transaction
Replay is always compiled and tr_enabled is the runtime switch) and that 1.9 added the
[journal], [topology], strict_config and [limits] keys described in
Configuration — all default to the previous behaviour.
Highlights by release
Highlights from 0.5.0 to 2.0.0. The repository CHANGELOG has the complete history.
- 2.0.0 (2026-09-25) — The HA topology, the query cache and Transaction Replay share one model of what the backend actually committed. The query cache (still opt-in) invalidates on commit on both wire protocols and every tier, with DDL,
TRUNCATE,COPY ... FROM,EXECUTE,CALLandDOinvalidating the whole cache; a Patroni cluster can be the write authority ([topology] provider = "patroni"); conflicting primaries under thepostgresprovider are resolved by the strictly highest timeline or fail closed; gateways gainquery_timeout_msandmax_concurrent_requests; unknown config keys are reported at any nesting depth; a login burst against a backend atmax_connectionsno longer surfaces as a false authentication failure;--tr falseworks. Read the upgrade notes and the announcement. - 1.9.0 (2026-09-22) — Recovery-grade transaction journal: real committed transactions with parameters and outcomes, an optional durable on-disk journal (
[journal] dir, CRC-checked segments, torn-tail truncation,commit/interval/nonefsync), andPOST /api/replaymode: "committed_history". Authoritative topology ([topology] provider = "postgres") with an authority lease (lease_timeout_secs);GET /capabilitiesand opt-instrict_config;[load_balancer] read_strategyhonoured (newpower_of_two); credentialed health probes and measured replica lag (require_known_lag); bounded fair client admission (client_admission_wait_secs); pooled gateway backend connections (gateway_pool_max_idle); byte budgets for the L1/L3 and edge caches;replay_deadline_secs; rustls 0.23.45 (RUSTSEC-2026-0285). - 1.8.0 (2026-09-12) — Transaction Replay is part of the default build; the
ha-trcargo feature is a deprecated no-op andtr_enabledis the runtime switch (falsestops journaling, forcestr_mode = "none", and makesPOST /api/replayreturn503). Dependency security updates (reqwest0.12,wasmtime36,lru0.18); the unusedprometheus/opentelemetrydependencies were dropped.GET /api/migration/statusno longer reportsmigration_readywhile applies are failing. - 1.7.0 — Completes the Transaction Replay series: replay verifies each statement’s response digest against what the client already saw (divergence rolls back with
40001),SERIALIZABLE/REPEATABLE READtransactions are never replayed, an interrupted read is only re-executed when every function it calls is provably side-effect-free (built-in allowlist plus the newtr_read_functions), sessionSETrestore is transactional and savepoint-scoped, exceedingtr_max_session_set_statementsrefuses the failover with08006rather than re-homing with partial state, andwrite_timeout_secsis now one deadline for the entire recovery. New[limits]bounds:tr_max_observation_bytes,backend_response_timeout_secs,max_backend_frame_bytes. - 1.6.1 — Transaction Replay commit-outcome and delivery safety: a possibly-committed statement is never re-executed (
08007asks the client to verify), recovery never appends a second result to a response the client already partly received, the idle backend-watch relay forwards only complete frames, andSETs from a rolled-back transaction are no longer restored. - 1.6.0 —
tr_modenow drives real in-session failover on both query protocols; backend faults return a proper PostgreSQLErrorResponseinstead of a dropped socket; SCRAM/MD5/cleartext backend authentication on redial; new[limits]and[cache]bounds; per-query hot-path performance work. - 1.5.0 —
[limits]and[anomaly]configuration sections;/admin/kv/<plugin>/<key>endpoints for pushing plugin runtime config;/healthz,/livez,/readyzprobe routes; admin dashboard fixed to work withadmin_tokenset. Contains a stored-XSS fix for the 1.4.0 admin dashboard — 1.4.0 operators should upgrade. - 1.4.0 — Admin API binds loopback by default (breaking); environment-variable substitution in config files; edge/geo result-cache mode; MCP bearer auth; gateway and admin request hardening.
- 1.3.0 / 1.3.1 — In-band failure detection, protocol-level health probes,
/api/circuit, idle-connection reaper. - 1.2.0 — Real LDAP search-then-bind authentication (
ldap-auth). - 1.1.0 — Transaction and statement pooling do real work on the data path.
- 1.0.0 — First stable release; every feature flag does real work, and the limits of each capability are documented.
- 0.5.0 — Client TLS/mTLS, proxy-terminated SCRAM-SHA-256, pg_hba-style admission rules, MCP agent gateway, HTTP SQL gateway, admin bearer auth, SIGHUP reload and SIGUSR2 binary handoff.
Transaction Replay
- 1.6.0 (2026-09-04) — introduced
tr_modein-session failover. - 1.6.1 (2026-09-09) — fixed commit-outcome, publication and delivery safety.
- 1.7.0 (2026-09-11) — completes the series: verification, refusals, and one deadline.
- 1.8.0 (2026-09-12) — Transaction Replay is part of the default build;
ha-trbecomes a deprecated no-op andtr_enabledthe runtime switch. - 1.9.0 (2026-09-22) — recovery-grade journal: real committed transactions with
parameters and outcomes, optional durable segments (
[journal]), andPOST /api/replaymode: "committed_history"; write-path journaling no longer convoys concurrent writers. Before 1.9.0 the journal held post-response statement text only, as synthetic one-statement transactions, and extended-protocol writes were not journaled. - 2.0.0 (2026-09-25) — the journal capture also drives commit-aware query-cache
invalidation (and runs whenever the cache is on);
--tr false/--tr=falsenow actually turn Transaction Replay off.