Twelve years of distributed SQLite
philipotoole.com
philipotoole.com
> I'll let you in on a sort of dirty secret: It's almost always better to use Durable Objects storage, rather than D1. Even if you only want a single global database, it's better to implement that as a singleton Durable Object, than by using D1. Because that's all D1 itself actually is: a singleton Durable Object that exposes an API to its SQLite database. It's just a wrapper.
I'm able to handle around 200k/s on a sub $100 box. https://github.com/pairshaped/gleam_sqlite_benchmarks/blob/m...
IMHO support for transactions is a pretty important dividing line. Some engines support full SQLite transactions while others - like rqlite - don't officially support BEGIN/COMMIT [0], which matters if you rely on multi-statement transactions.
A friend/colleague has been building a pure-Python client for dqlite [1] (DB-API and SQLAlchemy), which may interest folks here. dqlite has full support for transactions, and like rqlite doesn't have external dependencies (ie no S3/Consul).
No knock on rqlite or any other engine - dqlite has warts too [2].
[0] https://rqlite.io/docs/faq/#does-rqlite-support-transactions
[1] https://github.com/letsdiscodev/python-dqlite-dbapi
[2] https://github.com/canonical/dqlite/issues/882 opened by my friend, https://github.com/canonical/dqlite/issues/908 , https://github.com/canonical/dqlite/issues/912 opened by me
I fully expected the article to get into D1 shortly and mention how that's about the same relationship between Cloudflare Durable Objects (which D1 is based on) and celld, an open source reimplementation of Cloudflare Durable Objects which writes to S3. But then the article treats D1 with a very sudden snarky disinterest, and then the final section feels very awkwardly defensive of rqlite and defeatist.
# 2014: rqlite
The need was concrete.
# Before 2014, and alongside it
Two things deserve mention for honesty’s sake.
(the above line is extremely typical of Claude Opus 4.8 and 5.0) [...] and the main difference is of one of packaging:
# What the twelve years show
Three things, I think.
The core was right. [...] Nobody has found a reason to stop doing it.
The design space has three corners, and they appeared in order.
(What order? The corners of this design space, which aren't spelled out until the following sentence, don't have any other natural ordering. This type of misapplied flourish feels very typical of LLMs.)- embeddable like sqlite
- clustered like dqlite
- has a standalone node like rqlite
- can be backed up to S3 like litesteeam
- optionally AP like cr-sqlite alongside CP
it is great, fun, easy.
Are you still going to use dqlite after this experience, or has it shaken your confidence in it? Also what’s been your experience with microk8s itself - I hadn’t heard of it before
He's right that histories start too late, and I'd like to see more posts like this that trace the history back further than the last 5 years. Like for databases, a lot can go back 20+ years and it's good to read how the idea came about (independently from many people), how it developed over time and why.
My understanding is that rqlite gives you "stored in more than place" guarantees, which is nice if you need it. Much slower than a 1 node db though.
Just came here to say two things:
- rqlite is amazing and warmly recommend - Philip is an exceptionally dedicated, kind, and helpful maintainer
5 stars, no notes. Thank you Philip, I'm eternally grateful for all your great work.
Full report here: https://github.com/pairshaped/gleam_sqlite_benchmarks/blob/m...
Obviously real world queries will vary, but I tried to be representative of the type of queries / updates I am sending.
Because if it hasn't, it's likely there are problems lurking.
The rqlite docs however tell you to never use Strong mode and that Linearizable is sufficient. https://rqlite.io/docs/api/read-consistency/#strong
https://philipotoole.com/faster-reads-same-guarantees-linear...