Litestream, rqlite or cr-sqlite: Which SQLite Replication Model Fits?

A SQLite replica survives the server crash, but the app still can’t accept the next write. Which of Litestream, rqlite and cr-sqlite fits the failure you’re planning for?

Litestream, rqlite or cr-sqlite: Which SQLite Replication Model Fits?
TLDR
  • For host-loss recovery, examine Litestream’s replication lag and restore process.
  • For writes through partial outages, rqlite requires a communicating majority; read freshness depends on the selected mode.
  • For independent offline edits, cr-sqlite provides change merging rather than a shared write leader.

The shared storage engine hides different requirements

In an October 23 retrospective, rqlite creator Philip O'Toole traces distributed SQLite back to his project's 2014 beginnings. His central distinction is between designs answering different questions: consensus, streaming replication and merging independent changes.

Operational questionRepresentative approachKey condition
Can the database be restored after losing its host?Litestream's asynchronous replicationReplication lag and a restore process
Can writes continue after some nodes fail?rqlite's Raft consensusA communicating majority of voting nodes
Can devices edit offline and reconcile later?cr-sqlite's change mergingChange exchange and merge rules

Litestream preserves a route back after host failure

Litestream runs separately from the application and asynchronously replicates SQLite WAL changes. Recovery reconstructs the database from a stored snapshot and subsequent LTX files.

Its operational guidance identifies a window in which a catastrophic failure can lose recent writes that have not reached the replica. The documented default for S3 is a one-second replication interval; that is not a universal guarantee limiting data loss to one second.

Current documentation also describes VFS read replicas. Litestream is therefore more than a backup that can never serve queries. Serving remote reads, however, does not mean that each write waits for multi-node consensus.

rqlite needs a connected majority to keep committing writes

The cluster guidelines require two communicating voting nodes in a three-node cluster, or three in a five-node cluster. Non-voting read replicas do not count toward that quorum.

The rqlite FAQ explains that clients may send requests to different nodes, but changes still go through the leader. Followers forward writes; they do not independently accept divergent changes for later merging.

Applications must also write through the HTTP API instead of modifying the underlying SQLite file directly. This is not a transparent replacement for embedded file access, and adding nodes does not horizontally scale writes. Fault tolerance is the main purpose.

Replication does not give every read the same guarantee

rqlite's read-consistency modes make the distinction explicit. The default, Weak, checks leadership locally and can return stale data during a short leadership-transition window.

Linearizable adds quorum communication and waits for the required changes to be applied. None reads the local database without checking leadership or cluster contact, permitting stale results. Query latency and freshness requirements need to be chosen together.

Offline edits ask for reconciliation, not a reachable leader

cr-sqlite adds CRDT-based replication for independent changes. Its stated uses include device synchronization, real-time collaboration and offline editing.

The extension exposes changes through crsql_changes; networking code fetches and applies those changes between peers. Loading the extension does not, by itself, supply every device's transport path.

Frequently asked questions

Will more rqlite nodes proportionally increase write throughput?

No. All writes pass through the leader. Adding nodes is not a horizontal write-scaling mechanism.

Does the default read mode always return current data?

Weak reads can be stale during leadership changes. Select a read mode according to the guarantee the application needs.

Decide whether the application can wait for recovery, tolerate missing recent writes, or must accept edits while disconnected. Those requirements explain why the same storage engine supports such different replication designs.