Skip to content

Default SQLite connections to WAL#405

Open
JanJakes wants to merge 4 commits into
trunkfrom
wal
Open

Default SQLite connections to WAL#405
JanJakes wants to merge 4 commits into
trunkfrom
wal

Conversation

@JanJakes

@JanJakes JanJakes commented May 26, 2026

Copy link
Copy Markdown
Member

What changed

Journal mode:

  • Default new SQLite connections to journal_mode = WAL.
  • Skip defaulting to WAL when unavailable (e.g., on network filesystems).

Synchronous flag:

  • Apply synchronous = NORMAL when WAL is used.
  • Otherwise, use the SQLite default.

Other changes:

  • Wire the SQLITE_JOURNAL_MODE override through the WordPress plugin connection paths.
  • Accept journal_mode and synchronous in the WP_PDO_MySQL_On_SQLite driver options.
  • Add connection setup tests for the defaults, overrides, invalid values, and the WAL fallback.

Why

WAL improves read/write concurrency for SQLite-backed WordPress installs, and synchronous = NORMAL avoids frequent sync to the main database. In WAL mode, NORMAL is safe. From the SQLite docs:

WAL mode is safe from corruption with synchronous=NORMAL, and probably DELETE mode is safe too on modern filesystems. WAL mode is always consistent with synchronous=NORMAL, but WAL mode does lose durability. A transaction committed in WAL mode with synchronous=NORMAL might roll back following a power loss or system crash. Transactions are durable across application crashes regardless of the synchronous setting or journal mode.

The synchronous=NORMAL setting provides the best balance between performance and safety for most applications running in WAL mode. You lose durability across power lose with synchronous NORMAL in WAL mode, but that is not important for most applications. Transactions are still atomic, consistent, and isolated, which are the most important characteristics in most use cases.

Benchmark

A local benchmark ran a WordPress-like 90% read / 10% write workload against the same database file with 4, 8, and 16 concurrent workers, comparing the trunk defaults with WAL + NORMAL (median of 3 runs, PHP 8.5.5, SQLite 3.53.0).

Workers Config Ops/s p50 p95 p99
4 default 4,985 0.21 ms 3.94 ms 10.2 ms
4 WAL + NORMAL 15,982 (3.2×) 0.19 ms 0.73 ms 1.2 ms
8 default 5,249 0.24 ms 4.22 ms 22.6 ms
8 WAL + NORMAL 25,371 (4.8×) 0.20 ms 1.02 ms 1.5 ms
16 default 5,226 0.25 ms 10.25 ms 59.0 ms
16 WAL + NORMAL 30,300 (5.8×) 0.22 ms 1.43 ms 4.0 ms

This was run on an M4 MacBook Pro Max.

@JanJakes JanJakes force-pushed the wal branch 7 times, most recently from 52b2201 to e5f3c64 Compare June 12, 2026 13:15
JanJakes added 4 commits June 12, 2026 15:18
Configure new SQLite connections to use WAL by default and apply
synchronous=NORMAL when WAL is the effective journal mode. Keep the
explicit SQLITE_JOURNAL_MODE override available for WordPress plugin
connections, including initial installation.
WAL can fail to engage in some environments, e.g., on network filesystems
or when the WAL sidecar files cannot be created. In that case, setting the
journal mode throws, which would newly fail connections that worked before
WAL became the default. Keep the database's current journal mode when the
WAL default fails, but let explicitly configured modes surface the error.

Also include the SQLite connection setup in the installation error
handling, so a connection failure dies gracefully during WordPress
installation instead of causing a fatal error.
PRAGMA synchronous accepts integers from 0 to 3 as equivalents of the
keyword values, and constants like SQLITE_SYNCHRONOUS are likely to be
defined as integers. Map integer values to the corresponding keywords
instead of silently ignoring them.
The WAL default applies to all WP_SQLite_Connection consumers, but only
the WordPress plugin paths supported overriding it. Accept journal_mode
and synchronous in the WP_PDO_MySQL_On_SQLite driver options so the
PDO API consumers can configure them as well.
@JanJakes JanJakes marked this pull request as ready for review June 12, 2026 13:37
@JanJakes JanJakes requested a review from adamziel June 12, 2026 13:37
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.

1 participant