Live data from Hacker News

Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

github.com

21–30 of 55 posts

Re: Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

#21
post #14

Have you considered using techniques like conditional PUT to enable multiple writers? https://aws.amazon.com/about-aws/whats-new/2024/08/amazon-s3... https://docs.aws.amazon.com/AmazonS3/latest/userguide/condit...

It's funny, I did consider that and put some work into doing it. I moved that work into a different project, https://github.com/russellromney/haqlite that focuses on high-availability SQLite. Like Litestream but focused on embedding in your application. It uses conditional PUTs for leader election, ships WAL to S3, and writes (and reads for consistency) are forwarded to the leader - so it's still single writer, but failover happens automatically when the leader fails to claim the leader lease again. Data window is the lease timeout + checkpoint interval. Maybe I'll explore how to use haqlite + turbolite together.

Short answer: conditional PUTs for distributed scare me for multiwriter. The issue isn't doing the writes, it's ensuring that the writer is writing against the most current data. For OLTP workloads with upserts, this is very hard! If you have immutable data without any upserts and your writes don't depend on reads, that actually works really well. But in any other scenario it's dangerous. The writer needs to ensure that the other writers have checkpointed first, and there's not a great way to do that.

One thing that could make this work in turbolite is a fast distributed lock system with transaction and lock timeouts. E.g. use Redis as the lock lease holder, and distributed writers acquire it, fetch the latest manifest from s3, sync any data they need, do the write, checkpoint, update the lock to be released and note the new manifest version, and return success to the user. then before any reads, they simple check Redis for the new manifest (or S3 for guarantee that the manifest update/lock release didn't fail). All writes have an N second timeout, and the write lock has N second + T timeout, so it's guaranteed that successful checkpoints are used in the next read, as long as readers check the manifest first.

This could work, but it's single writer lol. But you'd only want it with infrequent writes. And reads cost an S3 GET. So I guess it would work best with Wasabi, which doesn't charge for operations, or self-hosted MinIO.

Re: Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

#22
post #15

i wonder how much that costs per hour to run any normal load? what benefit does this have versuss using mysql (or any similar rdbms) for the queries? mysql/pgsql/etc is free remember, so using S3 obviously charges by the request, or am i wrong?

Cost really depends on your workflow, your durability needs, prefetch aggression (how quickly you need all the data locally), and how aggressively you cache. The storage is what it is, and it's cheap. The variation comes in transaction counts.

If you evict the cache on every read/write, then all reads and writes do S3 GET. PUTs are 10-100x more expensive than GETs usually. Check the benchmark/README.md for GET counts, but it's usually 5-50 per cold read (with interior B-tree pages on disk).

S3 GETs are $0.0004/1000, S3 Express is $0.00003. So 10 queries per minute all day long averaging 20 GET operations, with full eviction on each request, would be 20*10*$0.0004*60*24/1000*30 = $3.45 per month. With S3 Express One Zone that's $0.26/mo. Both plus storage costs, which would probably be lower.

On Wasabi, that would be just the cost of storage (but they have minimum 1TB requirements at $6.99/mo).

If you checkpoint after every write and write 10 times per minute, each write hitting e.g. 5 page groups (S3 objects) plus the manifest file, the analysis looks like: 6*10*$0.005*60*24/1000*30=$12.96. Again that's worst case for the benchmark 1.5GB database. On S3 Express that' $2.92.

Point is - it's not too bad, and that's kind of worst-case scenario where you evict on every request every 6 seconds which isn't really realistic. If you evict the cache hourly, that cost goes is 1/600th - less than a $0.01 per month.

Summary: use S3 Express One Zone, don't evict the cache too often, checkpoint to S3 once a minute (turbolite lets you checkpoint either locally (disk-durability) or locally+S3 separately), and you're running a decent workload for pennies every month.

[Apologies for the spreadsheet math in plaintext]

Re: Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

#23
post #13

This is awesome! With all of the projects/teams working on improving sqlite, it feels like it's just a matter of time before it becomes a better default than postgres for serious projects. I do wonder - for projects that do ultimately enforce single writer sqlite setups - it still feels to me as if it would always be better to keep the sqlite db local (and then rsync/stream backups to whatever S3 storage one prefers)…

[flagged]

Couldn't have said it better myself.

Re: Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

#24
post #13

This is awesome! With all of the projects/teams working on improving sqlite, it feels like it's just a matter of time before it becomes a better default than postgres for serious projects. I do wonder - for projects that do ultimately enforce single writer sqlite setups - it still feels to me as if it would always be better to keep the sqlite db local (and then rsync/stream backups to whatever S3 storage one prefers)…

Yeah I mostly agree, and another comment brought up this idea kind of. If you can keep SQLite local, that’s usually the better answer. Local reads are insanely hard to beat, and Litestream is the canonical “keep SQLite local and ship durability elsewhere” model.

That’s actually a big part of why I started another project, haqlite: https://github.com/russellromney/haqlite which is much more on the “keep SQLite local” side: leader election via S3 conditional PUTs, WAL replication to S3, follower catchup, write forwarding to the leader, and graceful leader handoff. So it can get pretty close to zero-downtime deploys with 2+ nodes.

But not true zero downtime on a single server — if there isn’t already another warm follower alive, there is nowhere for leadership to go. So in my head:

- Litestream: local SQLite is primary; object storage is for durability / replication / failover

- haqlite: kind of a Litestream but with a focus on embedding it into any application.

- turbolite: object storage is the actual backing store, and the question is how plausible cold reads can get. No HA ideas

Re: Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

#25

Earlier quoted context omitted.

Very cool, thanks. I hadn’t seen Graft before, but that sounds pretty adjacent in a lot of interesting ways. I looked at the repo and see what I can apply. I've tried out all sorts of optimizations - for free pages, I've considered leaving empty space in each S3 object and serving those as free pages to get efficient writes without shuffling pages too much. My current bias has been to over-store a little if it keeps…

Both of those roadmap items make sense! Excited to see how you evolve this project!

Thanks! I think the hole punching is the key one, as it is important for "this delete has happened but we need to free the space without a vacuum".

Re: Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

#26
post #14

Have you considered using techniques like conditional PUT to enable multiple writers? https://aws.amazon.com/about-aws/whats-new/2024/08/amazon-s3... https://docs.aws.amazon.com/AmazonS3/latest/userguide/condit...

rqlite does this well but it’s still server based

Re: Show HN: Turbolite – a SQLite VFS serving sub-250ms cold JOIN queries from S3

#30
post #13

This is awesome! With all of the projects/teams working on improving sqlite, it feels like it's just a matter of time before it becomes a better default than postgres for serious projects. I do wonder - for projects that do ultimately enforce single writer sqlite setups - it still feels to me as if it would always be better to keep the sqlite db local (and then rsync/stream backups to whatever S3 storage one prefers)…

[flagged]

[flagged]
Post reply on HN