Skip to main content
DuckDB writes go to a write-ahead log (WAL) and are folded into the main database file on checkpoint. The plugin lets you configure composable checkpoint strategies at init time, in addition to the explicit checkpoint command. The default is fully passive — rely on DuckDB’s own WAL-size auto-checkpoint.
CHECKPOINT fails while a transaction is active, so background and after-write sweeps can use FORCE CHECKPOINT (DuckDB v1.4+ waits for the lock) via checkpoint_force.

Strategies

All strategies are set on core::Builder / diesel::Builder and are additive — enable any mix.

Automatic (checkpoint_threshold)

Sets DuckDB’s own checkpoint_threshold at load time (e.g. "64MB"), tuning how large the WAL grows before DuckDB auto-checkpoints. The most hands-off strategy.

AfterWrites (checkpoint_after_writes)

Counts write operations (execute / import / append_rows / revert) and checkpoints the connection after every n-th one. Good for bursty writes you want flushed promptly. Uses FORCE CHECKPOINT when checkpoint_force(true) is set.

Interval (checkpoint_interval)

Spawns a background thread at plugin setup that sleeps for the period and then checkpoints every loaded connection (checkpoint_all). Best-effort — failures on an individual connection are ignored.

OnAppLifecycle (checkpoint_on_exit)

Hooks the Tauri RunEvent::Exit event and checkpoints all connections as the app exits — the safety net for data still in the WAL at shutdown.

checkpoint_force

Switches the background / after-write / lifecycle sweeps from CHECKPOINT to FORCE CHECKPOINT, which waits for the lock instead of failing when a transaction is active. The explicit db.checkpoint(force) command takes its own force argument independently.

Platform defaults

checkpoint_platform_defaults() applies a sensible per-platform set:
  • Mobile (Android / iOS): enables OnAppLifecycle + FORCE CHECKPOINT, because the OS can suspend or kill the app without a clean process exit, so pending WAL data must be flushed on the lifecycle event.
  • Desktop: stays passive (relies on DuckDB’s WAL-size auto-checkpoint).
Merge semantics make call order irrelevant. checkpoint_platform_defaults() fills only what you have not set: Option fields fall back to the defaults, and the on_exit / force booleans are OR-ed in. A platform default can enable a strategy but never disables one you turned on, so it is safe to call before or after the other checkpoint_* setters.

Explicit checkpoint from the webview

See Maintenance. Reach for this at a critical moment — before an export, on logout — rather than relying only on a background strategy.

Picking a strategy

  • Desktop, moderate writes: checkpoint_interval(…) and/or checkpoint_on_exit(true).
  • Mobile: checkpoint_platform_defaults() (or checkpoint_on_exit(true).checkpoint_force(true)).
  • Bursty writes to flush promptly: checkpoint_after_writes(n).
  • WAL-size tuning: checkpoint_threshold("…").
  • A critical moment: db.checkpoint(true) from JS.
Checkpointing (WAL → main file) is not the same as the migration backup protocol (<db>.bak / <db>.migrate-journal). The latter is an automatic crash-safety net around migrations — see Migrations. Don’t conflate them.

See also

  • Maintenance — the explicit checkpoint command.
  • Migrations — the separate, migration-time backup mechanism.
  • Registration — where the strategy setters live on the builder.