docs(databases): describe HA replication honestly as async-only#3113
docs(databases): describe HA replication honestly as async-only#3113abnegate wants to merge 1 commit into
Conversation
The high-availability page promised sync mode "no data loss on single failure" and quorum acknowledgement, recommended sync as the production default, labeled MySQL/MariaDB replication semi-synchronous, and told readers to "use a stronger sync mode" for read-your-writes. None of it exists: syncMode is rejected for sync/quorum (DAT-1942 — the value was stored and echoed while every engine replicated async; no synchronous_standby_names, no semi-sync plugin, no quorum rule). Correct the claims in place: async-only sync-modes section with the real crash-loss semantics, asynchronous replication mechanisms in the engine table, samples request async, and the read-your-writes list points at the routing that actually exists (transactions and SELECT ... FOR UPDATE pin to the primary via the pooler — already documented on the pooler page, which needed no changes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Appwrite WebsiteProject ID: Website (appwrite/website)Project ID: Tip Every Git commit and branch gets its own deployment URL automatically |
Greptile SummaryThis PR updates the dedicated databases HA page to describe replication as async-only.
Confidence Score: 4/5The docs change is close, but two user-facing HA guidance paths need fixes before merging.
src/routes/docs/products/databases/dedicated/high-availability/+page.markdoc Important Files Changed
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
src/routes/docs/products/databases/dedicated/high-availability/+page.markdoc:4
**Overview Still Promises Sync**
This page now says HA is async-only, but the dedicated databases overview still advertises synchronous and semi-synchronous replicas for the same feature. A reader can enter through that overview, try `sync`, and hit the API rejection described here.
### Issue 2 of 2
src/routes/docs/products/databases/dedicated/high-availability/+page.markdoc:662
**PostgreSQL Reads May Replicate**
The `SELECT ... FOR UPDATE` guidance is broader than the documented pooler behavior. The pooler docs only guarantee that PostgreSQL statements inside a transaction go to the primary, so a bare PostgreSQL `SELECT ... FOR UPDATE` can still be treated as a replica read and miss the read-your-writes guarantee this bullet promises.
Reviews (1): Last reviewed commit: "docs(databases): describe HA replication..." | Re-trigger Greptile |
| layout: article | ||
| title: High availability | ||
| description: Run up to five replicas of a dedicated database with synchronous, semi-synchronous, or asynchronous replication and automatic failover on primary failure. | ||
| description: Run up to five replicas of a dedicated database with asynchronous replication and automatic failover on primary failure. |
There was a problem hiding this comment.
This page now says HA is async-only, but the dedicated databases overview still advertises synchronous and semi-synchronous replicas for the same feature. A reader can enter through that overview, try sync, and hit the API rejection described here.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/routes/docs/products/databases/dedicated/high-availability/+page.markdoc
Line: 4
Comment:
**Overview Still Promises Sync**
This page now says HA is async-only, but the dedicated databases overview still advertises synchronous and semi-synchronous replicas for the same feature. A reader can enter through that overview, try `sync`, and hit the API rejection described here.
How can I resolve this? If you propose a fix, please make it concise.| - **Always read from the primary**, the safest default. The pooler routes all queries to the primary if read/write splitting is off. | ||
| - **Use read replicas, with primary-affinity for writes**, turn on the [connection pooler with read/write split](/docs/products/databases/dedicated/pooler). The pooler pins transactions and writes to the primary and routes ambient `SELECT`s to replicas. | ||
| - **Use a stronger sync mode**, in `sync` or `quorum`, any reader on an in-sync replica sees the write as soon as `COMMIT` returns. | ||
| - **Pin critical reads to the primary**, run the read inside a transaction or use `SELECT ... FOR UPDATE` — the [pooler routes both to the primary](/docs/products/databases/dedicated/pooler#read-write) even with read/write splitting on. |
There was a problem hiding this comment.
PostgreSQL Reads May Replicate
The SELECT ... FOR UPDATE guidance is broader than the documented pooler behavior. The pooler docs only guarantee that PostgreSQL statements inside a transaction go to the primary, so a bare PostgreSQL SELECT ... FOR UPDATE can still be treated as a replica read and miss the read-your-writes guarantee this bullet promises.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/routes/docs/products/databases/dedicated/high-availability/+page.markdoc
Line: 662
Comment:
**PostgreSQL Reads May Replicate**
The `SELECT ... FOR UPDATE` guidance is broader than the documented pooler behavior. The pooler docs only guarantee that PostgreSQL statements inside a transaction go to the primary, so a bare PostgreSQL `SELECT ... FOR UPDATE` can still be treated as a replica read and miss the read-your-writes guarantee this bullet promises.
How can I resolve this? If you propose a fix, please make it concise.|
Closing per Jake's direction — the honest-async-only docs approach is being dropped in favor of a different direction on syncMode. |


Problem (DAT-1942)
nyc3 2026-07-21 Drill C proved
syncModeis stored-but-inert:sync/quorumwere accepted and echoed while every engine replicated async (commits undersyncMode=syncwith the replica scaled down completed in milliseconds; nosynchronous_standby_names, no semi-sync plugin, no quorum handling). The HA docs page promised exactly that missing durability:sync= "at least one replica acknowledges",quorum= "a majority acknowledge" — plus "a safe default for production issync".'sync'— which the API now rejects (appwrite-labs/edge#890, appwrite-labs/cloud#4894).Fix (minimal, claims only)
asyncis the only accepted value (sync/quorumrejected until implemented), with the real crash-loss disclosure semantics.SELECT … FOR UPDATEpin to the primary via the pooler (verified in the pooler routing rules, already documented on the pooler page — that page needed no changes).async; dropped the "sync mode change online" limits row; frontmatter description no longer advertises synchronous/semi-synchronous.Base is
feat-dedicated-db(the branch carrying these docs, PR #3018), matching #3042's stacking.Refs DAT-1942.
🤖 Generated with Claude Code