Skip to content

Allow caching prepared statements#150

Merged
simolus3 merged 4 commits into
mainfrom
prepared-statements-cache
Jul 22, 2026
Merged

Allow caching prepared statements#150
simolus3 merged 4 commits into
mainfrom
prepared-statements-cache

Conversation

@simolus3

@simolus3 simolus3 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

This adds the preparedStatementCacheSize option, which is supported both for native (sqlite3_connection_pool) and web (sqlite3_web) databases. For web databases, the statement cache is implemented in Dart and managed by the web worker. For native databases, the cache is implemented in Rust and shared between isolates.

With a cache size of 10 statements, this provides a modest performance improvement compared to not caching any prepared statements:

Benchmark Without cache Cache enabled
Insert: JSON1 11.685 ms 11.575 ms
Insert: Direct 13.620 ms 12.845 ms
Insert: writeTransaction 9.0310 ms 7.7310 ms
Insert: executeBatch in isolate 13.842 ms 14.123 ms
Insert: direct write in isolate 60.972 ms 52.800 ms
Insert: writeTransaction no await 8.6580 ms 7.7120 ms

To be able to release this in a patch release without much risk, this does not enable statement caching by default.

@simolus3
simolus3 force-pushed the prepared-statements-cache branch from 79c8dfa to 5cfd4bd Compare July 21, 2026 15:20
@simolus3
simolus3 force-pushed the prepared-statements-cache branch from 5cfd4bd to ff6a17d Compare July 22, 2026 09:18

@rkistner rkistner left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a configurable cache seems like a good idea.

I think we should explicitly note the potential caveats of the cache in the docs. One that I've seen in the past is that an open statements can block dropping a table or index, such as in this example.

I also noticed the PR description mentions a default cache size of 10, but the code mentions 0 - I assume the latter is the correct default?

@simolus3

simolus3 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

One that I've seen in the past is that an open statements can block dropping a table or index, such as in this example.

It looks like that comment is outdated from powersync-ja/powersync-sqlite-core@c023c89 since we no longer have a prepared statement there, but it's still a good point in general. We call sqlite3_reset() on statements before putting them in the cache which I believe would have fixed the original issue in the core extension too, but it's still something worth pointing out.

I also noticed the PR description mentions a default cache size of 10, but the code mentions 0 - I assume the latter is the correct default?

Yes, I initially added a cache by default but considering that this is a patch release I think it's better to leave it disabled by default. I have updated the PR description.

rkistner
rkistner previously approved these changes Jul 22, 2026
@simolus3
simolus3 merged commit b65583f into main Jul 22, 2026
6 checks passed
@simolus3
simolus3 deleted the prepared-statements-cache branch July 22, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants