Experiment 212: Lazy nested-savepoint materialization moonshot

Date: 2026-07-03

Status: Rejected

Category: Moonshot

Direction:transaction-control-paths

Benchmark Run: focused

benchmark/experiments/savepoint_name_compression.dart,

order-flipped baseline/candidate pair

Archive:archive/exp-212

Problem

The nested-transaction direction has already closed the small local

savepoint optimizations:

strings, but the release suite had no nested workload yet.

workload and re-ran that cache; the 50x shallow fanout row moved only

-9%, inside the +/-17% decision threshold.

Empty/rollback/deep best-case rows improved, but the representative

nested-write fanout failed to reproduce and flipped slower in the

order-flipped pass.

The recurring lesson is that per-savepoint string and allocation work is not

the active ceiling once the nested body performs a real write. The only

remaining plausible frontier is round-trip shaped: a nested write body pays one

writer-isolate message for SAVEPOINT, one for the write, and one for

RELEASE. If that request count is the actual floor, a prototype that removes

one message should improve the one-write nested fanout.

Hypothesis

Assumption challenged: nested Transaction.transaction() must materialize its

SQLite savepoint eagerly, before the body runs, even when the body might be

empty or might perform exactly one write.

Prototype:

SAVEPOINT and RELEASE;

SAVEPOINT sN and the write together;

existing nested-transaction semantics;

nested transaction, keeping the prototype bounded and conservative.

Expected result:

per inner block;

cost;

nested bodies are not common or important enough to carry runtime complexity.

The risk budget is intentionally moonshot-shaped. The prototype changes

transaction-control scheduling and adds internal request/state complexity, but

does not add public API. If accepted, it would still need a careful audit of

rare savepoint-failure edges before merge.

Approach

The archived prototype is at

archive/exp-212.

Implementation sketch:

lib/src/writer/write_worker.dart

whose handler runs _beginNestedSavepoint(state) and then executeWrite()

before replying with the normal ExecuteResponse;

for the fused first nested write;

materialization first;

The runtime change was tested, archived, and then reverted from the final

branch. The PR keeps only this writeup, result artifact, index row, and signal

metadata.

Results

Raw run notes are recorded in

benchmark/results/2026-07-03T10-09-23Z-exp212-lazy-nested-savepoint.md.

Focused harness: dart run benchmark/experiments/savepoint_name_compression.dart.

Negative delta means candidate faster.

CasePair 1 baselinePair 1 candidateDeltaPair 2 candidatePair 2 baselineDelta
empty fanout x5004.760 ms1.052 ms-77.9%1.230 ms4.823 ms-74.5%
write fanout x1001.603 ms2.802 ms+74.8%2.174 ms1.612 ms+34.9%
rollback fanout x1002.383 ms2.738 ms+14.9%2.462 ms2.445 ms+0.7%
deep chain 100 x depth=53.702 ms3.934 ms+6.3%4.004 ms3.736 ms+7.2%

The empty-control case behaves exactly as predicted: skipping SAVEPOINT/RELEASE

for empty nested blocks is roughly 4x faster. That is not the acceptance gate.

The representative write fanout fails hard. It regresses in both pass

orderings: +74.8% in the baseline-first pair and +34.9% in the candidate-first

pair. Rollback fanout is neutral-to-slower and the deep chain is slower in both

passes. The fused first-write request removed one message, but it did not lower

the workload wall time; the added state and request shape likely disrupted the

already-cheap transaction path more than the removed empty begin helped.

Decision

Rejected.

Lazy nested-savepoint materialization is a real win only for empty nested

transaction bodies. The workload that matters for this direction is the

one-write nested fanout, and it reproduced candidate-slower across the

order-flipped pair. Keeping runtime complexity for an empty-body win would

optimize a rare shape while slowing the representative nested write path.

The implementation is preserved at archive/exp-212; no runtime code is kept.

Future Notes

fusion without new evidence that empty nested bodies are a common production

hot path. The current focused harness says the write-shaped case regresses.

lazy begin: either a full savepoint-scope command batch that fuses begin,

body, and release/rollback into one request, or a profile showing deeply

nested transaction control is hot enough to justify design work.

batching would need a massive, broad win. This experiment does not provide

that evidence.

Validation