Skip to content

perf(store): stop waiting for the disk and scanning whole tables - #74

Merged
httpsphl merged 1 commit into
mainfrom
perf/store
Sep 30, 2026
Merged

httpsphl merged 1 commit into
mainfrom
perf/store

Conversation

@httpsphl

Copy link
Copy Markdown
Owner

First slice of the performance round.

What changes

  • synchronous=NORMAL (WAL). Before, every commit waited for FlushFileBuffers (5–30 ms on Windows) while holding the only store mutex, on every chat item, mark_read and delivery claim/finish. NORMAL never corrupts a WAL database; a power cut can lose the last commits.
  • temp_store=MEMORY, a 16 MB cache, journal_size_limit, and a bounded PRAGMA optimize on open.
  • A statement cache of 128. Hot statements go through it: chat item insert/update, tool_item, deliveries, messages, session_id, plus every prepare.
  • Migration 0012:
    • indexes on every foreign key that had none (deleting a bot or crew scanned the child tables once per row);
    • the toolUseId lookup that each tool result and permission prompt runs;
    • written_files;
    • a routine's runs in rowid order;
    • routines_due as a partial index.
  • delivery_backlog (polled every 15 s) counts through the state index. runs_with_dead_delivery and stale_runs use EXISTS.
  • Spec 12 describes the pragmas.

Tests

  • plans.rs runs EXPLAIN QUERY PLAN on the hot queries and the foreign-key lookups, and fails on a full scan or a sort.
  • cargo fmt, clippy -D warnings, cargo test --workspace pass locally.

Manual check (real install)

  • Open an existing botloft.db with this build. Migration 0012 runs, bots, chats and routines load as before, and a bot's chat keeps streaming.

- synchronous=NORMAL: in WAL mode it never corrupts the database, and a
  commit no longer waits for FlushFileBuffers. With FULL every chat item,
  read receipt and delivery paid a flush while holding the store lock.
- temp_store=MEMORY, a 16 MB page cache, a WAL size limit and a bounded
  PRAGMA optimize on open.
- Statement cache of 128; statements run on every chat item, delivery,
  message and session lookup go through it instead of being parsed and
  planned each time.
- Migration 0012 indexes every foreign key that had none (deleting a bot
  or crew scanned the child tables once per row), the tool lookup that
  each tool result and permission prompt runs, the files a bot wrote,
  a routine's runs in rowid order and the routines that can come due.
- delivery_backlog counts through the state index; the routine run
  queries use EXISTS so they walk only the open runs.
- A test checks the query plans of the hot queries and the foreign keys.
@httpsphl
httpsphl merged commit 3c16ef9 into main Sep 30, 2026
3 checks passed
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