library · how it got fast

reads on a small cache.

Point reads when the data is ten times larger than the cache.

39 min read · 8,647 words · commit fd1b95c · filed as “Small-cache point reads”

The mapped warm point target passes, and the five-pair final confirmation shows no latest-ten regression (see the first section). The final engine is rebased onto main 37feee99. Only durable-write p99p9999% of operations were faster than this. It shows how bad the slow cases get. non-regression remains unproven (not observed to regress). Keep mmapmmapMapping a file into memory so it can be read like an array, with the OS handling the disk. opt-in and do not claim the full requested goal is met.

Rebased source was frozen at 72e057a0f4886f48633f50999b0a6d632b2120c1. Engine hashes in rebased provenance identify the validated source independently of later evidence-only commits.

315 MiB1M records on disk32 MiB cachelocators stay residentone valueits own CRC, verified alone
fig. 05ten times the dataWith 1M records in about 315 MiB of SSTs and a 32 MiB cache, volumes drawn to scale. Compact locators stay resident, so a read jumps to the exact value and verifies only those bytes.

Final five-pair confirmation (supersedes the three-pair latest-ten verdict)

Five alternating main/candidate pairs, each side with an adjacent LMDBLMDBA widely used embedded database built on a B+tree and memory-mapped files, known for very fast reads. control, on every mode/layout/cache cell (CPU 6 only, 100,000 calls each, all 1M records verified) put candidate latest-ten at or below main within noise everywhere.

The three-pair 1.24x/1.51x at mapped/bulk/32 was a noise outlier, as the earlier independent five-pair control (1.029/0.966) already suggested. Engine source is unchanged: all 40 engine file hashes still match rebased-checks/source-hashes.json.

Diagnostics supporting this: in rebased-scan-cache the candidate latest-ten hot loop at 32 MiB has 0 misses and 0 evictions (110 resident blocks beside 32.6 MB of locators), with the same 1.7 block hits per call as main; the perf-stat run (rebased-latest-profile) shows user instructions per call 49,044 vs 49,117 and cycles 12,218 vs 12,550 (candidate vs main), so no extra copy, CRC, or page-touch work exists on the scan path.

Remaining mean differences track host load (load average about 24 on 22 CPUs during this work).

Latencies in microseconds, median of five alternating trials. Ratio is raw candidate/main p50p50The median: half of all operations were faster than this. / p99. LMDB columns are the control run next to each side. Trial ranges: mapped 32, mapped bulk 512/default, mapped normal, pread.

Mode / layout / cache MiB / workloadMain p50/p99Candidate p50/p99Cand/main p50 / p99LMDB (main side) p50/p99LMDB (cand side) p50/p99
mapped / bulk / 32 / recall-by-id3.584 / 6.1441.184 / 1.6000.33 / 0.261.728 / 2.5601.728 / 2.688
mapped / bulk / 32 / recent-for-agent3.840 / 8.9603.712 / 8.7040.97 / 0.973.008 / 6.1442.816 / 6.016
mapped / bulk / 512 / recall-by-id1.216 / 1.6321.056 / 1.5040.87 / 0.921.856 / 2.8161.824 / 2.880
mapped / bulk / 512 / recent-for-agent3.904 / 8.7043.904 / 8.9601.00 / 1.033.456 / 8.1923.264 / 7.680
mapped / bulk / default / recall-by-id1.008 / 1.4721.056 / 1.5361.05 / 1.041.760 / 2.6241.792 / 2.752
mapped / bulk / default / recent-for-agent3.776 / 7.5523.712 / 8.4480.98 / 1.123.136 / 6.5282.944 / 6.400
mapped / normal / 32 / recall-by-id3.328 / 5.2481.344 / 2.0480.40 / 0.391.824 / 2.9441.728 / 2.496
mapped / normal / 32 / recent-for-agent4.224 / 8.1923.712 / 7.2960.88 / 0.893.008 / 6.2722.816 / 5.760
mapped / normal / 512 / recall-by-id1.376 / 2.1121.280 / 2.0160.93 / 0.951.792 / 2.6881.760 / 2.688
mapped / normal / 512 / recent-for-agent4.352 / 7.9364.032 / 7.9360.93 / 1.003.008 / 5.8882.944 / 6.272
mapped / normal / default / recall-by-id1.376 / 2.1121.216 / 1.7600.88 / 0.831.728 / 2.5601.760 / 2.752
mapped / normal / default / recent-for-agent4.352 / 8.1923.776 / 7.8080.87 / 0.952.944 / 5.8883.008 / 6.144
pread / bulk / 32 / recall-by-id4.864 / 7.6801.920 / 2.9440.39 / 0.381.856 / 3.1361.888 / 2.944
pread / bulk / 32 / recent-for-agent3.840 / 8.7043.968 / 8.1921.03 / 0.943.136 / 6.9123.200 / 7.168
pread / bulk / 512 / recall-by-id1.120 / 1.5361.088 / 1.5680.97 / 1.021.760 / 2.6241.760 / 2.624
pread / bulk / 512 / recent-for-agent4.608 / 9.4723.968 / 8.9600.86 / 0.953.456 / 6.5283.072 / 6.016
pread / bulk / default / recall-by-id1.152 / 1.6641.120 / 1.5680.97 / 0.941.920 / 2.8801.952 / 3.008
pread / bulk / default / recent-for-agent4.608 / 10.2404.608 / 9.7281.00 / 0.953.712 / 7.4243.648 / 7.552
pread / normal / 32 / recall-by-id4.736 / 7.4242.240 / 3.6480.47 / 0.491.824 / 2.8801.824 / 2.816
pread / normal / 32 / recent-for-agent4.736 / 10.4964.352 / 9.2160.92 / 0.883.328 / 6.5283.328 / 6.784
pread / normal / 512 / recall-by-id1.472 / 2.1761.216 / 1.7920.83 / 0.821.760 / 2.6241.760 / 2.688
pread / normal / 512 / recent-for-agent4.480 / 8.7043.904 / 7.5520.87 / 0.873.200 / 6.4003.008 / 6.144
pread / normal / default / recall-by-id1.440 / 2.1761.280 / 1.9200.89 / 0.881.792 / 2.7521.728 / 2.624
pread / normal / default / recent-for-agent4.608 / 8.9604.096 / 8.7040.89 / 0.973.264 / 6.0163.072 / 5.504

Worst latest-ten cells versus main: pread bulk/32 p50 +3.3% (3.968 vs 3.840), mapped bulk/512 p99 +2.9%; every other latest-ten cell is equal or faster. Point reads keep the win: mapped 32 MiB point p50/p99 is 3.584/6.144 -> 1.184/1.600 (bulk) and 3.328/5.248 -> 1.344/2.048 (normal), against LMDB 1.728/2.7 (Kiban/LMDB 0.685 bulk, 0.78 normal).

Larger-cache point cells are at parity or better than main (largest deviation: mapped bulk default p50 1.008 -> 1.056, +4.8%, p99 +4.3%, while still 0.56x LMDB).

Writes: five alternating pairs, fast and durable, index off/on (10k ops per stage, default cache)

Source: rebased-write-confirm. Microseconds, medians; main -> candidate.

Mode / index / opp50p99
fast / off / remember1.120 -> 1.1209.728 -> 9.216
fast / off / update1.760 -> 1.63211.008 -> 9.984
fast / on / remember1.120 -> 1.1209.472 -> 9.984
fast / on / update1.664 -> 1.60010.240 -> 10.496
durable / off / remember622.6 -> 622.63211 -> 3277
durable / off / update606.2 -> 622.61868 -> 3277
durable / on / remember639.0 -> 655.45374 -> 3342
durable / on / update622.6 -> 655.43473 -> 4194

Fast-write p50/p99 are equal within noise (index on: p99 +1.1% to +2.5%; trial ranges overlap). Durable p50 is within +5%. Durable p99 is dominated by fsync outliers and swings in both directions across the same code (index-off update 1.9 -> 3.3 ms and index-on remember 5.4 -> 3.3 ms are the same code path, both writers unchanged; LMDB controls moved 8.9 -> 11.8 ms).

The data show no consistent durable p99 regression, but five pairs cannot prove p99 non-regression on fsync-bound tails; this stays a limitation. Per-value CRC adds 4 bytes per version to the point section only when point_index is on, and does not touch WALWALWrite-ahead log. Every change is appended here first, so it can be replayed after a crash., flushflushWriting a full memtable out to disk as a new SST., or fsyncfsyncForces a file and its metadata onto the disk. ordering.

Gates

No engine source changed after the rebased gates, so they apply to the final source (hash-verified): 11/11 gates in rebased-checks/status.json passed (debug and release workspace tests, clippy -D warnings, fmt, fixed crash corpora, loom, both 20,000-seed suites, readbench clippy/test/fmt). cargo fmt --check and cargo clippy --all-targets --workspace -- -D warnings were also rerun clean on the final tree.

Limitations

  • mmap stays opt-in (cold-storage tradeoff documented below). Durable-write p99 is not proven non-regressive, only not observed to regress. CPU 7 (sibling of CPU 6) was not provably idle. Ratios above 1 within a few percent in individual cells (listed above) are inside the trial ranges.

Rebased warm confirmation against current main

Three alternating pairs per layout, cache, and access mode. Every Kiban process has an adjacent LMDB control. Timed children use CPU 6; builds, gates, and coordinators use CPUs 12–21 at nice 10. Other host work remained active. Each trial runs 100,000 point calls and 100,000 latest-ten calls and verifies all 1M records. Ratios are medians of within-pair ratios. Latencies are microseconds.

Both binaries include main's SQLite benchmark support. Main fixtures are fresh flag-zero PH3PH3Kiban's compact on-disk format for the perfect-hash point index., while candidate fixtures are the frozen CRC-bearing PH3 datasets. The production engine logic matches the frozen campaign; the reader has only main's explanatory comment, and the ignored maintenance benchmark gains a trial selector. See source comparison.

Mode / layout / cache MiBMain p50/p99Candidate p50/p99LMDB p50/p99Paired K/L p50/p99Adjusted candidate/main p50/p99
mapped / bulk / 323.968 / 6.7841.440 / 2.2401.952 / 3.0720.682 / 0.6600.389 / 0.364
mapped / bulk / 5121.216 / 1.7281.280 / 1.8561.920 / 3.0720.667 / 0.6171.000 / 1.015
mapped / bulk / default1.184 / 1.7921.184 / 1.7921.888 / 2.9440.627 / 0.5651.068 / 1.000
mapped / normal / 323.520 / 5.7601.568 / 2.6881.888 / 3.1360.831 / 0.8780.467 / 0.479
mapped / normal / 5121.920 / 2.9441.504 / 2.5601.984 / 3.2640.758 / 0.7710.783 / 0.962
mapped / normal / default1.760 / 2.6241.568 / 2.4321.984 / 3.7120.790 / 0.6550.847 / 0.815
pread / bulk / 325.120 / 9.7282.240 / 3.7121.920 / 3.1361.186 / 1.2040.438 / 0.336
pread / bulk / 5121.248 / 1.9201.184 / 1.7921.984 / 3.2000.597 / 0.5600.927 / 0.906
pread / bulk / default1.248 / 2.0161.376 / 2.1121.952 / 3.2000.717 / 0.6111.034 / 0.999
pread / normal / 325.120 / 8.7042.496 / 4.3521.984 / 3.3281.246 / 1.3110.471 / 0.543
pread / normal / 5121.728 / 2.8161.664 / 2.3681.920 / 3.1360.765 / 0.6730.845 / 0.689
pread / normal / default1.600 / 2.5601.696 / 2.4961.920 / 3.0720.869 / 0.8040.981 / 1.075

Mapped trial ranges, pread trial ranges. Values above one in the adjusted columns remain visible; three pairs are a confirmation, not a replacement for the five-pair campaign.

Latest-ten mode / layout / cache MiBMain p50/p99Candidate p50/p99Adjusted candidate/main p50/p99
mapped / bulk / 324.032 / 8.1924.992 / 11.2641.241 / 1.512
mapped / bulk / 5124.032 / 9.4724.096 / 8.9601.102 / 1.111
mapped / bulk / default3.968 / 8.4483.776 / 8.0641.010 / 0.900
mapped / normal / 324.480 / 8.4483.968 / 7.8080.923 / 1.017
mapped / normal / 5124.992 / 13.0564.224 / 10.2400.903 / 0.853
mapped / normal / default4.608 / 9.4724.224 / 9.9840.935 / 0.902
pread / bulk / 324.352 / 8.9604.096 / 8.7041.000 / 0.909
pread / bulk / 5124.096 / 8.9603.968 / 8.9600.905 / 0.349
pread / bulk / default4.096 / 9.4723.968 / 8.9601.039 / 1.273
pread / normal / 324.736 / 10.4964.096 / 8.9600.897 / 1.024
pread / normal / 5124.608 / 9.4724.096 / 8.4480.943 / 0.997
pread / normal / default4.608 / 9.9843.968 / 8.4480.915 / 0.887

Bulk control confirmation

Five additional alternating pairs repeat the three uncertain mapped bulk cache cases with the same binaries and fixtures. The original three-pair matrix is retained in full. Latencies are microseconds.

Cache MiB / workloadMain p50/p99Candidate p50/p99Adjusted candidate/main p50/p99
32 / recall-by-id3.968 / 7.0401.376 / 2.1120.350 / 0.276
32 / recent-for-agent4.032 / 8.1923.968 / 7.6801.029 / 0.966
512 / recall-by-id1.216 / 1.9521.344 / 2.1121.045 / 1.049
512 / recent-for-agent4.032 / 8.9603.904 / 8.4480.987 / 1.014
default / recall-by-id1.280 / 2.0481.312 / 1.9521.038 / 0.899
default / recent-for-agent3.968 / 7.9363.840 / 7.8081.050 / 1.139

The large initial bulk/32 latest-ten slowdown does not reproduce at five pairs: adjusted p50/p99 is 1.029/0.966. Other controls remain above main. Default point is 1.038/0.899, 512 MiB point is 1.045/1.049, and default latest-ten is 1.050/1.139. The data do not establish the requested larger-cache and latest-ten non-regression bounds. All trial ranges and both series remain visible.

All five-pair controls and ranges.

Rebase and final gates

PH3 base 4feca511 is already present through squash merge f3d21dc1 and was dropped from the replay. Main's Bloom bypass is retained. Duplicate engine commit 0283fc7a was dropped, with its unique tools and measurement evidence preserved in the campaign evidence commit. The locator lookup follows the same exact-key-before-Bloom ordering.

The CRC extension, resident packing, exact reservation accounting, and L0 prefix fix remain. Main's PH3 field offsets and frozen flag-zero contract are retained in the design document. SQLite benchmarking from 37feee99 is unchanged.

All 11 gates passed again on the rebased source, including 353 debug and release library tests, fixed corpora, loom, and both complete 20,000-seed suites. No timing runs overlapped this task's builds or tests. See gate status, source hashes, and reproduction commands.

The verifier now adds only the niceness increment needed to reach nice 10. A partial run with inherited nice 19 was preserved under rebased-checks-inherited-nice19, then all 11 gates were repeated at effective nice 10. The final metadata records coordinator nice 10 and increment zero.

No task process uses sibling CPU 7, but the sibling was not established to be idle. Whole-child CPU 7 busy fractions were median 12.3% for mapped, 10.8% for pread, and 11.9% for the extra controls, with maxima 48.8%, 87.9%, and 23.2%. These samples include open and verification, so they do not isolate activity during API timers.

This is an active-host measurement, and strict idle-sibling acceptance is not established. See sibling summary and the per-child sibling.jsonl receipts.

Cold, concurrent, profiling, and write rows below retain the original five-pair campaign against 06a457db; they were not repeated against updated main. The separate write confirmation is also preserved. Those results establish the observed cold mmap tradeoff and leave durable-write p99 uncertain. The source comparison supports carrying that evidence forward, while the new three-pair warm matrix directly checks the rebased binary and main's PH3 baseline.

The frozen source patch reconstructs the archived engine and Rust readbench source from public main 37feee99, independently of old local commit reachability after rebase. Applying it to a private Git index reproduced all 40 frozen engine file hashes. See the reconstruction receipt.

Archived five-pair campaign

Engine source: 0283fc7af8cfba828ff05343c8b77bc27b228962; baseline main 06a457db. All timing children use CPU 6; build/test/coordinator processes use CPUs 12–21 at nice 10. No task work runs on sibling CPU 7. Other host workloads were active; this is not an isolated-host claim.

The opt-in configuration is CRC-bearing PH3 SSTs, point_index=true, block_cache_bytes=32 MiB, mmap_max_level=Some(u32::MAX). Both warm layout targets are evaluated on five alternating main/PH3 pairs, each side followed by its own LMDB control. Ratios use the median of within-trial ratios, rather than dividing unrelated medians. All five trials are retained. The warm read target is met; durable-write p99 non-regression remains uncertain after the additional confirmation block, as detailed below.

Warm 32 MiB layoutPaired PH3/LMDB p50Paired PH3/LMDB p99Meets ≤0.9 p50 and ≤1 p99
bulk0.6410.587True
normal0.7780.797True

Verification and read path

PH3 feature bit 0 appends an IEEE value CRC per version, preserving flag-zero PH3 and PH2 reads. Admission checks the section CRC, every sorted block CRC, exact key/MVCC/address/coverage correspondence, and each stored value CRC. External hits copy exact value bytes and CRC the owned return buffer against immutable validated metadata.

Resident full-data hits retain verified owned backing; scans and sorted fallbacks retain block verification. No mapped value is returned unchecked. See DESIGN.md.

The resident view preserves the PH3 arena and packs its hash tables (u24 pilots, no redundant fingerprints; full keys still compare). The variable locator buffer is charged exactly to the same block-cache budget; fixed table/index bookkeeping remains outside that byte accounting. Actual 32 MiB locator charges are 32,601,232 bytes bulk and 32,503,515 bytes normal.

Locator mode retains no whole-SST heap backing for values; per-call owned return buffers remain necessary. Temporary open allocations, allocator retention and the OS page cache still contribute to RSSRSSResident set size: the physical memory a process is actually using.. Inspection receipts include peak/RSS and open time.

Admitted point indexes compare complete keys directly and skip redundant Bloom probes; the Bloom section is still verified at open and remains in the sorted fallback. The immutable Version caches its L0 prefix boundary, avoiding a per-point walk across every leveled table merely to filter L0. Probe order and cross-table sequence resolution remain unchanged. mmap_max_level retains its existing level-selection and best-effort fallback semantics.

The option is explicitly enabled for mapped rows, and remains None for pread rows. Only CRC-bearing PH3 tables qualify for locator-only admission; existing PH2 and flag-zero PH3 remain readable through their original full-resident or sorted paths. Reservations are decided when a table handle opens and are not dynamically promoted after another snapshot or compaction releases budget.

Measurement conditions

Mode labels refer to Kiban; LMDB always uses its native mmap-backed engine. Warm rows run 100,000 point calls and 100,000 latest-ten calls per trial, with complete 1M-record verification. Main indexed fixtures are PH2; candidate indexed fixtures use PH3+CRC, prepared from the same seed and logical workload.

Normal compactioncompactionBackground merging of SSTs into larger sorted files, which drops old versions and keeps reads fast. topology and bytes change with the section size; the measurements include that effect. Index-off fixtures and LMDB fixtures are shared. The computed default is 449,030,592 bytes on this host (about 428.23 MiB); explicit 512 MiB is separate.

Cold rows use cold.rs: post-open madvise(DONTNEED) and file-specific posix_fadvise(DONTNEED), then 10,000 point calls with an oracle check on each result. Pages warm during those calls. Four readers share CPU 6 and exercise I/O concurrency, not four-core CPU scaling. Storage bytes/faults are retained. Main can retain verified full backing for a subset of normal-layout tables even at 32 MiB; the new locator mode uses that budget for metadata instead.

Default/512 index-on configurations retain full verified heap values through file-page eviction, so those rows are retained-resident tests, not cold-storage speedups. Open time is excluded from latency, and locator validation reads the full data region at open.

All latency tables use microseconds, median of five trials. The adjusted PH3/main columns divide each side by its adjacent LMDB control before comparing the paired results. This shows host drift but does not remove every source of noise; full min/max ranges are linked. A value above one in an adjusted column is a measured relative regression, not hidden by the headline target.

Warm point: mapped

Mapped means Some(u32::MAX); pread means None.

Layout / index / cache / readersMain p50/p99PH3 p50/p99LMDB p50/p99Paired K/L p50Adjusted PH3/main p50/p99
bulk / 0 / 32 / 13.136 / 4.6083.136 / 4.7361.504 / 2.1122.0851.000 / 0.955
bulk / 0 / 512 / 11.760 / 2.4961.728 / 2.4321.408 / 1.9201.2270.978 / 0.943
bulk / 0 / default / 11.952 / 2.7521.920 / 2.7521.536 / 2.1761.2000.935 / 0.911
bulk / 1 / 32 / 13.200 / 4.7360.944 / 1.2801.440 / 2.0160.6410.294 / 0.254
bulk / 1 / 512 / 11.056 / 1.4080.944 / 1.2161.504 / 1.9840.6410.868 / 0.861
bulk / 1 / default / 11.088 / 1.5040.960 / 1.3441.568 / 2.3040.6180.818 / 0.759
normal / 0 / 32 / 13.136 / 5.5043.072 / 5.2481.472 / 1.9842.0910.999 / 1.120
normal / 0 / 512 / 11.984 / 3.0721.888 / 2.9441.472 / 2.0161.3410.977 / 0.971
normal / 0 / default / 11.824 / 2.7521.856 / 2.8161.376 / 1.8241.3181.002 / 1.012
normal / 1 / 32 / 12.368 / 4.0961.120 / 1.6641.472 / 2.0480.7780.427 / 0.387
normal / 1 / 512 / 11.248 / 1.6961.008 / 1.3121.440 / 1.9520.7500.808 / 0.788
normal / 1 / default / 11.152 / 1.5681.024 / 1.3441.408 / 1.8880.7160.835 / 0.833

Raw trials, controls and ranges: ph3-mapped-read/SUMMARY.md.

Warm latest-ten: mapped

Layout / index / cache / readersMain p50/p99PH3 p50/p99LMDB p50/p99Paired K/L p50Adjusted PH3/main p50/p99
bulk / 0 / 32 / 13.264 / 6.1443.392 / 5.3762.752 / 4.6081.2330.952 / 0.768
bulk / 0 / 512 / 12.944 / 4.7363.072 / 4.8642.560 / 4.0321.2000.944 / 0.921
bulk / 0 / default / 13.200 / 6.0163.328 / 5.3762.752 / 4.0961.2250.974 / 0.878
bulk / 1 / 32 / 13.136 / 4.7363.008 / 4.8642.560 / 3.9681.2110.940 / 0.900
bulk / 1 / 512 / 13.200 / 5.5043.264 / 5.1202.752 / 4.4801.1860.925 / 0.849
bulk / 1 / default / 13.136 / 5.3763.328 / 5.7602.880 / 4.7361.1560.899 / 0.862
normal / 0 / 32 / 13.584 / 6.9123.776 / 6.5282.624 / 4.2241.4390.964 / 1.054
normal / 0 / 512 / 13.584 / 6.2723.520 / 6.1442.624 / 4.3521.3750.917 / 0.916
normal / 0 / default / 13.392 / 5.5043.584 / 5.6322.432 / 3.9681.4590.972 / 0.943
normal / 1 / 32 / 13.584 / 6.4003.200 / 5.3762.624 / 4.2241.2200.720 / 0.713
normal / 1 / 512 / 13.392 / 6.0163.008 / 5.2482.496 / 4.2241.2050.809 / 0.786
normal / 1 / default / 13.264 / 6.0163.072 / 5.1202.432 / 3.8401.2630.811 / 0.725

Raw trials, controls and ranges: ph3-mapped-read/SUMMARY.md.

Cold-start point: mapped

Default/512 index-on rows retain heap values.

Layout / index / cache / readersMain p50/p99PH3 p50/p99LMDB p50/p99Paired K/L p50Adjusted PH3/main p50/p99
bulk / 0 / 32 / 13.392 / 655.3603.584 / 655.3603.904 / 1114.1120.9661.073 / 1.059
bulk / 0 / 32 / 43.584 / 2162.6883.520 / 2162.6883.904 / 3407.8720.9171.034 / 0.944
bulk / 0 / 512 / 13.264 / 638.9763.200 / 638.9763.776 / 1081.3440.8451.043 / 1.042
bulk / 0 / 512 / 43.456 / 2228.2243.456 / 2228.2243.840 / 3276.8000.9001.047 / 1.024
bulk / 0 / default / 13.264 / 638.9763.264 / 671.7443.968 / 1114.1120.8771.032 / 0.988
bulk / 0 / default / 43.264 / 2162.6883.392 / 2064.3843.840 / 3276.8000.8831.000 / 1.016
bulk / 1 / 32 / 13.584 / 688.1281.344 / 606.2084.096 / 1146.8800.3310.376 / 0.900
bulk / 1 / 32 / 43.648 / 2359.2961.280 / 1540.0963.648 / 3145.7280.3510.351 / 0.663
bulk / 1 / 512 / 1 †1.152 / 1.4720.976 / 1.2485.120 / 1212.4160.1910.851 / 0.932
bulk / 1 / 512 / 4 †1.184 / 1.5041.008 / 1.3765.376 / 3866.6240.1920.873 / 0.962
bulk / 1 / default / 1 †1.152 / 1.4400.944 / 1.2484.992 / 1212.4160.1860.789 / 0.778
bulk / 1 / default / 4 †1.184 / 1.5041.008 / 1.3125.248 / 3735.5520.1920.806 / 0.862
normal / 0 / 32 / 13.904 / 606.2083.776 / 589.8244.480 / 1146.8800.8330.989 / 0.949
normal / 0 / 32 / 43.968 / 2752.5124.096 / 2686.9764.608 / 3670.0160.8711.003 / 0.945
normal / 0 / 512 / 13.584 / 589.8243.520 / 589.8244.736 / 1179.6480.7431.006 / 0.950
normal / 0 / 512 / 43.712 / 2424.8323.712 / 2555.9044.736 / 3604.4800.7761.000 / 1.057
normal / 0 / default / 13.520 / 589.8243.520 / 557.0564.608 / 1114.1120.7861.037 / 0.944
normal / 0 / default / 43.648 / 2555.9043.712 / 2686.9764.864 / 3866.6240.7631.027 / 1.015
normal / 1 / 32 / 13.712 / 557.0561.536 / 720.8964.992 / 1179.6480.3080.418 / 1.294
normal / 1 / 32 / 43.776 / 2686.9761.504 / 2097.1525.248 / 3735.5520.2940.434 / 0.808
normal / 1 / 512 / 1 †1.440 / 1.9201.184 / 1.6005.376 / 1179.6480.2150.803 / 0.750
normal / 1 / 512 / 4 †1.472 / 1.8561.184 / 1.6005.248 / 3670.0160.2200.809 / 0.888
normal / 1 / default / 1 †1.408 / 1.8561.152 / 1.6325.376 / 1146.8800.2190.808 / 0.850
normal / 1 / default / 4 †1.472 / 1.9521.216 / 1.6645.376 / 3670.0160.2260.792 / 0.875

† Retained verified heap backing; file-page eviction does not make these values cold.

Raw trials, controls and ranges: ph3-mapped-cold/SUMMARY.md.

Warm point: pread

Mapped means Some(u32::MAX); pread means None.

Layout / index / cache / readersMain p50/p99PH3 p50/p99LMDB p50/p99Paired K/L p50Adjusted PH3/main p50/p99
bulk / 0 / 32 / 13.712 / 5.3763.968 / 5.7601.472 / 2.0162.5710.952 / 0.909
bulk / 0 / 512 / 11.920 / 2.9441.888 / 2.8161.440 / 2.3041.3180.949 / 0.884
bulk / 0 / default / 11.888 / 2.6881.952 / 2.8161.504 / 2.1121.2770.963 / 0.901
bulk / 1 / 32 / 13.968 / 6.2721.504 / 2.3041.408 / 1.8881.0240.398 / 0.374
bulk / 1 / 512 / 10.912 / 1.2480.864 / 1.1201.344 / 1.8880.6430.921 / 0.921
bulk / 1 / default / 11.120 / 1.4400.976 / 1.2481.568 / 2.2400.6220.904 / 0.945
normal / 0 / 32 / 13.968 / 6.4003.968 / 6.4001.440 / 2.1122.8441.000 / 1.012
normal / 0 / 512 / 11.888 / 3.0081.888 / 3.0081.408 / 1.9521.4050.968 / 0.894
normal / 0 / default / 11.984 / 3.3281.856 / 2.8801.408 / 2.0481.3490.967 / 0.914
normal / 1 / 32 / 13.456 / 5.5041.664 / 2.4321.568 / 2.3041.1180.462 / 0.422
normal / 1 / 512 / 11.184 / 1.6001.056 / 1.4401.344 / 1.7920.7560.944 / 1.106
normal / 1 / default / 11.216 / 1.7601.056 / 1.3761.408 / 1.8880.7080.820 / 0.796

Raw trials, controls and ranges: ph3-pread-read/SUMMARY.md.

Warm latest-ten: pread

Layout / index / cache / readersMain p50/p99PH3 p50/p99LMDB p50/p99Paired K/L p50Adjusted PH3/main p50/p99
bulk / 0 / 32 / 12.880 / 5.3763.200 / 4.9922.624 / 4.3521.2000.971 / 0.894
bulk / 0 / 512 / 12.944 / 6.0163.072 / 5.8882.560 / 4.9921.2110.952 / 0.955
bulk / 0 / default / 13.008 / 4.7363.200 / 5.1202.752 / 4.4801.1900.913 / 0.992
bulk / 1 / 32 / 13.008 / 5.8883.072 / 5.3762.560 / 4.2241.2110.941 / 0.916
bulk / 1 / 512 / 12.816 / 4.7362.880 / 4.8642.432 / 3.8401.1841.013 / 1.061
bulk / 1 / default / 13.136 / 5.5043.328 / 6.0162.624 / 4.6081.1820.956 / 1.016
normal / 0 / 32 / 13.520 / 5.8883.520 / 6.0162.432 / 4.2241.4210.904 / 1.005
normal / 0 / 512 / 13.392 / 6.0163.200 / 5.7602.368 / 3.7761.4290.933 / 0.982
normal / 0 / default / 13.520 / 6.4003.584 / 5.7602.432 / 4.2241.4740.974 / 1.056
normal / 1 / 32 / 13.392 / 6.4003.008 / 5.6322.624 / 4.7361.1780.793 / 0.731
normal / 1 / 512 / 13.264 / 5.3763.328 / 5.5042.368 / 3.7121.3330.972 / 1.033
normal / 1 / default / 13.264 / 5.5043.136 / 4.9922.624 / 4.4801.1860.830 / 0.781

Raw trials, controls and ranges: ph3-pread-read/SUMMARY.md.

Cold-start point: pread

Default/512 index-on rows retain heap values.

Layout / index / cache / readersMain p50/p99PH3 p50/p99LMDB p50/p99Paired K/L p50Adjusted PH3/main p50/p99
bulk / 0 / 32 / 17.168 / 434.1766.912 / 450.5605.248 / 1179.6481.3500.976 / 1.019
bulk / 0 / 32 / 47.040 / 540.6727.040 / 507.9045.248 / 3735.5521.3411.000 / 0.984
bulk / 0 / 512 / 17.552 / 557.0567.168 / 466.9445.248 / 1277.9521.3660.968 / 0.850
bulk / 0 / 512 / 47.040 / 1114.1127.296 / 1376.2565.504 / 4980.7361.4361.070 / 1.120
bulk / 0 / default / 17.040 / 417.7927.296 / 425.9845.120 / 1179.6481.4151.018 / 0.983
bulk / 0 / default / 47.424 / 557.0567.040 / 540.6725.376 / 4063.2321.3100.948 / 0.938
bulk / 1 / 32 / 17.296 / 458.7523.584 / 417.7925.376 / 1245.1840.6830.491 / 0.963
bulk / 1 / 32 / 47.296 / 540.6723.264 / 434.1765.248 / 3735.5520.6340.456 / 0.849
bulk / 1 / 512 / 1 †1.120 / 1.3760.912 / 1.1525.248 / 1212.4160.1700.781 / 0.813
bulk / 1 / 512 / 4 †1.152 / 1.4080.960 / 1.3445.120 / 3538.9440.1840.833 / 1.013
bulk / 1 / default / 1 †1.120 / 1.3760.912 / 1.1525.120 / 1114.1120.1780.814 / 0.791
bulk / 1 / default / 4 †1.120 / 1.4080.912 / 1.1845.120 / 3538.9440.1810.829 / 0.834
normal / 0 / 32 / 18.448 / 417.7928.448 / 417.7925.120 / 1212.4161.6000.923 / 0.974
normal / 0 / 32 / 48.064 / 507.9048.448 / 557.0564.992 / 3866.6241.6921.052 / 1.104
normal / 0 / 512 / 17.424 / 466.9447.680 / 466.9444.992 / 1114.1121.5251.068 / 1.022
normal / 0 / 512 / 48.704 / 589.8248.960 / 655.3605.504 / 4194.3041.6001.016 / 1.179
normal / 0 / default / 17.808 / 475.1367.680 / 466.9445.120 / 1114.1121.4750.968 / 1.006
normal / 0 / default / 47.808 / 540.6727.680 / 540.6725.248 / 3801.0881.4631.000 / 1.034
normal / 1 / 32 / 17.552 / 434.1764.864 / 393.2165.248 / 1146.8800.9270.677 / 0.938
normal / 1 / 32 / 47.424 / 499.7124.224 / 491.5205.376 / 3932.1600.7860.576 / 1.034
normal / 1 / 512 / 1 †1.472 / 1.9521.184 / 1.6645.504 / 1212.4160.2160.810 / 0.909
normal / 1 / 512 / 4 †1.504 / 2.0481.216 / 1.6325.504 / 3866.6240.2150.787 / 0.751
normal / 1 / default / 1 †1.408 / 1.9201.120 / 1.6325.248 / 1146.8800.2130.795 / 0.784
normal / 1 / default / 4 †1.408 / 1.9201.120 / 1.6005.248 / 3538.9440.2190.815 / 0.890

† Retained verified heap backing; file-page eviction does not make these values cold.

Raw trials, controls and ranges: ph3-pread-cold/SUMMARY.md.

10k writes

Each trial starts from a fresh 10k-record fixture and uses 10,000 operations per harness stage, both fast and durable modes, with index off/on. The write helper keeps its existing default cache/mapping settings; these populations fit the cache. Remember and update each perform 10,000 writes; mixed-90-10 performs 1,000 writes and 9,000 reads, with separate histograms retained in raw receipts. Flush/sync/final verification are outside call timers and retained in completion receipts.

Index / durable / stageMain p50/p99PH3 p50/p99LMDB p50/p99Adjusted PH3/main p50/p99
0 / 0 / mixed-90-100.800 / 2.3680.864 / 2.3680.976 / 8.7041.033 / 0.971
0 / 0 / recall-by-id0.848 / 1.9200.880 / 2.0480.944 / 1.2481.001 / 1.100
0 / 0 / recent-for-agent3.328 / 5.5043.520 / 5.7602.880 / 4.7360.965 / 0.872
0 / 0 / remember0.784 / 6.0160.768 / 6.0167.552 / 12.0320.980 / 1.044
0 / 0 / update1.088 / 6.6561.120 / 6.6567.936 / 11.0081.000 / 1.029
0 / 1 / mixed-90-101.728 / 655.3601.856 / 688.1281.888 / 1703.9361.035 / 0.928
0 / 1 / recall-by-id0.880 / 1.9841.008 / 2.2400.896 / 1.4721.293 / 1.319
0 / 1 / recent-for-agent3.136 / 4.9923.904 / 7.9362.688 / 4.2241.297 / 1.809
0 / 1 / remember573.440 / 3080.192589.824 / 7077.8881245.184 / 9699.3281.056 / 3.795
0 / 1 / update573.440 / 3276.800589.824 / 5505.0241310.720 / 11272.1921.003 / 1.404
1 / 0 / mixed-90-100.800 / 1.6000.832 / 1.6000.992 / 8.7041.040 / 1.044
1 / 0 / recall-by-id0.800 / 1.2480.768 / 1.1840.992 / 1.5040.924 / 1.011
1 / 0 / recent-for-agent3.264 / 6.1443.520 / 6.4002.944 / 4.6080.968 / 1.028
1 / 0 / remember0.784 / 6.1440.784 / 6.4008.064 / 13.3120.980 / 1.062
1 / 0 / update1.088 / 6.6561.184 / 7.4247.936 / 11.2641.088 / 1.141
1 / 1 / mixed-90-101.760 / 1146.8801.632 / 819.2001.792 / 2359.2960.878 / 1.490
1 / 1 / recall-by-id0.784 / 1.4720.720 / 1.3760.896 / 1.5040.875 / 1.396
1 / 1 / recent-for-agent3.008 / 5.8883.072 / 5.6322.624 / 4.0320.937 / 1.213
1 / 1 / remember573.440 / 6291.456589.824 / 4849.6641245.184 / 11272.1920.937 / 1.066
1 / 1 / update589.824 / 5767.168557.056 / 3014.6561245.184 / 11010.0480.971 / 0.547
Index / durableMain end sync+flush+verify msPH3 msLMDB main-control msLMDB candidate-control ms
0 / 097.13898.13163.30564.021
0 / 180.31085.20323.44323.505
1 / 056.95058.24550.21150.737
1 / 1112.325100.01622.40422.470

Write confirmation

A second five-pair block uses the same active database path for both labels. It confirms fast indexed insert/update controls and repeats the uncertain unindexed durable case. The original run is retained in full; neither run replaces the other.

Index / durable / stageConfirm main p50/p99Confirm PH3 p50/p99LMDB p50/p99Adjusted PH3/main p50/p99
0 / 1 / remember557.056 / 5636.096557.056 / 3932.1601245.184 / 9699.3281.013 / 0.902
0 / 1 / update557.056 / 3538.944573.440 / 3932.1601245.184 / 11272.1921.002 / 1.140
1 / 0 / remember0.608 / 4.7360.592 / 4.7365.888 / 9.4720.974 / 1.000
1 / 0 / update0.848 / 5.5040.816 / 5.2486.272 / 8.7040.962 / 0.953

The fast indexed update slowdown does not reproduce: confirmation p50/p99 improves 0.848/5.504 to 0.816/5.248 us. Durable unindexed insert p99 changes direction (original 3.080 to 7.078 ms; confirmation 5.636 to 3.932 ms). Durable update confirmation p50 stays close (557 to 573 us), but p99 remains higher (3.539 to 3.932 ms; adjusted ratio 1.140).

The host data do not establish a durable-write p99 no-regression guarantee. All stored values and final 20k-record states verify. This uncertainty is separate from the passing warm read target and passing correctness gates.

Write trials and ranges, confirmation and ranges.

Profiling

Round 2 already rejected verified mapped points: bulk/32 improved 3.840/6.528 to 2.432/3.584 us and normal/32 4.096/7.296 to 2.688/4.352, but all remained behind LMDB; normal/512 p50 rose 2.368 to 2.688 us. Its four-reader cold mapped p99 was 2949.120 us versus pread 589.824 us in the same prototype. Those prior results use CPU 3 and are historical, not comparable absolute timings for this CPU-6 campaign.

This implementation retains full verified heap backing when the dataset fits, uses resident exact locators when it does not, and checks every returned external value rather than caching a per-block verification bit. The new cold/larger-cache matrices are required to judge the old tradeoffs. See round-2 rejection.

The original 32 MiB sorted path used about 9,916/10,432 user cycles and 13,881/15,447 instructions per bulk/normal operation, versus LMDB 5,154/5,614 cycles and 7,893 instructions. Exclusive samples placed about 13% in cache insertion, 8–13% in block loading and 5% in block CRC, with routing/index/seek work in the inlined getter. See baseline-profile and profile-summary.json.

The rejected PH2-derived path already used per-value CRCs, derived at open. Its remaining mapped profile put 18–22% of samples in memmove and about 2–3% in CRC, with locator reconstruction in the inlined getter. Normal routing sampled at 11.86%. PH3 removes key reconstruction, and the L0 prefix removes a topology-sized filter walk.

These samples identify hot code; they are not exact nanosecond attribution. DWARF reconstruction was incomplete and perf lost samples; raw coverage/loss receipts are preserved. User-only counters exclude kernel syscall instructions.

Full-path final counters and stacks: ph3-pread-profile and ph3-mapped-profile. Syscall interposition is diagnostic only: it counts positioned-read calls/bytes/time inside the perf FIFO operation boundary and includes clock overhead. It is never enabled for latency trials. The isolated component results overlap and must not be added into a full-read prediction.

Final profile / modeLoop mean usUser cycles/opInstructions/opLLC misses/opBranch misses/op
before-bulk-kiban / pread3.6479744.013881.24.7415.959
before-bulk-lmdb / pread1.4035099.37893.412.09910.069
before-normal-kiban / pread3.1608156.915559.12.62213.094
before-normal-lmdb / pread1.2274718.37893.49.82710.041
ph3-bulk-kiban / pread1.2453052.66429.62.0361.983
ph3-bulk-lmdb / pread1.3935143.07893.412.03411.139
ph3-normal-kiban / pread1.8335035.87349.43.5905.705
ph3-normal-lmdb / pread1.3535967.37893.413.68111.864
before-bulk-kiban / mapped2.77512003.213168.141.5635.161
before-bulk-lmdb / mapped1.3825988.07893.414.29410.089
before-normal-kiban / mapped2.2459615.314503.840.91310.070
before-normal-lmdb / mapped1.3285867.57893.413.73610.070
ph3-bulk-kiban / mapped0.8643839.85641.58.1541.988
ph3-bulk-lmdb / mapped1.2945751.37893.412.86411.083
ph3-normal-kiban / mapped1.0124485.56260.98.4343.235
ph3-normal-lmdb / mapped1.4355387.87893.413.62711.768
Syscall probe / modepread calls / millionReturned bytes / millionDiagnostic pread ns/call
before-bulk-kiban / pread89651437779748851532.9
before-bulk-lmdb / pread000.0
before-normal-kiban / pread91653838612646841981.6
before-normal-lmdb / pread000.0
ph3-bulk-kiban / pread1000000296732188519.3
ph3-bulk-lmdb / pread000.0
ph3-normal-kiban / pread1000000296732188456.3
ph3-normal-lmdb / pread000.0
before-bulk-kiban / mapped000.0
before-bulk-lmdb / mapped000.0
before-normal-kiban / mapped000.0
before-normal-lmdb / mapped000.0
ph3-bulk-kiban / mapped000.0
ph3-bulk-lmdb / mapped000.0
ph3-normal-kiban / mapped000.0
ph3-normal-lmdb / mapped000.0
Isolated unchanged-path componentns/op
bloom62.6
index278.6
verify-block600.5
cache329.8
hash30.1
block-seek680.3
copy25.2
crc-value19.3

Rejected experiments and gates

The private PH2-derived locator candidate is preserved only as experiments/ph2-locators.patch. Its final pread paired K/LMDB point p50 ratios were 1.065 bulk and 1.532 normal, missing the stricter target. Earlier bulk pilot p50/p99 improved 3.712/5.504 to 1.536/2.176 us, versus LMDB 1.344/1.824; near parity was explicitly rejected. Historical final-* directories, development receipts and old source hashes refer to that experiment, not this PH3 source.

The first frozen PH3 candidate, with the Bloom precheck retained, missed the full normal target: paired p50/p99 ratios 0.930/0.864, despite bulk 0.800/0.759. The pipeline stopped before cold/writes; all 240 warm commands remain in ph3-before-bloom-read. The direct no-Bloom pilot against that source reduced bulk paired p50 K/L from 0.857 to 0.732 and normal from 0.829 to 0.791.

Its p99 ratios remain below LMDB, and all trials are retained in no-bloom-pilot. The earlier PH3 mapped pilot before the L0 change measured 1.152/1.536 us bulk versus LMDB 1.504/2.240 and 1.248/1.600 us normal versus LMDB 1.440/2.176; paired p50 ratios 0.795/0.886.

It was superseded by the frozen full matrix above. A missing-SST classification failure in the earlier candidate was fixed at the admission prepass root, preserving DbError::Corrupt. It was a caught development regression, not an existing-engine integrity bug. decisions.tsv records the parent clarification and fix.

All 11 final-source gates passed: fmt, clippy -D warnings, debug and release workspace tests (353 library tests), fixed crash corpora, loom, site facts, readbench checks, and both 20,000-seed suites. New tests cover mixed PH2/PH3 flags, snapshots, tombstones, binary/empty keys, address widths, checksum metadata corruption with recomputed section CRC, pre-open backing corruption, post-open repeated mapped/pread value corruption, short pread, concurrent reads after unlink, address-space eligibility, and exact reservation release.

See gate receipts, source hashes, provenance, design, and reproduction.

Across modes, the candidate four-reader cold p99 is also higher with mmap: bulk 1540.096 us versus pread 434.176 us, normal 2097.152 us versus pread 491.520 us (about 3.5x and 4.3x).

The existing option lets deployments choose this warm-page-cache advantage explicitly, and the report separately measures pread. Open-time validation, mixed old tables, and snapshot-dependent admission also argue against a default change. The complete acceptance decision and any other material controls are recorded in decisions.tsv.