Get the top HN stories in your inbox every day.
slashdev
otoolep
I agree -- this blog post is light on details. To me the value Cloudflare believes they are offering is mostly ease-of-use, particularly setup. With minimal work you can have a stateful, relational store available to your code. But in terms of actual database functionality, they are not offering anything particularly novel. Of course, I might be missing something.
In fact, I don't see anything D1 is doing that is not already offered by something like rqlite[1], which is also a super-easy-to-use distributed database built on SQLite. Of course Cloudflare will run the database for you, which is a great help -- they take care of the uptime, monitoring, backups, etc. And that's important obviously, because in the real-world databases must be operated.
Disclaimer: I am the creator of rqlite.
rad_gruchalski
I’ve been looking at rqlite for some time and it’s really great to track the product on github.
I believe that the power of what Cloudflare offers here isn’t in the actual database. It’s the packaging and how it sits in their serverless world. Even with rqlite, I still need ip addresses to run a resilient system. As someone who sometimes needs a table here snd there, I really, really don’t want a server. I want a table to store a thousand records in and that’s it. This is where I would very much enjoy using something like D1.
A combo of D1, R2 and Workers is a serious contender for over-the-top serverless distributed apps. This is great.
CRConrad
> It’s the packaging and how it sits in their serverless world. [...] As someone who sometimes needs a table here snd there, I really, really don’t want a server. I want a table to store a thousand records in and that’s it.
Sorry, but I don't get it -- WTF does "serverless" even mean here?
I mean, sorry for jumping on your comment specifically, I know that wasn't primarily what you were talking about here, but... You seem to know what you're talking about, effortlessly encompassing "their serverless world" etc.
The article even mentions that <<SQLite was so ahead of its time, it dubbed itself “serverless” before the term gained connotation with cloud services, and originally meant literally “not involving a server”.>> That makes sense to me; "serverless" means "not having a server". So then you have a local DB; be it SQLite or a DBF or Paradox or MS Access file or whatever. Or even a local DB software "service"; Firebird or MySQL or what have you.
But the term, as it's been bandied about online for the last decade(?) or so (including in this article), seems to pretty obviously actually be about... Remote servers (that's what it talks about replicating between, right?). So what's "serverless" about that???
I've been wondering for a good while now. Anyone who has a short explanation, or link to such, please jump in and enlighten me.
(Otherwise I'll have to conclude it's like "the Cloud", a.k.a. "Someone else's computer". "Serverless" = Someone else's server? :-)
[Edit: Typo.] [Edit: Sigh... Two of them.]
sebk
Small nitpick, but that's still consistent as in ACID. I think what you mean is it wouldn't be consistent in the CAP sense (it wouldn't be linearizable).
TFA does say that read-replicas will be present at every edge location, which makes sense for a product like Workers. But it doesn't mention writes at all.
eloff
Yes, that's true.
dragonwriter
> I'm guessing this is a single master database with multiple read replicas. That means it's not consistent
Single master with read replicas is fully consistent if commits don't return until propagated to and acknowledged by replicas (the expense here being commit latency.)
otoolep
You've basically described rqlite [1], which uses Raft to coordinate the changes to the Leader, and then across some number of Followers. The write won't be acked until a quorum has persisted the change, and committed to the underlying SQLite database.
Disclaimer: I am the creator of rqlite.
otoolep
rqlite also supports read-only nodes, so in theory you can have more nodes at the edge, just like D1 -- but these nodes won't participate in the distributed consensus process. Those nodes will keep up-to-date with changes, even catching up in the event of a temporary disconnection.
eloff
I would say the expense is both latency and availability because if one node doesn't ack within the timeframe then you have to drop it from the cluster. Requests that go there would need to be routed elsewhere to avoid being unavailable. If there's a network partition preventing that, then you have partial downtime. If enough nodes fail then you have full downtime across the whole cluster.
ithrow
Yeah, nothing about WAL mode which is what most users will want for web apps.
sqlite is accessed via a socket? defeats the whole purpose of using sqlite.
Many here are mentioning using one sqlite file per customer but that sounds like a nightmare for migrations and analytics.
SQLite is great and all these new services and articles are nice but intentionally shadowing lots of complexity.
detroitcoder
Going to be very interesting to see how they glue together R2, edge workers and sqllite. They can manage replication using R2 and make the sqllite process aware of this for eventual consistency. Having edge compute with edge data on a globally consistent data model is the dream.
kurinikku
wow SQLite getting a lot of love these days
https://tailscale.com/blog/database-for-2022
peterhunt
SQLite is great but it's way overhyped and abused on HN. People are very eager to turn SQLite into a durable, distributed database and it's really not meant for that, and by going down that road instead of using something like MySQL or Postgres you're missing out on lots of important functionality and tooling.
I only say this because I have made this mistake at my previous startup. We built these really cool distributed databases on top of a similar storage engine (RocksDB) plus Kafka, but it ended up being more trouble than it was worth. We should have just used a battle-tested relational database instead.
Using SQLite for these applications is really fun, and it seems like a good idea on paper. But in practice I just don't think it's worth it. YMMV though.
manigandham
So you didn't use SQLite then? Because RocksDB + Kafka is not similar at all.
Also databases all use the same fundamental primitives and it's up to you to choose the level of abstraction you need. For example, FoundationDB is a durable distributed database that uses SQLite underneath as the storage layer but exposes an ordered key/value API, but then allows you to build your own relational DB on top.
If you just needed distributed SQL because a single instance wasn't enough then there are already plenty of choices like CockroachDB/Yugabyte/TiDB/Memsql/etc that can serve the purpose instead of building your own.
peterhunt
It's actually quite similar. Both are embedded storage engines that are designed for a single node.
Actually, the case for RocksDB for backing a distributed data store is probably much stronger than SQLite given that it supports multiple concurrent writers.
SQLite lacks many important characteristics that one would expect a distributed data store to have. Row level locking is one obvious feature that's super important in a highly concurrent context (as mentioned, RocksDB has this). Want to backup your production DB? You're going to need to block all writes until the backup completes.
Additionally, features like profiling and replication are nonexistent or immature with SQLite. Rqlite and Litestream are super new relative to tools like Postgres and MySQL and you can't find a lot of people that know how to run them.
Also, you can't autoscale your app since your processes are now highly stateful. Sure, this is a problem with MySQL/Postgres too, but I can pay AWS or Google Cloud for a managed version that will abstract this problem away from me.
Most of these problems are solvable with enough net new software on top of SQLite. But... why? I think the only reason you'd subject yourself to such an architecture is because you want to learn (great!) or you're gunning for that next promotion and need to show off your system design skills :P
ignoramous
> So you didn't use SQLite then? Because RocksDB + Kafka is not similar at all.
To me, I could make the connection in the sense that just like sqlite, rocksdb is an embedded store, while Kafka can be used to build a replicated log (log device).
> If you just needed distributed SQL because a single instance wasn't enough then there are already plenty of choices...
Well, that was GP's point, too? In addition, they mention that existing DBMS like Postgres have way more breath and depth than a replicated sqlite can ever hope to have (which isn't really a controversial assertion at all, tbh).
samatman
I accept that you learned a lot about the limits of combining RockDB with Kafka, especially in the exact way you combined them.
This might have limited utility if the goal were to combine RocksDB with something else. And even less for SQLite and something else.
The big push of interest in SQLite serverside isn't driven by people who have never set up pgbounce, but rather by developers who have both read the SQLite docs very carefully and have used the library extensively, and know what it's good for.
ripley12
I'm not sure why you concluded that SQLite is the problem when you built a "really cool distributed database" with Kafka. Distributed databases are complicated, Kafka's complicated.
If you're saying that a replicated Postgres setup would be simpler than what you're built, I agree; but SQLite+Litestream probably would be too.
petre
Litestream is too much work if you're not using S3: replication over sftp. Even fossil has nicer no nonsense replication done over http/s. It's way easier to set up mysql with replication than manage unix accounts and public keys.
MuffinFlavored
Is this any good? https://github.com/rqlite/rqlite
I've been looking for a turn key solution that is better than me running a single node Postgres instance "bare metal" or in a container.
postgres-operator seems cool but... k8s, pretty heavy I guess.
undefined
jen20
It’s the default storage engine for FoundationDB - not sure many would agree that isn’t a “durable, distributed database”.
peterhunt
For one thing, they're ripping it out because of its poor write parallelism https://youtu.be/nlus1Z7TVTI?t=271
But that's orthogonal to my point. As a user of FoundationDB, you're not programming directly against SQLite, so you aren't going to run into these issues as much since FoundationDB exposes different semantics and coordinates concurrency across many SQLite instances in parallel.
I think it's best to think of SQLite as a replacement for your filesystem, rather than a replacement for your relational DBMS.
jgrahamc
SQLite has been cool forever. It was the underlying data store for my machine learning email filter POPFile 20 years ago!
https://en.wikipedia.org/wiki/POPFile https://getpopfile.org/browser/trunk/engine/POPFile/Database...
runlevel1
It's high-quality software too. It's well-commented and exceptionally well tested.[^1][^2]
> As of version 3.33.0 (2020-08-14), the SQLite library consists of approximately 143.4 KSLOC of C code. ... By comparison, the project has 640 times as much test code and test scripts - 91911.0 KSLOC.
I don't usually place much stock in those sort of counts, but 640x is notable.
It makes sense considering the wide variety of use-cases, from embedded devices to edge computing and everything in between.
[1]: https://www.sqlite.org/testing.html [2]: https://sqlite.org/src/dir?ci=trunk
sigzero
I used POPFile!! It was awesome.
alberth
SQLite was originally great for desktop applications.
Problem is, there's still a huge market for these apps but everything has moved to the web (no one is making desktop apps anymore). So having a full-blown RDMS is overkill for these kind of app, and now SQLite is starting to fill these web app needs.
@sqlite - if you are reading this, any word on merging WAL2 and BEGIN CONCURRENT into main? There clearly is a new class of needs to do so in this world that has completely moved over to web app development (which introduces concurrency problems never experienced on desktop). Any thoughts of focusing more on these web related needs for SQLite (or maybe even fork your own code base to have a more enhanced SQLite version targeted at web needs)?
jchw
I think it’s long overdue. While SQLite certainly has its limitations, it’s a winner in many categories. Even for sites with mild traffic using ordinary SQLite in PHP like a decade ago, it was always nice to use for its simplicity and the performance was totally acceptable. In comparison, the memory usage of typical relational database servers was high enough to make it hard to fit on a single lowend VPS with the same data and traffic. (I found myself tuning MySQL, but I never needed to tune SQLite.)
Cthulhu_
The main thing for tuning SQLite will be how to open it, e.g. in write-ahead mode, to turn on foreign keys (this needs to be enabled manually), and whether it should wait to get a database lock on slower hardware before giving up. There's also some gotchas like if you mark an ID column as primary key, it'll use the rowid as key - which can be reused if a row is removed. So you need to explicitly set primary key AND autoincrement, else you're going to have a bad time. (https://www.sqlite.org/autoinc.html)
gigatexal
If you define a table with an integer primary key you get autoincrement as default at least in newer versions.
RaoulP
With the mileage (and attention) those new products are getting out of using SQLite, I think Richard Hipp deserves a lot more acknowledgement for creating such an amazing piece of software.
sophacles
New products getting a lot of mileage out of sqlite is old-hat at this point. It one of those rare evergreen techs - pay attention for a while and this latest round of attention will die down for 6-12 months then someone else will start another round of "look how cool sqlite is".
At least that's been my observation since I started coming around here.
tootie
I'm wondering if we'll see some similar energy around non-sql embedded databases like leveldb or rocksdb
sanderjd
Right! SQLite is great, but those two are great as well. It seems like the energy should be around "hey, you should consider a local, maybe even in-memory, database for some things!" more so than specifically "SQLite is great" (though it is).
Thaxll
Well I don't think it's a good fit for regular service, exactly how do you handle 2 replicas of the same service talking to the same DB?
The fact that it's just a file on disk limits the usage.
nibab
Projects such as litestream and rqlite have this figured out.
otoolep
rqlite author here, happy to answer any questions.
Thaxll
Mutliple writer on the same SQLLite?
manigandham
Transactions, locks, queues, etc. No different than multiple app instances changing the same row in other databases.
Any state mutation is ultimately ordered in time and how that that ordering is accomplished depends on the abstractions you're using: in your app, network layer, database, etc.
Thaxll
Why would you use SQLlite once you start dealing with network, just use MySQl or PG.
It's just re-inventing the wheel badly, I need to read the details but basically you're using a tool SQLLite that was not designed to be used outside of a single app use case.
mbreese
Is think one way to think about this is to have one database being tied to one replica (replicas could handle more than one database). Where (importantly) the idea would be one database for each user. You horizontally scale for the number of users, but each user is only using one end node.
It’s interesting because you have to consider how to scale your database as well as your application. The fact that you don’t have one central database opens up more possibilities. But it doesn’t work for all instances (such as a shared read-write data source for all users). For example, this approach wouldn’t work for something like Twitter (at least the original architecture).
jgrahamc
BTW R2 is open beta now: https://blog.cloudflare.com/r2-open-beta/
mariushn
R2 is 3x more expensive than B2 (storage) https://www.backblaze.com/b2/cloud-storage-pricing.html
Am I missing something? Is there no bandwidth cost at all?
messe
Yep, you're not charged for egress.
einichi
B2 to Cloudflare also does not incur egress fees: https://www.backblaze.com/blog/backblaze-and-cloudflare-part...
Backblaze B2 customers will be able to download data stored in B2 to Cloudflare for zero transfer fees. This happens automatically once Cloudflare is configured to distribute your B2 files.
alberth
Does R2 provide synching between regions? Maybe that's why it's so much more expensive? You're getting regional failover?
archon810
Presumably under the hood it'll be nicely distributed, as per https://blog.cloudflare.com/introducing-r2-object-storage/.
"Our vision for R2 includes multi-region storage that automatically replicates objects to the locations they’re frequently requested from."
rubenv
Latency
losvedir
Wow, this looks potentially very interesting. Since this is sort of fresh in my mind from the recent Fly post about it:
* How exactly is the read replication implemented? Is it using litestream behind the scenes to stream the WAL somewhere? How do the readers keep up? Last I saw you just had to poll it, but that could be computationally expensive depending on the size of the data (since I thought you had to download the whole DB), and could potentially introduce a bit of latency in propagation. Any idea what the metrics are for latency in propagation?
* How are writes handled? Does it do the Fly thing about sending all requests to one worker?
I don't quite know what a "worker" is but I'm assuming it's kind of like a Lambda? If you have it replicated around the world, is that one worker all running the same code, and Cloudflare somehow manages the SQL replicating and write forwarding? Or would those all be separate workers?
hn_ei_ser_23
First, I'm very excited. Sure, SQLite has some limitations compared to Postgres, esp. regarding the type system and concurrency. But we get ACID compliance and SQL.
But it is really hard getting some useful information from this article. I can't even tell if it is not there or just buried in all this marketing hot air.
So, what is it really? Is there one Write-Master that is asynchronously replicated to all other locations? Will writes be forwarded to this master and then replicated back?
I'm very curious about how it performs in real life. Especially considering the locking behavior (SQLite has always the isolation level 'serializable' iirc). The more you put in a transaction or the longer you have to wait for another process to finish their writes, the more likely you have to deal with stale data.
But overall I'm very excited. Also by the fly.io announcement, of course. Lots of innovation and competition. Good times for customers.
tyingq
>So, what is it really? Is there one Write-Master that is asynchronously replicated to all other locations? Will writes be forwarded to this master and then replicated back?
Not a lot of detail, but that is mentioned:
"But we're going further. With D1, it will be possible to define a chunk of your Worker code that runs directly next to the database, giving you total control and maximum performance—each request first hits your Worker near your users, but depending on the operation, can hand off to another Worker deployed alongside a replica or your primary D1 instance to complete its work."
infogulch
Very cool! Glad to see all the love for SQLite recently.
One thing I've noticed that many commenters miss about read-replicated SQLite is assuming that the only valid model is having one, giant, centralized database with all the data. Lets be honest with ourselves, the vast majority of applications hold personal or B2B data and don't need centralized transactions, and at scale will use multi-tenant primary keys or manual sharding anyways. For private data, a single SQLite database per user / business will easily satisfy the write load of all but the most gigantic corporations. With this model you have unbounded compute scaling for new users because they very likely don't need online transactions across multiple databases at once.
Some questions:
Will D1 be able to deliver this design of having many thousands of separate databases for a single application? Will this be problematic from a cost perspective?
> since we're building on the redundant storage of Durable Objects, your database can physically move locations as needed
Will D1 be able to easily migrate the "primary" at will? CockroachDB described this as "follow the sun" primary.
unraveller
I guess the first answer is: similar to Durable Object limits (unlimited databases / 50 GB total) since they alluded to those abilities more so than a simple file stored on R2 (only for backups).
fzaninotto
Love the Northwind Traders reference! However, for a demo, I suggest a slightly larger and more complex data set, [data-generator-retail](https://www.npmjs.com/package/data-generator-retail).
The demo is also a bit buggy: orders are duplicated as many times as there are products, but clicking on the various lines of the same order leads to the same record, where the user can only see the first product...
I also think the demo would have more impact if it wasn't read-only (although I understand that this could lead to broken pages if visitors mess up with the data).
Anyway, kudos to the CloudFlare team!
naiv
I was thinking the same. The dataset is way too small.
celso
Fixed the orders table. Good catch.
ranguna
This looks amazing!
I see cloudflare people are on this post, any chance to compar D1 vs postgres in terms of DB features?
Insert ... Returning
Stored procedures and triggers
Etc etc
Would be really helpful to get a comparison like cockroachDB did here https://www.cockroachlabs.com/docs/stable/postgresql-compati...
Or even better, a general sql compatibility matrix like this https://www.cockroachlabs.com/docs/stable/sql-feature-suppor...
Kudos to the cloudflare team!
the_duke
Well, it's sqlite... so presumably you will get most of the capabilities sqlite has.
RETURNING is covered.
Stored procedures are indirectly there by running your own code "next to the database", as mentioned in the post. Which is arguably much nicer than having to use some database specific language, given that you can run WASM on workers.
tyingq
There is a layer on top of Sqlite here, so I imagine it's something less than all the capabilities sqlite has, at least initially. Plus the upsides and downsides from their approach to have a master and read replicas.
ranguna
Yes was thinking the same. Nice to see some people here actually understood the question, thank you.
ranguna
> Stored procedures are indirectly there by running your own code "next to the database",
"indirectly" is a keyword here, because running code when data is modified potentially won't replace triggers since they'll probably execute outside the running transaction.
pier25
Listen/notify
Cthulhu_
The announcement - if you read it before posting - says it's sqlite, so that's something you can punch into google.
Long story short, don't expect anything fancy. Support for alter table is limited, and concurrency can be an issue.
ranguna
It is indeed sqlite but it could possibly have modification done or additions added. Please be considerate and think a little more before commenting.
the_duke
All this recent hype around sqlite...
sqlite is a great embedded database and thanks to use by browsers and on mobile the most used database in the world by orders of magnitude.
But it also comes with lots of limitations.
* there is no type safety, unless you run with the new strict mode, which comes with some significant drawbacks (eg limited to the handful of primitive types)
* very narrow set of column types and overall functionality in general
* the big one for me: limited migration support, requiring quite a lot of ceremony for common tasks (eg rewriting a whole table and swapping it out)
These approaches (like fly.io s) with read replication also (apparently?) seem to throw away read after write consistency. Which might be fine for certain use cases and even desirable for resilience, but can impact application design quite a lot.
With sqlite you have do to a lot more in your own code because the database gives you fewer tools. Which is usually fine because most usage is "single writer, single or a few local readers". Moving that to a distributed setting with multiple deployed versions of code is not without difficulty.
This seems to be mitigated/solved here though by the ability to run worker code "next to the database".
I'm somewhat surprised they went this route. It probably makes sense given the constraints of Cloudflares architecture and the complexity of running a more advanced globally distributed database.
On the upside: hopefully this usage in domains that are somewhat unusual can lead to funding for more upstream sqlite features.
prirun
* the big one for me: very limited migration support, requiring quite a lot of ceremony for common tasks (eg rewriting a whole table and swapping it out)
I don't know where this idea of having to swap a whole table in SQLite came from, but it simply isn't true. Over the last 13 years I have upgraded production HashBackup databases at customer sites a total of 35 times without rewriting and swapping out tables by using the ALTER statement, just like other databases:
https://www.sqlite.org/lang_altertable.html
For the most recent upgrade, I upgraded to strict tables, which I could also have done without a rebuild/swap. I chose to do a rebuild/swap this one time because I wanted to reorder some columns. Why? Because columns stored with default or null values don't have row space allocated if the column is at the end of the row.
the_duke
For a long time sqlite did not have DROP COLUMN and RENAME COLUMN support, which are both pretty essential.
I'm embarrassed to admit that I didn't realize RENAME COLUMN was actually added in 3.25, almost four years ago.
DROP COLUMN was only just added last year in 3.35.
I'm surprised a database schema lasted 9/12 years without ever renaming or dropping a column.
This changes things! But even now, ALTER TABLE is not transactional. So especially with many concurrent readers there can definitely be situations where you'd still want to rewrite.
teraflop
I'm not sure what you mean by "not transactional". SQLite implements transaction support at the "page" level, and builds all other database operations on top of it, which means anything that touches the bytes of the database file is transaction-safe. You can verify this for yourself:
sqlite> CREATE TABLE foo(a,b,c);
sqlite> INSERT INTO foo VALUES (1,2,3);
sqlite> BEGIN;
sqlite> ALTER TABLE foo DROP COLUMN b;
sqlite> SELECT * FROM foo;
1|3
sqlite> ROLLBACK;
sqlite> SELECT * FROM foo;
1|2|3
It's of course still subject to SQLite's normal restrictions on locking, which means a long-running ALTER statement will block concurrent writers (and probably also concurrent readers if you're not running in WAL mode).prirun
> I'm surprised a database schema lasted 9/12 years without ever renaming or dropping a column.
I did have a couple of columns that were no longer needed and would have dropped them, but instead I just set them to null and ignored them. Nulls only take 1 byte of space in a row. I dropped them when DROP COLUMN was added.
cryptonector
It would really help if SQLite3 had a `MERGE`, or, failing that, `FULL OUTER JOIN`. In fact, I want it to have `FULL OUTER JOIN` even if it gains a `MERGE`.
`FULL OUTER JOIN` is the secret to diff'ing table sources. `MERGE` is just a diff operation + insert/update/delete statements to make the target table more like the source one (or even completely like the source one).
`FULL OUTER JOIN` is essential to implementing `MERGE`. Granted, one could implement `MERGE` without implementing `FULL OUTER JOIN` as a public feature, but that seems silly.
Sadly, the SQLite3 dev team specifically says they will not implement `FULL OUTER JOIN`[0].
Implementing `MERGE`-like updates without `FULL OUTER JOIN` is possible (using two `LEFT OUTER JOIN`s), but it's an O(N log N) operation instead of O(N).
The lack of `FULL OUTER JOIN` is a serious flaw in SQLite3. IMO.
[0] https://www.sqlite.org/omitted.htmlSQLite
RIGHT and FULL JOIN are on the trunk branch of SQLite and will (very likely) appear in the next release. Please grab a copy of the latest pre-release snapshot of SQLite (https://sqlite.org/download.html) and try out the new RIGHT/FULL JOIN support. Report any problems on the forum, or directly to me at drh at sqlite dot org.
sorenbs
Migrations have gotten better recently, but there are still cases where you need to follow the 12 steps very carefully: https://www.sqlite.org/lang_altertable.html#otheralter
Prisma Migrate can automatically generate these steps, removing most of the pain. I'm sure other migration tools can do this as well.
llimllib
simonw's sqlite-utils can help here too: https://sqlite-utils.datasette.io/en/stable/cli.html#transfo...
vlovich123
D1 does not throw away consistency. It’s built on top of Durable Objects which is globally strongly consistent.
smarx007
"D1 will create read-only clones of your data, close to where your users are, and constantly keep them up-to-date with changes."
Sounds like there will be no synchronous replication and instead there will be a background process to "constantly keep [read-only clones] up-to-date". This means that a stale read from an older read replica can occur even after a write transaction has successfully committed on the "primary" used for writes.
So, while the consistency is not "thrown away", it's no longer a strong consistency? Anyway, Kyle from Jepsen will figure it out soon, I guess :)
geelen
Yeah, so you can always opt-in to strong consistency by transferring execution to the primary (see the "Embedded Compute" section of the blog). Then it's pretty much exactly the same as a DO.
greg-m
Just clarifying - D1 without read replicas is strongly consistent. If you add read replicas, those can have replication lag and will not be strongly consistent.
Disclaimer: I work at Cloudflare :)
infogulch
Thanks for the clarification, that is what I would expect.
Does SQLite support some kind of monotonic transaction id that can be used as a cache coherency key? Say a client writes a new record to the database which returns `{"result": "ok", "transaction_id": 123}`, then to ensure that subsequent read requests are coherent they provide a header that checks that the read replica has transaction_id >= 123 and either waits for replication before serving or fails the request. (Perhaps a good use for the embedded worker?)
mwcampbell
Interesting that D1 is built on top of Durable Objects. Does this mean that it would be practical for a single worker to access multiple D1 databases, so it could use, for example, a separate database for each tenant in a B2B SaaS application? Edit: And could each database be in a different primary region?
a-robinson
Yes, exactly!
hn_ei_ser_23
That is interesting. I wish CF would give us some more information as I've assumed that there must be a lack of strong consistency which would be a major drawback.
Edit: But that would mean that durable objects can't be replicated asynchronously? That would mean a big latency hit. Then what's the difference to a central DB in one datacenter?
kwizzt
I’m not familiar with Durable Objects. When D1 does replication to read replicas, if it’s not doing synchronous replication, then it’s not strongly consistent, is that correct?
the_duke
I wish the post had provided some more technical details.
It's more of a "quickstart" than a peek under the hood.
unraveller
I'd like to see some up front D1 & R2 benchmarks (read/write/iops). I can't judge invocation cost value until I can judge my use case performance. Here's hoping its -gt NVMe raid 10 under the hood of D1 as some big SQLite reads suffer under slow storage.
jpcapdevila
Are you guys using litestream or a similar approach? E.g storing WAL frames in a durable object.
vaughan
Has anyone tried to write a new modern SQLite?
sophacles
Why? Yes sqlite doesn't have all the features postgres has. Postgres doesn't have all the features the sqlite has either. What's wrong with having different tools with different sets tradeoffs. It's a different shape of Lego and that's fine - some things call for a 1/3height 2x2 and others call for a full height 1x8.
jpcapdevila
I think the most successful attempt would be Realm.
chrisshroba
DuckDB comes to mind, but I can't speak to its differences from SQLite.
anyfactor
I haven't tried duckdb but I have been googling about it. I think I saw a discussion where it was mentioned that duckdb isn't a replacement for SQLite. It is an OLAP database [0] which makes its ingestion time slower than SQLite, I think. So it is meant for analytics but not as fullfledge replacement for SQLite.
[0]: https://en.wikipedia.org/wiki/Online_analytical_processing
Duckdb on HN: https://news.ycombinator.com/item?id=23287278
gigatexal
DuckDB is Olap SQLite. The vector engine is dope. But most of the innovation is in the OLAP stuff.
undefined
steaminghams
why do you consider sqlite to not be modern?
all the hip service providers seem to be all over it which would indicate pretty good modernity to me at least.
undefined
ngrilly
Not clear from reading the post if the SQLite C library is embedded and linked in the Worker runtime (which would mean no network roundtrip) or if each query or batch of queries is converted to a network request to a server embedding the SQLite C library.
That's important to understand because that's one of the key advantages of SQLite compared to the usual client-server architecture of databases like PostgreSQL or MySQL: https://www.sqlite.org/np1queryprob.html
samwillis
This is really interesting, it's (basing it on SQLite) exactly what I was expecting CloudFlare to do for their first DB.
Its perfect for content type sites that want search and querying.
Anyone from CF here, is it using Litestream (https://litestream.io) for its replication or have you built your own replication system?
I assume this first version is somewhat limited on write performance having a single "main" instance and SQLite laking concurrent writes? It seems to me that using SQLite sessions[0] would be a good way to build an eventually consistent replication system for SQLite, would be perfect for an edge first sql database, maybe D2?
endisneigh
Have any of the problems that led people to use Postgres instead of SQLite actually been solved? Are we doomed to repeat the same mistakes?
Also, any plans to support PATCH x-update-range so SQLite can be used entirely in the browser via SQLite.js?
Can someone enlighten me with the types of use cases this would be better for vs say Postgres?
ignoramous
It isn't as much as folks who need Postgres features are moving to SQLite just because it is cool, but it is folks who don't want those Postgres features moving to SQLite, because the latter has just enough features they only ever really need.
endisneigh
SQLite made sense as an embedded database on day a desktop or phone because there’s only a single person generally writing to it. The perfect use case.
I don’t understand how it will be usable at all in a website with multiple users. Is the idea to make your site to every user gets their own database? How do you stop SQL injection?
Once you solve all of these problems aren’t you better off just using Postgres?
adamckay
> I don’t understand how it will be usable at all in a website with multiple users
With WAL mode enabled the database is locked during writes only, and concurrent writes are queued but you can still perform reads concurrently. If you keep your write transactions small and consider that a lot of apps aren't writing a lot, it can give perfectly good performance for a lot of usecases.
> Is the idea to make your site to every user gets their own database?
You can do... I know of B2B apps that give each billable customer their own database.
> How do you stop SQL injection?
In the exact same way you do in all other flavours of SQL - with parameterized queries.
> Once you solve all of these problems aren’t you better off just using Postgres?
Not necessarily. Postgres gives you a different set of problems and limitations to consider and work around.
nindalf
Which problems were you thinking of?
Cloudflare and fly.io both promise hassle free read replicas and backup. They will both offer only a single node capable of writes, because that’s how SQLite rolls.
This is a pretty good fit for a read heavy load that requires SQL and very low latency.
endisneigh
I guess I’m not understanding what the benefit is vs hosted Postgres. Also low latency and setup can be equally trivial - see supabase for example.
simonw
Biggest benefit over hosted PostgreSQL is that you get SELECT queries that are measured in microseconds, because SQLite avoids needing network overhead per query.
jve
Hope this can give you some concrete answers: https://www.sqlite.org/whentouse.html
hn_ei_ser_23
The important drawback is async replication and therefore the lack of full consistency. On the other hand, this is the big advantage of hosted Postgres and the like.
Those offerings are great for use-cases that don't need that kind of consistency, which are many.
hn_ei_ser_23
No and no. I think this is great for Edge computing, where there is currently no solution. So, it's better than nothing.
It all depends on the use-case, of course. A traditional hosted Postgres or MySQL database or cluster is certainly the go-to solution for all who need advanced features or full consistency, which only synchronous replication could provide.
jve
What problems? Both are for different use cases albeit overlapping.
endisneigh
Concurrent writes, for one.
Get the top HN stories in your inbox every day.
For a Cloudflare article, this one is surprisingly light on technical details. And for the product where it most matters.
I'm guessing this is a single master database with multiple read replicas. That means it's not consistent anymore (the C in ACID). Obviously reads after a write will see stale data until the write propogates.
I'm a bit curious how that replication works. Ship the whole db? Binary diffs of the master? Ship the SQL statements that did the write and reapply them? Lots of performance and other tradeoffs here.
What's the latency like? This likely doesn't run in every edge location. Does the database ship out on the first request. Get cached with an expiry? Does the request itself move to the database instead of running at the edge - like maybe this runs on a select subset of locations?
So many questions, but no details yet.