sqliterg (CURL)
20,000 / 2,500 / 237
For those wondering about write performance...its poor except for direct SQLite. If you're write heavy, look elsewhere, or use SQLite directly (preferably with multiple databases and WAL2).
INSERT INTO users (id) VALUES (..); per second ( 1x / 10x / 100x )
SQLite WAL
11,000 / 3,000 / 300
SQLite WAL2
14,500 / 3,000 / 760
SQLite WAL2 (3x Database files)
29,000 / 6,000 / 1,400
sqliterg (CURL)
1,750 / 181 / blocks indefinitely
Keep in mind that PocketBase do a lot more than just executing a raw DB query. We perform data validation, normalization, serialization, enriching, auto fail-retry to handle additional SQLITE_BUSY errors, etc. All of this comes with some cost and will always have an effect when doing microbenchmarks like this.
The performance would also depend on what version of PocketBase did you try (before or after v0.10), whether you used CGO or the pure Go driver, etc.
For a benchmark closer to "real world" scenarios tested on various servers you can check the results from https://github.com/pocketbase/benchmarks.
There is definitely room for improvements (I haven't done any detailed profiling yet) but the current performance is "good enough" for the purposes the applications PocketBase is intended for (I've shared some numbers regarding a PocketBase app on production in https://github.com/pocketbase/pocketbase/discussions/4254).
Hope the above helps.
Or, not every project need the absolute best performance, sometimes good enough is simply good enough?
If I have an SPA querying a moderately-sized static dataset, then something like this is appealing. I can stand up a container on Fly, store the SQLite DB on the volume, and serve directly from there without needing to worry about # of reads I involve (w/ something like Turso) or all the ops complexity of a real DB.
Perhaps it's because I'm particularly snarky pre-morning coffee, but this doesn't come across as the welcoming attitude open source is supposed to be and comes across as downright entitled. Especially as the first thing to lead with. Maybe you didn't quite mean it that way?
I'm taking a wild guess to say that you don't have a screaming need to run 'SELECT * FROM user LIMIT 1;' tens of thousands of times per second on SQLite.
And if you did, I'm guessing you prob would be able to write your own API in front of it.
Am I wrong here?
Kudos to the authors of this tool. It looks great and I'd love to try it out on a recent project.
How far you can vertically scale on one server before requiring a split or shard in your data is why it's a big deal.
A) App servers are easy to scale (stateless, add hardware).
B) Database servers are hard to scale (requires changing logic).
If you're immediately hitting B) you're probably screwed.
Plenty of these SQLite web front ends exist, including more enticing single static binaries in go, and they are always far too slow to use in anything but toy projects.
Should be standard to bench against a standard SQLite integration (on modern cpu with nvme).
Even PocketBase, for as nice as the UI is, an order of magnitude slower than SQLite directly.
Here's some rough numbers I've found using SELECT * FROM user LIMIT 1; per second ( 1x / 10x / 100x )
SQLite
68,000 / 50,000 / 4,000
SQLite WAL2 (3x Database files)
67,000 / 52,000 / 8,000
Pocketbase (CURL)
15,000 / 2,300 / 234
Pocketbase (Direct)
62,000 / 29,000 / 3,900
ws4sqlite (CURL)
20,000 / 2,600 / 255