Skip to content

refactor(sqlite): reduce repeated schema validation work - #139366

Merged
steipete merged 1 commit into
mainfrom
codex/perf-sep05-sqlite-schema-shared-cache-current
Sep 5, 2026
Merged

steipete merged 1 commit into
mainfrom
codex/perf-sep05-sqlite-schema-shared-cache-current

Conversation

@steipete

@steipete steipete commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

What Problem This Solves

Repeated schema validation adds avoidable overhead to state-database operations that already hold an open connection.

Why This Change Was Made

Reuse the existing per-database statement cache for three fixed schema reads, with its implementation in the shared SQLite execution owner. SQL, bindings, validation results, cache limits/admission, active-statement isolation, authorizer/deserialization invalidation, and close behavior remain unchanged.

Production is +14 lines (208 added/194 removed, largely relocation); the growth connects schema reads to the existing synchronous statement-lifetime boundary. Tests are +97, the guard registry +1, and the assertion baseline records two removed assertions. No second cache is introduced.

User Impact

Less work for repeated schema checks on cache-enabled handles. There are no schema/version, persisted-data, configuration, or public API changes. Cache-disabled reads preserve their behavior. No Gateway-turn or universal tail/memory improvement is claimed.

Evidence

Current schema-v16 composition, base 5702b801: normal frozen install; all six owner/sibling test files passed 370 cases plus one unchanged Linux-only skip; all 34 normal changed-gate stages passed; one mapped normal build passed. The actual emitted owner passed fresh-open/reopen schema-v16 metadata checks, complete schema validation, read-only preflight and cleanup. Preflight preserved the closed source family's bytes/metadata and removed its snapshots; all native/adapter processes closed. Subsequent normal reopen changed ctime only, with bytes/mtime unchanged. Independent P0–P2 review completed all 11 partitions with no actionable findings.

Historical performance cohort, schema v15 at db2348: fixed B0/C0/C1/B1 order, 256 batch means, with complete results checked throughout. These measurements have not been relabeled as v16 results or rerun for a better outcome. Percentages compare candidate with baseline; negative means less time.

Complete operation Forward median Reverse median
R01: cache-disabled read-only control −1.79% +0.03%
R02: normal enabled schema check −16.03% −15.10%
R03: schema check + 29-query capacity control −15.93% −14.80%
R04: schema check + 32-query pressure control −15.52% −14.11%

The pressure rows are synthetic controls, not an observed production query mix. All 25 adverse entries out of 110 comparisons are retained below. Notable opposing results include read-only forward batch p95 +48.10%, reverse pressure-row p95 +24.08% / +7.67%, and sampled family RSS +0.21% / +1.20% despite lower kernel-child peaks. Four timing hosts do not establish fleet behavior; p95 here describes 16-cycle batch means, not individual-call latency.

All 25 adverse observations

With 16 samples, nearest-rank p95 equals the maximum; duplicate p95/maximum entries are not independent evidence. Lifecycle observations are single-host measurements. Forward compares B0/C0; reverse compares B1/C1 from the reverse execution order.

Order Metric Absolute increase Relative increase
Forward R01 warm-cycle median +0.306167 ms +2.72%
Forward R01 warm-cycle p95 +21.029708 ms +148.78%
Forward R01 warm-cycle maximum +21.029708 ms +148.78%
Forward R01 batch-cycle p95 +5.511156 ms +48.10%
Forward R01 batch-cycle maximum +5.511156 ms +48.10%
Forward R01 seed-open +22.895501 ms +27.19%
Forward R01 query-preparation +0.026625 ms +59.28%
Forward R01 owner-close +1.520292 ms +111.66%
Forward R02 query-preparation +0.000583 ms +17.49%
Forward R03 query-preparation +0.115375 ms +11.44%
Forward R04 query-preparation +0.012958 ms +2.73%
Forward Sampled process-family peak RSS +983,040 B +0.21%
Reverse R01 first cycle +0.097251 ms +0.86%
Reverse R01 batch-cycle median +0.003430 ms +0.03%
Reverse R03 batch-cycle p95 +2.810091 ms +24.08%
Reverse R03 batch-cycle maximum +2.810091 ms +24.08%
Reverse R04 batch-cycle p95 +1.049659 ms +7.67%
Reverse R04 batch-cycle maximum +1.049659 ms +7.67%
Reverse R01 owner-close +2.326125 ms +341.26%
Reverse R02 reopen +0.637916 ms +2.06%
Reverse R02 query-preparation +0.000792 ms +25.69%
Reverse R03 query-preparation +0.051667 ms +5.45%
Reverse R04 seed-close +0.103582 ms +0.71%
Reverse R04 owner-close +1.407000 ms +324.60%
Reverse Sampled process-family peak RSS +5,521,408 B +1.20%

The Linux initialization-failure descriptor assertion remains skipped on macOS. Existing Vite import-analysis and build EVAL/source-map/browser-externalization advisories remain recorded; no warning suppression, timeout change, or test bypass was added.

Data-model review clarification

The schema-change warning in the automated review does not describe this diff. No table/index/trigger definitions, schema versions, migrations, or persisted values change. The three SQL SELECT texts and bindings are unchanged; only their existing prepared-statement execution owner is reused. The canonical schema and migration files are untouched. No new migration is needed.

The requested upgrade compatibility evidence is also present in the current 370-pass/one-skip run: all three existing cases passed in openclaw-state-db.test.ts: v15 Workshop ownership migration preserves rows; a v15 database without Workshop tables upgrades to v16; and a v15 database missing a stable table remains rejected by runtime open and Doctor repair. These exercise existing migrations, not migrations introduced by this PR. The separately reported actual compiled v16 fresh-open/reopen/read-only/preflight proof also passed.

This addresses the review's compatibility-proof request; additional schema changes would be unrelated and are intentionally not added. Exact-head CI 33990278224 passed.

@clawsweeper

clawsweeper Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@steipete
steipete marked this pull request as ready for review September 5, 2026 20:29
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts size: L maintainer Maintainer-authored PR labels Sep 5, 2026
@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Sep 5, 2026
@clawsweeper

clawsweeper Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: blocked before merge. Reviewed September 5, 2026, 5:18 PM ET / 21:18 UTC.

ClawSweeper review

What this changes

Reuse the existing database statement cache for three schema queries, reducing repeated preparation while preserving schema validation results.

Warning

SQLite table change

This PR modifies persisted SQLite tables in src/infra/sqlite-schema-contract.ts. Prefer a design that avoids changing persisted SQLite tables. If the change is necessary, verify migration and upgrade compatibility against an existing database before merge.

Merge readiness

⛔ Blocked before merge - 2 items remain

The optimization remains useful and has no identified blocking defect. The previous migration blocker is resolved: this diff changes neither persisted representations nor migration policy, and the clarification supplies relevant upgrade validation.

Priority: P2
Reviewed head: b81de9ea8abf1cea4c8fecdc48811e4f7e4560f6

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused, maintainable optimization with relevant runtime evidence and no remaining blocking finding.
Proof confidence 🐚 platinum hermit (4/6) Sufficient (live_output): The captured body reports the compiled database owner exercising schema-v16 fresh-open, reopen, read-only preflight, and cleanup with preserved source bytes, alongside scoped before/after schema-check measurements; these cover the changed execution boundary.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The captured body reports the compiled database owner exercising schema-v16 fresh-open, reopen, read-only preflight, and cleanup with preserved source bytes, alongside scoped before/after schema-check measurements; these cover the changed execution boundary.
Evidence reviewed 8 items Introduced behavior and persistence boundary: The complete schema-reader diff changes only execution of three fixed SELECTs; SQL, bindings, comparison policy, schema definitions, and migrations remain unchanged.
Shared execution and lifecycle owner: Read both complete execution modules. Cache enablement still installs invalidation first; authorizers disable reuse, transitions clear retained statements, active statements remain isolated, and close/disposal clear database-owned caches. Kysely's execution entrypoint retains its invalidation installation.
Caller and sibling coverage: State-database open enables caching before schema validation; the fast path collects schema facts within its existing deferred transaction. Inspected transaction cleanup, complete schema tests, and complete Kysely tests covering reentry, changing authorization, deserialization, schema drift, and close-time retention. New schema tests exercise both cache modes and nonextensible uncached handles.
Findings None None.
Security None None.

How this fits together

SQLite schema validation checks database structure before OpenClaw exposes stored state. These reads now share the bounded statement cache used by synchronous database queries, while lifecycle owners retain cleanup responsibility.

flowchart TD
  A[Database open or validation] --> B[Schema contract reader]
  B --> C{Statement caching enabled and allowed?}
  C -->|Yes| D[Existing bounded statement cache]
  C -->|No| E[Fresh prepared statement]
  D --> F[Current SQLite schema rows]
  E --> F
  F --> G[Validation result]
  H[Close or invalidation] --> D
Loading

Before merge

  • Resolve merge risk (P1) - Historical schema-v15 benchmarks support a scoped median improvement, but do not establish schema-v16 production tail-latency or memory improvements.
  • Add data-model compatibility proof - Confirm migration or upgrade compatibility proof before merge.
Agent review details

Security

None.

PR surface

Source +14, Tests +97, Other +1. Total +112 across 6 files.

View PR surface stats
Area Files Added Removed Net
Source 3 208 194 +14
Tests 1 104 7 +97
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 2 2 1 +1
Total 6 314 202 +112

Review metrics

Metric Value Why it matters
Interpreted LOC delta Production +14; tests +97; guard registry +1; assertion baseline net 0 Most production churn relocates existing code; remaining growth connects three reads to the shared lifetime boundary.

Stored data model

Persistent data-model change detected: database schema: src/infra/sqlite-schema-contract.ts, unknown-data-model-change: src/infra/sqlite-schema-contract.ts. Confirm migration or upgrade compatibility proof before merge.

Merge-risk options

Maintainer options:

  1. Decide the mitigation before merge
    Keep schema reads within the existing bounded execution owner, preserving fresh results and lifecycle invalidation without adding a second cache or migration.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Technical review

Best possible solution:

Keep schema reads within the existing bounded execution owner, preserving fresh results and lifecycle invalidation without adding a second cache or migration.

Do we have a high-confidence way to reproduce the issue?

Not applicable as a correctness bug: current main visibly repeats statement preparation, and the supplied benchmark measures that overhead; this read-only review did not execute benchmarks or tests.

Is this the best way to solve the issue?

Yes. Reusing the established cache avoids competing ownership, and the unchanged SELECTs and validation policy do not require a migration.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 523d4c1840a7.

Labels

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The captured body reports the compiled database owner exercising schema-v16 fresh-open, reopen, read-only preflight, and cleanup with preserved source bytes, alongside scoped before/after schema-check measurements; these cover the changed execution boundary.

Label justifications:

  • P2: This is a bounded database performance improvement with no demonstrated urgent user-facing failure.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The captured body reports the compiled database owner exercising schema-v16 fresh-open, reopen, read-only preflight, and cleanup with preserved source bytes, alongside scoped before/after schema-check measurements; these cover the changed execution boundary.
  • proof: sufficient: Contributor real behavior proof is sufficient. The captured body reports the compiled database owner exercising schema-v16 fresh-open, reopen, read-only preflight, and cleanup with preserved source bytes, alongside scoped before/after schema-check measurements; these cover the changed execution boundary.

Evidence

What I checked:

  • Introduced behavior and persistence boundary: The complete schema-reader diff changes only execution of three fixed SELECTs; SQL, bindings, comparison policy, schema definitions, and migrations remain unchanged. (src/infra/sqlite-schema-contract.ts:426, b81de9ea8abf)
  • Shared execution and lifecycle owner: Read both complete execution modules. Cache enablement still installs invalidation first; authorizers disable reuse, transitions clear retained statements, active statements remain isolated, and close/disposal clear database-owned caches. Kysely's execution entrypoint retains its invalidation installation. (src/infra/kysely-sync-cache-state.ts:58, b81de9ea8abf)
  • Caller and sibling coverage: State-database open enables caching before schema validation; the fast path collects schema facts within its existing deferred transaction. Inspected transaction cleanup, complete schema tests, and complete Kysely tests covering reentry, changing authorization, deserialization, schema drift, and close-time retention. New schema tests exercise both cache modes and nonextensible uncached handles. (src/state/openclaw-state-db-open.ts:64, b81de9ea8abf)
  • Prior blocker and author disposition: The earlier review covered this same head and contained no findings. The author's clarification links existing v15-to-v16 row-preservation, missing-Workshop-table upgrade, and damaged-store rejection tests; source inspection confirms those cases. The database policy expressly excludes semantics-preserving read-only query improvements from the material-change checkpoint. See refactor(sqlite): reduce repeated schema validation work #139366 (comment). (src/state/openclaw-state-db.test.ts:1526, b81de9ea8abf)
  • Current-main and release necessity: Inspected fetched main and v2026.9.2: both still prepare these schema SELECTs directly. The requested optimization is therefore still distinct. No verified replacement PR was supplied; the attempted GitHub canonical search failed to connect. (src/infra/sqlite-schema-contract.ts:425, 523d4c1840a7)
  • Direct dependency contract inspection: The affirmative dependency signal is node:sqlite imports and the new retained StatementSync get/all calls. Inspected upstream reset/rebind behavior and deserialization finalization in Node SQLite source, including lines 3189–3311 and 1914–1996. These are Node contracts; no Codex dependency signal exists in this change. The browsed upstream revision was not pinned to a commit. (src/node_sqlite.cc:3242)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (1 earlier review cycle)
  • reviewed 2026-09-05T20:52:16.562Z sha b81de9e :: blocked before merge. :: none

@steipete

steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Data-model review clarification

The schema-change warning in the automated review does not describe this diff. No table/index/trigger definitions, schema versions, migrations, or persisted values change. The three SQL SELECT texts and bindings are unchanged; only their existing prepared-statement execution owner is reused. The canonical schema and migration files are untouched. No new migration is needed.

The requested upgrade compatibility evidence is also present in the current 370-pass/one-skip run: all three existing cases passed in openclaw-state-db.test.ts: v15 Workshop ownership migration preserves rows; a v15 database without Workshop tables upgrades to v16; and a v15 database missing a stable table remains rejected by runtime open and Doctor repair. These exercise existing migrations, not migrations introduced by this PR. The separately reported actual compiled v16 fresh-open/reopen/read-only/preflight proof also passed.

This addresses the review's compatibility-proof request; additional schema changes would be unrelated and are intentionally not added. Exact-head CI 33990278224 passed.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Sep 5, 2026
@steipete
steipete merged commit 6037e40 into main Sep 5, 2026
255 checks passed
@steipete
steipete deleted the codex/perf-sep05-sqlite-schema-shared-cache-current branch September 5, 2026 21:22
@steipete

steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

@steipete

steipete commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

The 21:18 review refresh acknowledges that the migration blocker is resolved and that the diff changes neither persisted representations nor migration policy. Its remaining performance warning matches limitations already stated in the PR: historical schema-v15 timings do not establish schema-v16 production tails or memory improvement. Neither claim is made.

The maintainer decision is to accept the bounded reuse refactor with unchanged queries and cache/lifecycle policy, supported by the scoped timings, all retained adverse observations, current upgrade/refusal tests, compiled-owner proof and green exact-head CI. No second cache, migration, widened benchmark claim, or additional database change is introduced. The refreshed review identifies no correctness finding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts size: L status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant