Changelog
Release notes for the ReflexDB engine and control plane. Engine and control plane versions are released independently.
July 2026
Section titled “July 2026”Safer keyset pagination and nested limits
Section titled “Safer keyset pagination and nested limits”Engine release — pagination correctness guards and a new nested-limit default:
AFTERnow requires a single-column primary key (integer or text). Tables with a composite or missing primary key return400instead of silently skipping rows between pages, and aggregate queries rejectAFTER(previously the clause was silently ignored).- Text primary keys (UUIDs, varchar ids) now fully support keyset pagination and the deterministic
ORDER BYtiebreaker. - Malformed cursors are rejected with
400— previouslyAFTER '12abc'was silently read as12. - Nested default limit: nested to-many selections without an explicit
LIMITnow default to 1000 rows, configurable viaquery.nested_default_limit(0restores unbounded). Set an explicit nestedLIMITif you rely on larger nested arrays. GET /schemaflagsprimaryKeyonly on genuinely unique single-column primary keys — composite-key tables no longer mark a wrong column.- Reliability: clean-shutdown hardening in CDC modes, uniform
500error envelopes with no internal details leaked in headers, and/health/detailJSON-escaping fixes.
CDC lifecycle hardening
Section titled “CDC lifecycle hardening”Engine release — cold starts, reconnects and degraded mode:
- No cold-start gap: the replication position is captured before the initial data load (on PostgreSQL the stream opens before the load and buffers through it), so changes committed during a deploy’s initial load are replayed instead of lost until the next write.
- SQL Server resume reconnects are gap-free: the poller resumes from the pre-disconnect LSN using change-table retention.
ETags are boot-scoped: a cachedGET /queryresponse can no longer earn a false304across an instance restart;If-None-Matchnow also accepts RFC 9110 lists and weak tags.POST /reloadon a cap-degraded instance returns409 cap_degradedinstead of risking an out-of-memory kill (the partial memory budget cannot hold two snapshots during a swap) — resize the instance instead.- Retry exhaustion truly halts sync under
cdc_reconnect_policy: shutdown: the worker stops polling after the fatal error instead of looping, and the pending change batch is never discarded uncovered. - PostgreSQL: the position file is ignored (temporary slots cannot replay a saved LSN) and the engine says so at startup instead of logging a “saved LSN” it cannot honor.
May 2026
Section titled “May 2026”Multi-region deployment
Section titled “Multi-region deployment”Instances can now be deployed to eu-west-1 (Ireland) or us-east-1 (Virginia). Choose a region per instance at creation time, or set a default on the connection.
- Region is selected in the Add Instance form
- The control plane routes all build and deployment operations to the correct region automatically
- Multi-region is available on Team plan and above
SSH tunnel / private database support
Section titled “SSH tunnel / private database support”ReflexDB can now connect to MySQL databases that are not publicly accessible, via an SSH bastion host.
- Configure SSH credentials (host, port, user, private key) per connection
- The key is stored encrypted at rest — never exposed in logs or API responses
- A Test Connection preflight runs before any provision or rebuild to catch connectivity issues early
- Supports RSA, Ed25519, and ECDSA keys in OpenSSH format
See the SSH tunnel setup guide for configuration instructions.
Teams — seat management and invites
Section titled “Teams — seat management and invites”Team plan accounts can now add multiple members:
- Invite team members by email from Settings → Team
- Invitees receive an email and can accept with their existing account or a new one
- Seat limits are enforced per plan
- Any team member can create connections, databases, and instances; billing stays with the account owner
MFA / TOTP
Section titled “MFA / TOTP”Two-factor authentication is now available for all accounts:
- Enable in Account settings → Two-factor authentication
- Scan the QR code with any TOTP app (Google Authenticator, Authy, 1Password, etc.)
- MFA is optional; enforcement per team is planned for Business and Enterprise plans
Connections — decoupled source databases
Section titled “Connections — decoupled source databases”The data model now separates connections (MySQL server credentials) from databases (schema configs and instances):
- One connection can serve multiple databases with independent schema configs
- Connection credentials are edited in one place and apply to all associated databases
- Changing connection credentials offers an option to reconfigure all running instances immediately
Build history
Section titled “Build history”Each build now records:
- Duration — wall-clock seconds from queue to completion
- Compute tier — build instance size selected based on schema complexity
- Estimated cost — per-build cost in cents, visible in the build history panel
Per-instance uptime tracking
Section titled “Per-instance uptime tracking”The dashboard now shows a 30-day uptime percentage on each instance card, derived from the monitoring poll history.
Management API keys
Section titled “Management API keys”Long-lived rmk_... bearer tokens authenticate against the control plane API and support the same operations as the dashboard. Management keys and the control plane API are not yet generally available — coming soon.
Webhook system
Section titled “Webhook system”Outbound webhooks can be configured from Settings → Webhooks (see the Webhooks reference):
- Events:
build.completed,build.failed,instance.unhealthy,instance.recovered - Payloads are HMAC-signed (
X-Reflexdb-Signature) — verify with the secret shown at creation - Delivery history and retry controls are available per subscription
Engine
Section titled “Engine”CDC reliability — formally verified sync fixes
Section titled “CDC reliability — formally verified sync fixes”The engine’s snapshot-swap, CDC, and reconnect machinery is now covered by TLA+ model-checked specifications, and model checking surfaced several fixes:
- No lost updates between
POST /reloadand CDC sync. Manual reloads and background sync now serialise on a writer lock, so neither can silently overwrite the other’s data. A reload issued while a sync flush or safety-net reload is mid-cycle returns409 reload_busyimmediately instead of waiting it out — retry once the write completes. - CDC reconnect no longer misses changes. The stream is reopened before the recovery reload, so changes committed during reconnection are always captured (previously a short gap existed until the safety net fired).
- Failed batch flushes retry instead of being dropped. A transient load error during a CDC batch flush now keeps the pending change set and retries next tick.
resumereconnect mode keeps observed changes. Changes seen before a disconnect are flushed after reconnecting instead of being discarded.- Fatal shutdowns exit non-zero. A schema-mismatch shutdown now exits with code 1 so orchestrators and monitoring flag it instead of seeing a clean exit.
/healthreadiness,swap_count, and snapshot age are now published atomically with the snapshot pointer — no more transient disagreement between them.- Replication pause takes effect at the next sync tick: a reload already in flight when the pause lands completes first. This was always the behaviour; it is now documented in the per-instance OpenAPI spec, which also gained entries for
POST /reloadandPOST /replication/pause|resume.
Query API — aggregations
Section titled “Query API — aggregations”COUNT(*), COUNT(field), SUM(field), and AVG(field) are now supported.
Non-aggregate fields in the selection act as implicit GROUP BY keys. Aggregates can also be used inside embedded reverse relations (e.g. count of child rows per parent).
See the Aggregations reference.
Schema config — row predicates
Section titled “Schema config — row predicates”The where key on both the root config and individual table entries lets you bake SQL predicates into the snapshot at load time:
where: "deleted_at IS NULL"where_columns: [deleted_at]See the Row predicates reference.
Schema config — field aliases
Section titled “Schema config — field aliases”Tables, columns, and relations can now be renamed in the generated API without changing the MySQL schema:
field_aliases: name: display_name author: writerSee the Field aliases reference.
OpenAPI spec — alphabetical model ordering
Section titled “OpenAPI spec — alphabetical model ordering”Models in the per-instance OpenAPI spec (GET /openapi.json) are now emitted in alphabetical order, making generated client code deterministic across rebuilds.