Skip to content

sqlutil: enable WAL, larger cache, and NORMAL sync for the modernc SQLite driver#3693

Open
Deln0r wants to merge 1 commit into
element-hq:mainfrom
Deln0r:sqlite/pragma-perf-tuning
Open

sqlutil: enable WAL, larger cache, and NORMAL sync for the modernc SQLite driver#3693
Deln0r wants to merge 1 commit into
element-hq:mainfrom
Deln0r:sqlite/pragma-perf-tuning

Conversation

@Deln0r

@Deln0r Deln0r commented May 12, 2026

Copy link
Copy Markdown

Summary

The !cgo SQLite path (modernc.org/sqlite driver) currently only sets busy_timeout=10000 on the connection DSN. This PR adds three further pragmas with documented rationale and a regression test:

  • journal_mode=WAL - readers proceed while a writer is active. Dendrite's storage layer always has concurrent readers and writers, so WAL is the SQLite-recommended setting.
  • cache_size=-32000 - 32 MiB page cache, up from the modernc default of 2 MiB. Federation and sync workloads touch many rooms per request and benefit from a larger working set.
  • synchronous=NORMAL - fsync only at WAL checkpoints. Safe under WAL for application-level durability that survives process crashes; a power loss may roll back the most recent commit to the last checkpoint, which Matrix recovers from by resyncing peers.

The CGO build path (sqlite_cgo.go, mattn/go-sqlite3) is untouched.

Test plan

A new TestSQLiteNativeDSNExtension in internal/sqlutil/sqlite_native_test.go opens a fresh file-backed database with the assembled DSN and asserts each of the four pragmas round-trips to the expected value (busy_timeout, journal_mode, cache_size, synchronous). It carries the !cgo build tag so it runs in lock-step with the code under test.

CGO_ENABLED=0 go test -run TestSQLiteNativeDSNExtension ./internal/sqlutil/
ok  	github.com/element-hq/dendrite/internal/sqlutil	0.468s

Notes

  • The encoded %3d form (=) of the DSN syntax is kept to match the existing busy_timeout line; switching to the parenthesis form (_pragma=cache_size(-32000)) would be a separate cosmetic refactor.
  • These defaults are tuned for the typical "always-on Dendrite homeserver" deployment. Operators with extreme durability needs can still set synchronous=FULL at the OS layer.

…Lite driver

Augment the !cgo SQLite DSN with three further pragmas alongside the
existing busy_timeout setting:

  journal_mode=WAL    - readers no longer block on the writer, which
                        Dendrite's storage layer always has multiple of.
  cache_size=-32000   - 32 MiB page cache, up from the modernc default
                        of 2 MiB. Federation and sync workloads touch
                        many rooms per request and benefit from the
                        larger working set.
  synchronous=NORMAL  - fsync only at WAL checkpoints. Safe under WAL
                        for application durability; a power loss may
                        roll back to the last checkpoint, which Matrix
                        recovers from by resyncing peers.

Adds a regression test that opens a fresh database with the assembled
DSN and asserts each pragma round-trips to the expected value. The
test inherits the !cgo build tag so it runs together with the code
it exercises.

Only the !cgo build path is touched. The CGO build path (sqlite_cgo.go,
mattn/go-sqlite3) is unchanged.

Signed-off-by: Ian Chechin <ian00chechin@gmail.com>
@Deln0r Deln0r requested a review from a team as a code owner May 12, 2026 16:30
@CLAassistant

CLAassistant commented May 12, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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