{"article":{"slug":"twelve-years-of-distributed-sqlite","title":"Twelve years of distributed SQLite","subtitle":null,"summary":"rqlite creator Philip O'Toole recounts the history of distributed SQLite from rqlite's 2014 launch (Raft + SQLite) through dqlite, Litestream, LiteFS, cr-sqlite, libSQL/Turso, SQLite Cloud and Cloudflare D1, arguing the design space has three corners (consensus, streaming, merge) and that the money went to the platforms.","content_type":"blog_post","language":"en","canonical_url":"https://philipotoole.com/twelve-years-of-distributed-sqlite/","author":{"name":"Philip O'Toole","url":"https://philipotoole.com/","person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Philip O'Toole","url":"https://philipotoole.com/","listing_slug":null,"listing":null},"topics":[{"name":"Databases","slug":"databases","url":"https://listedarticles.com/topics/databases"},{"name":"Open Source","slug":"open-source","url":"https://listedarticles.com/topics/open-source"},{"name":"Infrastructure","slug":"infrastructure","url":"https://listedarticles.com/topics/infrastructure"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":1129,"reading_minutes":5,"published_at":"2026-10-23T00:00:00.000Z","added_at":"2026-10-24T05:08:55.185Z","updated_at":"2026-10-24T05:08:55.185Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/twelve-years-of-distributed-sqlite","markdown_url":"https://listedarticles.com/articles/twelve-years-of-distributed-sqlite.md","example":false,"citation":"Philip O'Toole, Philip O'Toole. \"Twelve years of distributed SQLite.\" 23 Oct 2026. https://philipotoole.com/twelve-years-of-distributed-sqlite/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://philipotoole.com/twelve-years-of-distributed-sqlite/"},"body_markdown":"# Twelve years of distributed SQLite\n\n*Philip O'Toole · October 23, 2026*\n\nIn September 2014 I published a [short post announcing](https://philipotoole.com/replicating-sqlite-using-raft-consensus/) [rqlite](https://rqlite.io). The idea was simple: take [SQLite](https://sqlite.org/), put a [Raft log](https://raft.github.io) in front of it, and replicate every write to a cluster so that the loss of a node did not mean the loss of the data. The [source went on GitHub](https://github.com/rqlite/rqlite) that same weekend. As far as I can tell, that was the first open-source system to combine Raft and SQLite. Nobody else was doing it, and for several years nobody else tried.\n\nToday “distributed SQLite” is a category with a dozen projects in it, a few of them venture-funded, two of them acquired. Since the people now writing about the category tend to start the story around 2021, I thought I should write down the version that starts in 2014. I was there for all of it.\n\n## 2014: rqlite\n\nThe need was concrete. A clustered system [I worked on at jut.io](https://philipotoole.com/resume/) needed a small amount of relational storage, and the question of which node should hold it had no good answer. Replicating SQLite with a consensus protocol solved it. We went another way at work, but [I kept building rqlite](https://philipotoole.com/tag/rqlite/) because the problem was general and the solution was small. The first version used [goraft](https://github.com/goraft), the same library [InfluxDB](https://github.com/influxdata/influxdb) and [etcd](https://etcd.io/) used at the time (I subsequently joined InfluxDB as a core developer around the same time). In early 2016 I [replaced it with](https://github.com/rqlite/rqlite/blob/master/CHANGELOG.md#20-april-5th-2016) [Hashicorp’s Raft implementation](https://github.com/hashicorp/raft) which rqlite still uses.\n\nThe design decision that mattered most was made then and never changed. rqlite is a [CP system](https://www.scylladb.com/glossary/cap-theorem/). Writes must go through the leader, a majority must acknowledge, and a partitioned minority refuses writes. Everything else, the [HTTP API](https://rqlite.io/docs/api/api/), the [read-consistency levels](https://rqlite.io/docs/api/read-consistency/), the [snapshotting](https://youtu.be/8XbxQ1Epi5w?t=493), followed from that.\n\n## Before 2014, and alongside it\n\nTwo things deserve mention for honesty’s sake. [Expensify](https://www.expensify.com/) had been replicating SQLite inside its own infrastructure for years with a [Paxos](https://en.wikipedia.org/wiki/Paxos_(computer_science))-style protocol; they released it as [Bedrock](https://bedrockdb.com/) in [2016](https://dbdb.io/db/bedrock). And ActorDB, an Erlang system that gave each “actor” its own SQLite database replicated by Raft, [appeared around the same time as rqlite](https://dbdb.io/db/actordb). Neither was widely adopted outside its origin, but both show the idea was in the air. What rqlite did was make it a standalone, general-purpose, open-source thing anyone could run.\n\n## 2017: dqlite\n\n[Canonical](https://canonical.com/) built [dqlite](https://canonical.com/dqlite) to get [LXD](https://canonical.com/lxd) and later MicroK8s an embedded replicated store without running etcd. [Mark Shuttleworth](https://en.wikipedia.org/wiki/Mark_Shuttleworth) actually called me once, and we talked, hoping that rqlite could be made to work, but it never quite fit. dqlite [began in Go](https://www.reddit.com/r/golang/comments/8a8h8y/dqlite_distributed_sqlite_for_go_applications/) and was rewritten in C with its own Raft library. It is the project most similar to rqlite in intent, and the main difference is of one of packaging: dqlite is a library you embed, rqlite is a server you run. Canonical’s need was a database inside their products: mine was a database beside anyone’s product.\n\n## 2021: Litestream, and a change of approach\n\n[Ben Johnson](https://github.com/benbjohnson) (whom I worked with at InfluxDB) released [Litestream](https://github.com/benbjohnson/litestream) in [early 2021](https://litestream.io/blog/why-i-built-litestream/). Litestream does not use consensus at all. It watches the SQLite [WAL](https://www.sqlite.org/wal.html) and streams it to [S3](https://aws.amazon.com/s3/), giving you disaster recovery for a single-node SQLite database at almost no cost. Ben’s argument was that most applications do not need a cluster; they use one machine and need a way to recover if it dies. He was right about a great many applications, and the “SQLite is enough” movement of the next few years, with blog posts and conference talks, owes a lot to that argument.\n\nLitestream and rqlite answer different questions. Litestream: what if the machine dies? rqlite: what if the machine dies and I cannot wait to restore? The first question is more common, the second is the one people have when they come to rqlite.\n\n[Fly.io](https://fly.io/) hired Ben in 2022 and shipped [LiteFS](https://docs.fly.io/litefs), which replicates SQLite at filesystem level with leases from [Consul](https://developer.hashicorp.com/consul). It was the first attempt to make replicated SQLite a platform feature rather than a thing you deploy. And in a final twist, Litestream [inspired](https://philipotoole.com/rqlite-8-0-large-dataset-support-and-core-feature-upgrades/) rqlite’s v8.0 approach to handling the SQLite WAL.\n\n## 2022: forks and extensions\n\nTwo projects in 2022 took approaches that neither rqlite nor Litestream had. [cr-sqlite](https://github.com/vlcn-io/cr-sqlite) added [CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) to SQLite as an extension, so that multiple writers could diverge and merge without a leader. That is the AP corner of the design space, and it suits local-first applications where rqlite’s CP guarantees would be a hindrance.\n\n[libSQL](https://github.com/tursodatabase/libsql) forked SQLite itself. ChiselStrike, later [Turso](https://turso.tech/), wanted to change things inside the engine that the SQLite project, which does not accept outside contributions, and would not change. On top of the fork they built a hosted service with replicas at the edge. Turso raised venture money on that, and in 2026 [Supabase acquired them](https://turso.tech/blog/turso-is-joining-supabase).\n\nAround the same time, [SQLite Cloud](https://www.sqlite.ai/cloud) appeared, offering hosted SQLite replicated with Raft. It is the project closest to rqlite’s original design, wrapped in a cloud service.\n\n## 2022 onward: the platforms\n\n[Cloudflare](https://www.cloudflare.com/) announced [D1](https://developers.cloudflare.com/d1/) in 2022, SQLite as a serverless database inside their edge network, and later put SQLite storage inside [Durable Objects](https://developers.cloudflare.com/durable-objects/concepts/what-are-durable-objects/). This is replicated SQLite as a managed product from a company that does not need to tell you how it works. Turso’s service is the same shape. The category had gone from “a thing you run” to “a thing you buy.”\n\n## What the twelve years show\n\nThree things, I think.\n\nThe core was right. SQLite as a storage engine, with replication added on the outside, has been reinvented by at least eight teams with different needs and different protocols. Nobody has found a reason to stop doing it.\n\nThe design space has three corners, and they appeared in order. Consensus first (rqlite, dqlite): one leader, strong consistency, a cluster. Streaming second (Litestream): one writer, cheap recovery, no cluster. Merge third (cr-sqlite, and parts of the local-first movement): many writers, eventual consistency. Each is correct for a different question, and most of the arguments are arguments between their users about which question is being asked.\n\nAnd the money went to the platforms. rqlite, dqlite, and Litestream are open source and free. The projects that raised the capital or got acquired are the ones that turned replicated SQLite into a service with a bill. That is the usual fate of infrastructure ideas, and I do not mind it. But it is worth recording that the idea was open source for eight years before anyone sold it.\n\n[rqlite](https://rqlite.io/) is still here. It does the same thing it did in 2014, a good deal better, and it is still the thing you reach for when you want a fault-tolerant relational database you can run yourself, understand fully, and not pay anyone for. Twelve years in, I am content with that position in the story.\n","body_html":"<h1 id=\"twelve-years-of-distributed-sqlite\">Twelve years of distributed SQLite</h1>\n<p><em>Philip O&#39;Toole · October 23, 2026</em></p>\n<p>In September 2014 I published a <a href=\"https://philipotoole.com/replicating-sqlite-using-raft-consensus/\" rel=\"nofollow ugc noopener\">short post announcing</a> <a href=\"https://rqlite.io\" rel=\"nofollow ugc noopener\">rqlite</a>. The idea was simple: take <a href=\"https://sqlite.org/\" rel=\"nofollow ugc noopener\">SQLite</a>, put a <a href=\"https://raft.github.io\" rel=\"nofollow ugc noopener\">Raft log</a> in front of it, and replicate every write to a cluster so that the loss of a node did not mean the loss of the data. The <a href=\"https://github.com/rqlite/rqlite\" rel=\"nofollow ugc noopener\">source went on GitHub</a> that same weekend. As far as I can tell, that was the first open-source system to combine Raft and SQLite. Nobody else was doing it, and for several years nobody else tried.</p>\n<p>Today “distributed SQLite” is a category with a dozen projects in it, a few of them venture-funded, two of them acquired. Since the people now writing about the category tend to start the story around 2021, I thought I should write down the version that starts in 2014. I was there for all of it.</p>\n<h2 id=\"2014-rqlite\">2014: rqlite</h2>\n<p>The need was concrete. A clustered system <a href=\"https://philipotoole.com/resume/\" rel=\"nofollow ugc noopener\">I worked on at jut.io</a> needed a small amount of relational storage, and the question of which node should hold it had no good answer. Replicating SQLite with a consensus protocol solved it. We went another way at work, but <a href=\"https://philipotoole.com/tag/rqlite/\" rel=\"nofollow ugc noopener\">I kept building rqlite</a> because the problem was general and the solution was small. The first version used <a href=\"https://github.com/goraft\" rel=\"nofollow ugc noopener\">goraft</a>, the same library <a href=\"https://github.com/influxdata/influxdb\" rel=\"nofollow ugc noopener\">InfluxDB</a> and <a href=\"https://etcd.io/\" rel=\"nofollow ugc noopener\">etcd</a> used at the time (I subsequently joined InfluxDB as a core developer around the same time). In early 2016 I <a href=\"https://github.com/rqlite/rqlite/blob/master/CHANGELOG.md#20-april-5th-2016\" rel=\"nofollow ugc noopener\">replaced it with</a> <a href=\"https://github.com/hashicorp/raft\" rel=\"nofollow ugc noopener\">Hashicorp’s Raft implementation</a> which rqlite still uses.</p>\n<p>The design decision that mattered most was made then and never changed. rqlite is a <a href=\"https://www.scylladb.com/glossary/cap-theorem/\" rel=\"nofollow ugc noopener\">CP system</a>. Writes must go through the leader, a majority must acknowledge, and a partitioned minority refuses writes. Everything else, the <a href=\"https://rqlite.io/docs/api/api/\" rel=\"nofollow ugc noopener\">HTTP API</a>, the <a href=\"https://rqlite.io/docs/api/read-consistency/\" rel=\"nofollow ugc noopener\">read-consistency levels</a>, the <a href=\"https://youtu.be/8XbxQ1Epi5w?t=493\" rel=\"nofollow ugc noopener\">snapshotting</a>, followed from that.</p>\n<h2 id=\"before-2014-and-alongside-it\">Before 2014, and alongside it</h2>\n<p>Two things deserve mention for honesty’s sake. <a href=\"https://www.expensify.com/\" rel=\"nofollow ugc noopener\">Expensify</a> had been replicating SQLite inside its own infrastructure for years with a <a href=\"https://en.wikipedia.org/wiki/Paxos_(computer_science)\" rel=\"nofollow ugc noopener\">Paxos</a>-style protocol; they released it as <a href=\"https://bedrockdb.com/\" rel=\"nofollow ugc noopener\">Bedrock</a> in <a href=\"https://dbdb.io/db/bedrock\" rel=\"nofollow ugc noopener\">2016</a>. And ActorDB, an Erlang system that gave each “actor” its own SQLite database replicated by Raft, <a href=\"https://dbdb.io/db/actordb\" rel=\"nofollow ugc noopener\">appeared around the same time as rqlite</a>. Neither was widely adopted outside its origin, but both show the idea was in the air. What rqlite did was make it a standalone, general-purpose, open-source thing anyone could run.</p>\n<h2 id=\"2017-dqlite\">2017: dqlite</h2>\n<p><a href=\"https://canonical.com/\" rel=\"nofollow ugc noopener\">Canonical</a> built <a href=\"https://canonical.com/dqlite\" rel=\"nofollow ugc noopener\">dqlite</a> to get <a href=\"https://canonical.com/lxd\" rel=\"nofollow ugc noopener\">LXD</a> and later MicroK8s an embedded replicated store without running etcd. <a href=\"https://en.wikipedia.org/wiki/Mark_Shuttleworth\" rel=\"nofollow ugc noopener\">Mark Shuttleworth</a> actually called me once, and we talked, hoping that rqlite could be made to work, but it never quite fit. dqlite <a href=\"https://www.reddit.com/r/golang/comments/8a8h8y/dqlite_distributed_sqlite_for_go_applications/\" rel=\"nofollow ugc noopener\">began in Go</a> and was rewritten in C with its own Raft library. It is the project most similar to rqlite in intent, and the main difference is of one of packaging: dqlite is a library you embed, rqlite is a server you run. Canonical’s need was a database inside their products: mine was a database beside anyone’s product.</p>\n<h2 id=\"2021-litestream-and-a-change-of-approach\">2021: Litestream, and a change of approach</h2>\n<p><a href=\"https://github.com/benbjohnson\" rel=\"nofollow ugc noopener\">Ben Johnson</a> (whom I worked with at InfluxDB) released <a href=\"https://github.com/benbjohnson/litestream\" rel=\"nofollow ugc noopener\">Litestream</a> in <a href=\"https://litestream.io/blog/why-i-built-litestream/\" rel=\"nofollow ugc noopener\">early 2021</a>. Litestream does not use consensus at all. It watches the SQLite <a href=\"https://www.sqlite.org/wal.html\" rel=\"nofollow ugc noopener\">WAL</a> and streams it to <a href=\"https://aws.amazon.com/s3/\" rel=\"nofollow ugc noopener\">S3</a>, giving you disaster recovery for a single-node SQLite database at almost no cost. Ben’s argument was that most applications do not need a cluster; they use one machine and need a way to recover if it dies. He was right about a great many applications, and the “SQLite is enough” movement of the next few years, with blog posts and conference talks, owes a lot to that argument.</p>\n<p>Litestream and rqlite answer different questions. Litestream: what if the machine dies? rqlite: what if the machine dies and I cannot wait to restore? The first question is more common, the second is the one people have when they come to rqlite.</p>\n<p><a href=\"https://fly.io/\" rel=\"nofollow ugc noopener\">Fly.io</a> hired Ben in 2022 and shipped <a href=\"https://docs.fly.io/litefs\" rel=\"nofollow ugc noopener\">LiteFS</a>, which replicates SQLite at filesystem level with leases from <a href=\"https://developer.hashicorp.com/consul\" rel=\"nofollow ugc noopener\">Consul</a>. It was the first attempt to make replicated SQLite a platform feature rather than a thing you deploy. And in a final twist, Litestream <a href=\"https://philipotoole.com/rqlite-8-0-large-dataset-support-and-core-feature-upgrades/\" rel=\"nofollow ugc noopener\">inspired</a> rqlite’s v8.0 approach to handling the SQLite WAL.</p>\n<h2 id=\"2022-forks-and-extensions\">2022: forks and extensions</h2>\n<p>Two projects in 2022 took approaches that neither rqlite nor Litestream had. <a href=\"https://github.com/vlcn-io/cr-sqlite\" rel=\"nofollow ugc noopener\">cr-sqlite</a> added <a href=\"https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type\" rel=\"nofollow ugc noopener\">CRDTs</a> to SQLite as an extension, so that multiple writers could diverge and merge without a leader. That is the AP corner of the design space, and it suits local-first applications where rqlite’s CP guarantees would be a hindrance.</p>\n<p><a href=\"https://github.com/tursodatabase/libsql\" rel=\"nofollow ugc noopener\">libSQL</a> forked SQLite itself. ChiselStrike, later <a href=\"https://turso.tech/\" rel=\"nofollow ugc noopener\">Turso</a>, wanted to change things inside the engine that the SQLite project, which does not accept outside contributions, and would not change. On top of the fork they built a hosted service with replicas at the edge. Turso raised venture money on that, and in 2026 <a href=\"https://turso.tech/blog/turso-is-joining-supabase\" rel=\"nofollow ugc noopener\">Supabase acquired them</a>.</p>\n<p>Around the same time, <a href=\"https://www.sqlite.ai/cloud\" rel=\"nofollow ugc noopener\">SQLite Cloud</a> appeared, offering hosted SQLite replicated with Raft. It is the project closest to rqlite’s original design, wrapped in a cloud service.</p>\n<h2 id=\"2022-onward-the-platforms\">2022 onward: the platforms</h2>\n<p><a href=\"https://www.cloudflare.com/\" rel=\"nofollow ugc noopener\">Cloudflare</a> announced <a href=\"https://developers.cloudflare.com/d1/\" rel=\"nofollow ugc noopener\">D1</a> in 2022, SQLite as a serverless database inside their edge network, and later put SQLite storage inside <a href=\"https://developers.cloudflare.com/durable-objects/concepts/what-are-durable-objects/\" rel=\"nofollow ugc noopener\">Durable Objects</a>. This is replicated SQLite as a managed product from a company that does not need to tell you how it works. Turso’s service is the same shape. The category had gone from “a thing you run” to “a thing you buy.”</p>\n<h2 id=\"what-the-twelve-years-show\">What the twelve years show</h2>\n<p>Three things, I think.</p>\n<p>The core was right. SQLite as a storage engine, with replication added on the outside, has been reinvented by at least eight teams with different needs and different protocols. Nobody has found a reason to stop doing it.</p>\n<p>The design space has three corners, and they appeared in order. Consensus first (rqlite, dqlite): one leader, strong consistency, a cluster. Streaming second (Litestream): one writer, cheap recovery, no cluster. Merge third (cr-sqlite, and parts of the local-first movement): many writers, eventual consistency. Each is correct for a different question, and most of the arguments are arguments between their users about which question is being asked.</p>\n<p>And the money went to the platforms. rqlite, dqlite, and Litestream are open source and free. The projects that raised the capital or got acquired are the ones that turned replicated SQLite into a service with a bill. That is the usual fate of infrastructure ideas, and I do not mind it. But it is worth recording that the idea was open source for eight years before anyone sold it.</p>\n<p><a href=\"https://rqlite.io/\" rel=\"nofollow ugc noopener\">rqlite</a> is still here. It does the same thing it did in 2014, a good deal better, and it is still the thing you reach for when you want a fault-tolerant relational database you can run yourself, understand fully, and not pay anyone for. Twelve years in, I am content with that position in the story.</p>","headings":[{"level":1,"text":"Twelve years of distributed SQLite","id":"twelve-years-of-distributed-sqlite"},{"level":2,"text":"2014: rqlite","id":"2014-rqlite"},{"level":2,"text":"Before 2014, and alongside it","id":"before-2014-and-alongside-it"},{"level":2,"text":"2017: dqlite","id":"2017-dqlite"},{"level":2,"text":"2021: Litestream, and a change of approach","id":"2021-litestream-and-a-change-of-approach"},{"level":2,"text":"2022: forks and extensions","id":"2022-forks-and-extensions"},{"level":2,"text":"2022 onward: the platforms","id":"2022-onward-the-platforms"},{"level":2,"text":"What the twelve years show","id":"what-the-twelve-years-show"}]}}