-
Notifications
You must be signed in to change notification settings - Fork 302
sqlite: better-sqlite3 shouldn't be the default driver (as is), nor be used if more than one sqlite instance or other DBs are also used #1385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
You make a good point. We could expand the sqlite dialect to support both better-sqlite3 and some async alternative. And document the difference clearly. |
Citation needed. Due to said db context mutex you can also starve the nodejs thread pool by issuing a long running query and many small queries afterwards on the same db context. See also
I am unaware of any statistic which could be used to prove that this is indeed the or even a trend. |
The issue here is not about better-sqlite3 query performance.
The approach described is not what we are doing. For reference, the naive approach we used to fixed our issues is the following: async aquireLock() {
while (this.lock) {
await this.lock;
}
this.lock = new Promise(resolve => { this.resolve = resolve; });
}
release() {
if (this.resolve) {
const resolve = this.resolve;
this.resolve = null;
this.lock = null;
resolve();
}
} This way the sqlite thread only handles 1 query at the time and pending queries at kept as promises. Thanks to this:
We also didn't notice any performance penalty in CPU/RAM usage (last CPU spikes in fact) For the approach to be generalizable it would require a way to limit the total number of threads.
FLY.io article on sqlite for single tenant: blog post on the subject by Turso: referencing this DHH post about using sqlite for single-tenant: on the reach side of things, reaction from ThePrimeagen to said article: |
Hey 👋 We also use Turso for db-per-tenant in my team: |
Hi,
As you know better-sqlite3 is the default sqlite drive in Kysely and is synchronous.
The issue with this is that it blocks the full event look during each query.
This make kysely async interface of it quite unorthodox as most Db clients async interfaces are expected to offload query execution outside the event loop.
Also better-sqlite3 is an opinionated client,
as can testify the
When is this library not appropriate?
( https://www.npmjs.com/package/better-sqlite3 ).It isn't meant to be used with many sqlite DBs and combined with async code.
This makes it a poor fit for a default driver of kysely currently.
The consequence here is that it can degrades overall performance of the application and unrelated DBs.
In particular when the project:
etc.
The impact when this occurs can be catastrophic and very hard to find/debug.
For instance in our case it would:
This would then cause
oldest_xoid_transaction_age
to increase,degrading postgres performance and create very weird bugs in completely unrelated projects.
just to mention the main ones.
This also goes against the trend of creating many small isolated sqlite DB (for instance 1 per user).
Reason being that calls to 3 unrelated DBs are done is series currently instead of in parallel.
We found the issue a while back and replace the default drive in one of place where we create temporary sqlite Dbs
by using a custom dialect using the async lib sqlite3 ( https://www.npmjs.com/package/sqlite3 ) with a simple async mutex to prevent concurrent queries.
We thought this would be enough but forgot to migrate another cases where, we thought, it wouldn't be necessary.
After adding a query_timeout to postgresql's pool config of 1min, we discovered it was not so.
We made sure it was the source of the issue
by creating an sqlite extension that adds a function that sleep for 1 min.
Added an interval that logs and ran a query that uses the above extension.
We confirmed this way that better-sqlite queries block the event loop.
We replaced the default driver with our custom one and the before/after speaks for itself:


We just found the
kysely-sqlite-tools
repo that contains ahttps://github.com/subframe7536/kysely-sqlite-tools/tree/master
we are likely to replace our custom driver by this one as it address the issue.
Thanks for your attention
The text was updated successfully, but these errors were encountered: