Skip to content

Enable confirmed reads by default#4390

Merged
bfops merged 19 commits intomasterfrom
bot/confirmed-reads-default
Feb 24, 2026
Merged

Enable confirmed reads by default#4390
bfops merged 19 commits intomasterfrom
bot/confirmed-reads-default

Conversation

@clockwork-labs-bot
Copy link
Collaborator

Summary

Enable confirmed reads by default for all WebSocket subscriptions and SQL queries. This is a 2.0 breaking change that improves data integrity.

What changed

Previously, subscription updates and SQL results were sent to clients immediately, before the transaction was confirmed durable. A server crash could cause clients to have observed data that was lost.

Now the server defaults to confirmed=true. Clients receive updates only after durability is confirmed. This adds a small latency cost but guarantees that any data a client receives will survive a server restart.

Changes

Server (2 files, 2 lines each):

  • subscribe.rs: SubscribeQueryParams.confirmed defaults to true
  • database.rs: SqlQueryParams.confirmed defaults to true

Documentation:

  • Migration guide updated with "Confirmed Reads Enabled by Default" section
  • Added to overview list and quick migration checklist

Opt-out

Clients can opt out by explicitly passing ?confirmed=false in the WebSocket URL or using .withConfirmedReads(false) / .WithConfirmedReads(false) / .with_confirmed_reads(false) in SDKs.

Smoketest impact

Smoketests that don't explicitly pass --confirmed will now get confirmed reads via the server default. This should not cause failures -- confirmed reads only add a small wait for durability confirmation before sending results. The confirmed_reads.py smoketest explicitly passes --confirmed and continues to work as before.

SDK impact

No SDK changes needed. SDKs only send the confirmed query parameter when explicitly set by the user. When not set, the server default applies -- which is now true.

Subscription updates and SQL query results are now only sent to clients
after the underlying transaction is confirmed to be durable. This
prevents clients from observing data that could be lost on server crash.

Previously, confirmed reads were opt-in via ?confirmed=true query param.
Now the server defaults to confirmed=true. Clients that need lower
latency at the cost of durability guarantees can opt out with
?confirmed=false or .withConfirmedReads(false) in SDKs.

Changes:
- subscribe.rs: SubscribeQueryParams.confirmed defaults to true
- database.rs: SqlQueryParams.confirmed defaults to true
- Migration guide updated with new section and checklist item

No SDK changes needed -- SDKs that don't send the param will inherit
the server default. SDKs that explicitly set confirmed=true/false
continue to work as before.
The CLI now always sends ?confirmed=true or ?confirmed=false in
subscribe and SQL requests, rather than omitting the parameter when
--confirmed is not passed. This ensures CLI behavior is deterministic
regardless of the server-side default.

Without this fix, smoketests that don't pass --confirmed would inherit
the new server default (confirmed=true), causing race conditions in
tests like test_add_table_columns where subscribers get disconnected
before the durability-confirmed update arrives.
Per Zeke's review — the CLI should only send ?confirmed when the user
passes --confirmed. Otherwise it inherits the server default, which is
the correct behavior. Sending confirmed=false explicitly would override
the new server default for users who never asked for that.
Copy link
Collaborator Author

@clockwork-labs-bot clockwork-labs-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — reverted the CLI commit. The CLI now only sends ?confirmed when --confirmed is explicitly passed, so it inherits the server default. Pushed ea1c16a94.

clockwork-labs-bot added 2 commits February 22, 2026 14:35
--confirmed or --confirmed=true sends ?confirmed=true
--confirmed=false sends ?confirmed=false
Omitting the flag defers to the server default.

This lets users explicitly opt out of confirmed reads when needed,
while inheriting the server default (now true) by default.
confirmed=True  -> passes --confirmed=true
confirmed=False -> passes --confirmed=false
confirmed=None (default) -> omits flag, inherits server default
Per Kim's review: change the server-side confirmed field from
bool-with-serde-default-true to Option<bool> with #[serde(default)].
The unwrap_or(true) now lives at the usage site (handle_websocket and
sql_direct), making it easy to later add a server config option for
the default.
…g_value

Per Kim's follow-up review:
- Add const DEFAULT_CONFIRMED_READS: bool = true in client-api lib.rs
- Use the constant in unwrap_or() at both usage sites
- Remove default_missing_value from CLI --confirmed arg so bare
  --confirmed without a value is not accepted; only --confirmed=true
  or --confirmed=false explicitly set the parameter
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
bfops and others added 2 commits February 23, 2026 11:48
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
@bfops bfops enabled auto-merge February 24, 2026 01:05
Copy link
Collaborator

@bfops bfops left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bfops bfops added this pull request to the merge queue Feb 24, 2026
Merged via the queue into master with commit b002158 Feb 24, 2026
49 of 53 checks passed
kim added a commit that referenced this pull request Feb 24, 2026
Cherry-picked from #4404
Better default for confirmed reads (which are the default since #4390).
bfops added a commit that referenced this pull request Feb 24, 2026
# Description of Changes

Reducing scope of #4390
to only apply to V2 clients.

# API and ABI breaking changes

I think this is an API change?

# Expected complexity level and risk

1

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [ ] <!-- maybe a test you want to do -->
- [ ] <!-- maybe a test you want a reviewer to do, so they can check it
off when they're satisfied. -->

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
github-merge-queue bot pushed a commit that referenced this pull request Feb 24, 2026
Cherry-picked from #4404
Better default for confirmed reads (which are the default since #4390).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants