Skip to content

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 for read_your_writes_ms (1000). standby_reads = "primary" keeps the 2.0 routing. Standbys that require a password need [auth] mode = "scram" with an auth_file; otherwise those reads fall back to the primary.
  • A failover can refuse a session with 08006 when 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 sends DISCARD ALL, instead of re-homing it without them.
  • Reconnects are metered: [limits] max_concurrent_reconnects_per_node = 16 by default (0 = unlimited, the 2.0 behaviour).
  • Patroni: [topology] patroni_confirm_leader_lock = true by default (the leader’s own REST API must answer GET /primary with 200), and startup rejects a lease_timeout_secs that is not below patroni_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_token is a startup error. Command-line deployments can now pass --admin-token or 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’s port, weight and enabled default to 5432, 100 and true. Each node still needs host and role.
  • Gateways (HTTP SQL, GraphQL, MCP) now apply [rate_limit], [query_rewrite] and [circuit_breaker].
  • Library users only: JournalOp gains a PreparedCommitted variant 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 most max_concurrent_requests = 64 requests at once. Beyond that the HTTP and GraphQL gateways answer 503 with Retry-After, and MCP answers a JSON-RPC error (-32000) for tools/call; health checks and MCP initialize/ping/tools/list are never gated. Raise the key if you run more concurrent gateway requests. query_timeout_ms (default 30000) 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 logs WARN unknown config key 'cache.l1_max_byts' ignored at startup, and fails startup when strict_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 call pg_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, CALL and DO invalidate 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 when tr_enabled = false but the cache is on. The cache stays off by default; see why.
  • Library users only: the TopologyProvider trait gains defaulted conflicts_total() and leader_timeline() methods (existing implementations keep compiling), and QueryCache::purge_tables no 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, CALL and DO invalidating the whole cache; a Patroni cluster can be the write authority ([topology] provider = "patroni"); conflicting primaries under the postgres provider are resolved by the strictly highest timeline or fail closed; gateways gain query_timeout_ms and max_concurrent_requests; unknown config keys are reported at any nesting depth; a login burst against a backend at max_connections no longer surfaces as a false authentication failure; --tr false works. 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/none fsync), and POST /api/replay mode: "committed_history". Authoritative topology ([topology] provider = "postgres") with an authority lease (lease_timeout_secs); GET /capabilities and opt-in strict_config; [load_balancer] read_strategy honoured (new power_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-tr cargo feature is a deprecated no-op and tr_enabled is the runtime switch (false stops journaling, forces tr_mode = "none", and makes POST /api/replay return 503). Dependency security updates (reqwest 0.12, wasmtime 36, lru 0.18); the unused prometheus/opentelemetry dependencies were dropped. GET /api/migration/status no longer reports migration_ready while 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 READ transactions 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 new tr_read_functions), session SET restore is transactional and savepoint-scoped, exceeding tr_max_session_set_statements refuses the failover with 08006 rather than re-homing with partial state, and write_timeout_secs is 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 (08007 asks 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, and SETs from a rolled-back transaction are no longer restored.
  • 1.6.0 — tr_mode now drives real in-session failover on both query protocols; backend faults return a proper PostgreSQL ErrorResponse instead 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, /readyz probe routes; admin dashboard fixed to work with admin_token set. 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_mode in-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-tr becomes a deprecated no-op and tr_enabled the runtime switch.
  • 1.9.0 (2026-09-22) — recovery-grade journal: real committed transactions with parameters and outcomes, optional durable segments ([journal]), and POST /api/replay mode: "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=false now actually turn Transaction Replay off.

Release notes