# Performance Every number here was produced by `src/crates/bb-bench` and recorded as a baseline under `bench/baselines/`. Later runs on the same machine are compared against that file; CI compares allocations on every push. See `bench/README.md` for the workflow. ## How to run ```powershell .\build.ps1 -Config release cargo build --release -p bb-bench $bench = "target\release\bb-bench.exe" & $bench run # Tier A, default job (long; --filter *pathkey* to narrow) & $bench run --job short # Tier A, quick pass & $bench ui --repeat 5 # Tier B, each tools/ui/bench-*.bbs five times through bb-harness & $bench ui --scenario memory # Tier B, just the memory scenario (idle, 10k, 20k flat, soaks) & $bench startup --launches 10 # Tier C, the real BertBrowser.exe: time and memory (a window is shown offscreen) & $bench compare --baseline bench\baselines\.json --current bench-results\current.json & $bench baseline --from bench-results\current.json --from bench-results\ui.json --from bench-results\startup.json & $bench report # this file ``` How to read the native numbers next to the .NET ones in `docs/performance.md` of the `bertbrowser-csharp-archive` repository: - **Allocated/op** is exact: a counting global allocator sums the bytes requested by one operation, so it does not vary between runs. **Allocs/kop** is *allocator calls per thousand operations*, where the .NET tables have Gen0/kop. - **Rust allocator** and **Process heap** in the Tier B and C snapshots together stand where the .NET tables have "Managed heap", and neither is the same kind of number: see the end of this document. - The synthetic corpus has the same shape as the .NET one (100,000 rows under `Q:`, the same queries and sizes) but is cut from this crate's own random stream, so rows are the same kind of disk, not the same disk. - Tier A has no counterpart yet for the archive index, MFT builder, change log, folder comparison and content scan suites; the digests run over the 64 MB file through the public API, since the sinks are crate-private. ## amd-ryzen-9-3900x-12-core-24c-32gb-w26200-net1.99-7456a9ba | | | |---|---| | CPU | AMD Ryzen 9 3900X 12-Core Processor, 24 logical cores | | RAM | 32 GB | | Windows build | 26200 | | Rust | 1.99.1 | | Power plan | High performance | | Corpus | synthetic, scale 1 (100,000 rows) | | Job | default, counting-allocator toolchain | | Recorded | 2026-10-31 at `c616bc784` (uncommitted changes) | ### Tier A — Core micro-benchmarks | Benchmark | Median | p95 | Allocated/op | Allocs/kop | n | |---|---:|---:|---:|---:|---:| | `core.db.open` | 44.0 ns | 45.2 ns | 0 B | 0 | 15 | | `core.db.openwithoutpragmas` | 74.9 µs | 79.1 µs | 100 B | 2000 | 15 | | `core.delete.plan1000(mode=Permanent)` | 673 µs | 700 µs | 376 KB | 9089000 | 15 | | `core.delete.plan1000(mode=Recycle)` | 681 µs | 769 µs | 376 KB | 9089000 | 15 | | `core.digest.append64mb(algorithm=Crc32)` | 16.4 ms | 18.8 ms | 1.00 MB | 8000 | 15 | | `core.digest.append64mb(algorithm=Md5)` | 115 ms | 118 ms | 1.00 MB | 8000 | 15 | | `core.digest.append64mb(algorithm=Sha1)` | 42.1 ms | 45.7 ms | 1.00 MB | 8000 | 15 | | `core.digest.append64mb(algorithm=Sha256)` | 44.4 ms | 45.3 ms | 1.00 MB | 8000 | 15 | | `core.digest.append64mb(algorithm=Sha512)` | 131 ms | 136 ms | 1.00 MB | 8000 | 15 | | `core.dirsize.getmany(n=2000)` | 4.42 ms | 4.75 ms | 1.16 MB | 10006000 | 15 | | `core.dirsize.getmany(n=50)` | 78.7 µs | 80.4 µs | 22.0 KB | 256000 | 15 | | `core.dirsizewrite.upsertmany10k` | 20.5 ms | 28.7 ms | 0 B | 0 | 15 | | `core.filelistdiff.compute10k` | 2.71 ms | 3.13 ms | 1.62 MB | 30420000 | 15 | | `core.filesystem.listdirectory` | 6.36 ms | 6.68 ms | 2.90 MB | 40021000 | 15 | | `core.fsindex.search(query=dm:2026-09-15)` | 7.91 ms | 8.42 ms | 215 KB | 4220000 | 15 | | `core.fsindex.search(query=ext:txt)` | 4.86 ms | 5.04 ms | 877 KB | 18448000 | 15 | | `core.fsindex.search(query=re:^img_)` | 15.7 ms | 16.5 ms | 1.92 MB | 59473000 | 15 | | `core.fsindex.search(query=report ext:cs size:>1kb)` | 7.27 ms | 7.64 ms | 11.2 KB | 227000 | 15 | | `core.fsindex.search(query=report)` | 8.08 ms | 8.64 ms | 183 KB | 3376000 | 15 | | `core.fsindex.search(query=size:>100gb)` | 6.77 ms | 6.92 ms | 1.27 KB | 14000 | 15 | | `core.fsindex.search(query=size:>100mb)` | 7.32 ms | 7.61 ms | 138 KB | 2443000 | 15 | | `core.fsindex.searchglobal(query=dm:2026-09-15)` | 47.7 ms | 49.6 ms | 945 KB | 17669000 | 15 | | `core.fsindex.searchglobal(query=ext:txt)` | 7.68 ms | 8.19 ms | 992 KB | 19132000 | 15 | | `core.fsindex.searchglobal(query=re:^img_)` | 63.8 ms | 67.0 ms | 6.25 MB | 182116000 | 15 | | `core.fsindex.searchglobal(query=report ext:cs size:>1kb)` | 35.6 ms | 37.3 ms | 59.4 KB | 1012000 | 15 | | `core.fsindex.searchglobal(query=report)` | 52.3 ms | 55.7 ms | 816 KB | 14511000 | 15 | | `core.fsindex.searchglobal(query=size:>100gb)` | 31.0 ms | 39.7 ms | 1.12 KB | 9000 | 15 | | `core.fsindex.searchglobal(query=size:>100mb)` | 44.4 ms | 45.8 ms | 660 KB | 11718000 | 15 | | `core.fsindexscan.duplicatecandidates` | 7.77 ms | 8.67 ms | 34.2 KB | 15000 | 15 | | `core.fsindexscan.findcoveringroot` | 14.1 µs | 14.8 µs | 688 B | 11000 | 15 | | `core.fsindexscan.hassizedata` | 9.60 µs | 10.1 µs | 38 B | 4000 | 15 | | `core.fsindexscan.subtree` | 13.3 ms | 14.4 ms | 4.59 MB | 53179000 | 15 | | `core.fsindexwrite.upsert20k` | 105 ms | 117 ms | 252 KB | 20000000 | 15 | | `core.gif.next60frames` | 636 µs | 648 µs | 17.9 MB | 64000 | 15 | | `core.gif.nextshared60frames` | 266 µs | 277 µs | 354 KB | 4000 | 15 | | `core.glob.wildcardmatch10k` | 289 µs | 297 µs | 0 B | 0 | 15 | | `core.hash.hashfile64mb` | 44.4 ms | 45.6 ms | 1.00 MB | 5000 | 15 | | `core.hash.hashprefix64k` | 11.1 ms | 11.3 ms | 100 MB | 500000 | 15 | | `core.pathkey.canonicalizedeep` | 124 ns | 133 ns | 85 B | 1000 | 15 | | `core.pathkey.canonicalizeshort` | 48.2 ns | 59.6 ns | 24 B | 1000 | 15 | | `core.pathkey.canonicalizetrailing` | 97.9 ns | 101 ns | 60 B | 1000 | 15 | | `core.pathkey.isunderkeyloop` | 107 µs | 110 µs | 0 B | 0 | 15 | | `core.pathkey.isunderloop` | 3.00 ms | 3.06 ms | 1.44 MB | 50000000 | 15 | | `core.pathkey.prefixbounds` | 105 ns | 115 ns | 155 B | 3000 | 15 | | `core.preview.readhex5000rows` | 2.15 ms | 2.39 ms | 1.07 MB | 10002000 | 15 | | `core.preview.readtext1mb` | 2.13 ms | 2.16 ms | 2.43 MB | 3000 | 15 | | `core.rename.planliteral1000` | 1.72 ms | 1.76 ms | 1.15 MB | 25063000 | 15 | | `core.rename.plannumbered1000` | 1.78 ms | 2.08 ms | 1.15 MB | 31089000 | 15 | | `core.searchgrammar.compile(query=content:todo OR ext:md)` | 195 ns | 232 ns | 286 B | 7000 | 15 | | `core.searchgrammar.compile(query=dm:2026-09-15)` | 203 ns | 228 ns | 296 B | 7000 | 15 | | `core.searchgrammar.compile(query=ext:txt)` | 188 ns | 239 ns | 277 B | 7000 | 15 | | `core.searchgrammar.compile(query=re:^img_)` | 25.1 ns | 29.1 ns | 8 B | 1000 | 15 | | `core.searchgrammar.compile(query=report OR draft OR final ext:docx;pdf;txt size:>1kb !archive dm:2024 path:source is:file)` | 1.12 µs | 1.14 µs | 1.52 KB | 34000 | 15 | | `core.searchgrammar.compile(query=report ext:cs size:>1kb)` | 353 ns | 530 ns | 388 B | 12000 | 15 | | `core.searchgrammar.compile(query=report)` | 119 ns | 134 ns | 264 B | 5000 | 15 | | `core.searchgrammar.compile(query=size:>100gb)` | 137 ns | 138 ns | 288 B | 5000 | 15 | | `core.searchgrammar.compile(query=size:>100mb)` | 135 ns | 153 ns | 288 B | 5000 | 15 | | `core.searchgrammar.matches10k(query=content:todo OR ext:md)` | 215 µs | 220 µs | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=dm:2026-09-15)` | 69.7 µs | 70.4 µs | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=ext:txt)` | 94.4 µs | 96.0 µs | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=re:^img_)` | 252 µs | 269 µs | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=report OR draft OR final ext:docx;pdf;txt size:>1kb !archive dm:2024 path:source is:file)` | 1.12 ms | 1.13 ms | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=report ext:cs size:>1kb)` | 393 µs | 395 µs | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=report)` | 341 µs | 347 µs | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=size:>100gb)` | 67.7 µs | 68.0 µs | 0 B | 0 | 15 | | `core.searchgrammar.matches10k(query=size:>100mb)` | 66.8 µs | 68.7 µs | 0 B | 0 | 15 | | `core.searchgrammar.parse(query=content:todo OR ext:md)` | 432 ns | 705 ns | 664 B | 13000 | 15 | | `core.searchgrammar.parse(query=dm:2026-09-15)` | 1.55 µs | 1.61 µs | 153 B | 7000 | 15 | | `core.searchgrammar.parse(query=ext:txt)` | 212 ns | 248 ns | 165 B | 6000 | 15 | | `core.searchgrammar.parse(query=re:^img_)` | 9.97 µs | 10.1 µs | 20.8 KB | 175000 | 15 | | `core.searchgrammar.parse(query=report OR draft OR final ext:docx;pdf;txt size:>1kb !archive dm:2024 path:source is:file)` | 3.16 µs | 3.37 µs | 3.30 KB | 51000 | 15 | | `core.searchgrammar.parse(query=report ext:cs size:>1kb)` | 564 ns | 623 ns | 956 B | 16000 | 15 | | `core.searchgrammar.parse(query=report)` | 172 ns | 179 ns | 94 B | 5000 | 15 | | `core.searchgrammar.parse(query=size:>100gb)` | 313 ns | 318 ns | 87 B | 7000 | 15 | | `core.searchgrammar.parse(query=size:>100mb)` | 307 ns | 319 ns | 87 B | 7000 | 15 | | `core.textdecode.decode(kind=binary)` | 2.66 µs | 2.94 µs | 0 B | 0 | 15 | | `core.textdecode.decode(kind=latin1)` | 2.69 ms | 2.95 ms | 2.43 MB | 3000 | 15 | | `core.textdecode.decode(kind=utf16)` | 1.49 ms | 1.53 ms | 1.93 MB | 4000 | 15 | | `core.textdecode.decode(kind=utf8)` | 2.06 ms | 2.09 ms | 1.43 MB | 2000 | 15 | | `core.tokenize.tokenize1mb(language=CSharp)` | 8.96 ms | 9.47 ms | 10.0 MB | 20000 | 15 | | `core.tokenize.tokenize1mb(language=Json)` | 7.74 ms | 8.35 ms | 16.0 MB | 21000 | 15 | | `core.transfer.expandmerge4000` | 2.25 ms | 2.50 ms | 3.87 MB | 56798000 | 15 | | `core.transfer.plan1000` | 1.03 ms | 1.04 ms | 707 KB | 16037000 | 15 | ### Tier B — UI scenarios (offscreen harness) | Scenario | Median | p95 | n | |---|---:|---:|---:| | `ui.flat-20k.flat.off` | 21.2 ms | 22.5 ms | 5 | | `ui.flat-20k.flat.on` | 281 ms | 284 ms | 5 | | `ui.flat-20k.flat.sort.name` | 17.4 ms | 17.4 ms | 5 | | `ui.flat-20k.flat.sort.size` | 17.6 ms | 17.8 ms | 5 | | `ui.listing-10k.back` | 33.8 ms | 33.9 ms | 5 | | `ui.listing-10k.list` | 39.4 ms | 41.8 ms | 5 | | `ui.listing-10k.refresh` | 32.7 ms | 33.8 ms | 5 | | `ui.listing-10k.up` | 16.3 ms | 16.3 ms | 5 | | `ui.preview.preview.code` | 175 ms | 175 ms | 5 | | `ui.preview.preview.hex2mb` | 242 ms | 288 ms | 5 | | `ui.preview.preview.png` | 177 ms | 178 ms | 5 | | `ui.preview.preview.text2mb` | 179 ms | 180 ms | 5 | | `ui.search-local.search.clear` | 18.8 ms | 19.3 ms | 5 | | `ui.search-local.search.ext` | 48.8 ms | 49.7 ms | 5 | | `ui.search-local.search.regex` | 50.5 ms | 77.7 ms | 5 | | `ui.search-local.search.word` | 58.5 ms | 60.8 ms | 5 | | `ui.sort-select-10k.select.all` | 15.3 ms | 16.5 ms | 5 | | `ui.sort-select-10k.select.files` | 22.6 ms | 23.2 ms | 5 | | `ui.sort-select-10k.select.invert` | 23.0 ms | 24.0 ms | 5 | | `ui.sort-select-10k.select.none` | 10.2 ms | 10.9 ms | 5 | | `ui.sort-select-10k.sort.first` | 14.0 ms | 14.0 ms | 5 | | `ui.sort-select-10k.sort.modified` | 13.9 ms | 14.4 ms | 5 | | `ui.sort-select-10k.sort.name` | 13.7 ms | 13.9 ms | 5 | | `ui.sort-select-10k.sort.size` | 13.9 ms | 14.0 ms | 5 | | `ui.sort-select-10k.sort.type` | 53.5 ms | 55.3 ms | 5 | | `ui.startup.startup.hosted` | 78.9 ms | 81.6 ms | 5 | | `ui.tabs-panes.pane.close` | 36.0 ms | 40.5 ms | 5 | | `ui.tabs-panes.pane.split` | 25.3 ms | 27.5 ms | 5 | | `ui.tabs-panes.pane.switch` | 20.9 ms | 21.0 ms | 5 | | `ui.tabs-panes.tab.close` | 13.9 ms | 13.9 ms | 5 | | `ui.tabs-panes.tab.new` | 24.1 ms | 25.1 ms | 5 | | `ui.tabs-panes.tab.switch` | 13.5 ms | 13.8 ms | 5 | | `ui.tiles-5k.tiles.back` | 17.2 ms | 17.8 ms | 5 | | `ui.tiles-5k.tiles.large` | 139 ms | 140 ms | 5 | | `ui.tiles-5k.tiles.on` | 141 ms | 143 ms | 5 | | `ui.tiles-5k.tiles.scroll` | 33.4 ms | 37.4 ms | 5 | | `ui.transfer-2k.copy.2k` | 1.17 s | 1.19 s | 5 | | `ui.transfer-2k.delete.2k` | 952 ms | 962 ms | 5 | | Memory snapshot | Rust allocator | Process heap | Private bytes | Working set | Peak working set | Items | Realized | n | |---|---:|---:|---:|---:|---:|---:|---:|---:| | `ui.flat-20k.flat` | 4.10 MB | 6.34 MB | 49.5 MB | 63.3 MB | 127 MB | 200 | 34 | 5 | | `ui.listing-10k.listing` | 10.8 MB | 6.39 MB | 52.3 MB | 62.8 MB | 84.3 MB | 10000 | 34 | 5 | | `ui.memory.flat-20k` | 20.1 MB | 6.49 MB | 68.7 MB | 79.3 MB | 128 MB | 20000 | 34 | 5 | | `ui.memory.idle` | 494 KB | 6.66 MB | 34.3 MB | 48.4 MB | 48.7 MB | 2 | 2 | 5 | | `ui.memory.listing-10k` | 10.7 MB | 6.43 MB | 49.6 MB | 59.3 MB | 63.1 MB | 10000 | 34 | 5 | | `ui.memory.released` | 1.26 MB | 6.51 MB | 52.3 MB | 61.6 MB | 128 MB | 2 | 2 | 5 | | `ui.memory.soak-navigate` | 1.27 MB | 6.58 MB | 48.6 MB | 65.0 MB | 128 MB | 2 | 2 | 5 | | `ui.memory.soak-tabs` | 1.27 MB | 6.60 MB | 60.4 MB | 63.0 MB | 128 MB | 2 | 2 | 5 | | `ui.preview.preview` | 538 KB | 8.65 MB | 40.5 MB | 57.0 MB | 63.7 MB | 10 | 10 | 5 | | `ui.search-local.search` | 4.33 MB | 8.38 MB | 68.4 MB | 64.5 MB | 69.4 MB | 200 | 34 | 5 | | `ui.sort-select-10k.sort` | 6.88 MB | 6.31 MB | 50.7 MB | 58.9 MB | 66.8 MB | 10000 | 34 | 5 | | `ui.tabs-panes.tabs` | 5.61 MB | 6.43 MB | 55.1 MB | 58.4 MB | 72.3 MB | 5000 | 34 | 5 | | `ui.tiles-5k.tiles` | 4.52 MB | 14.1 MB | 60.5 MB | 62.7 MB | 77.1 MB | 5000 | 34 | 5 | | `ui.transfer-2k.transfer` | 879 KB | 6.67 MB | 61.3 MB | 58.6 MB | 71.3 MB | 0 | 0 | 5 | ### Tier C — Startup of the real executable | Mark | Median | p95 | Min | n | |---|---:|---:|---:|---:| | `startup.main` | 10.3 ms | 10.7 ms | 9.68 ms | 20 | | `startup.session.main` | 10.4 ms | 10.7 ms | 9.60 ms | 20 | | `startup.velopackDone` | 10.5 ms | 10.9 ms | 9.86 ms | 20 | | `startup.instanceClaimed` | 10.6 ms | 11.0 ms | 9.94 ms | 20 | | `startup.session.velopackDone` | 10.6 ms | 10.9 ms | 9.78 ms | 20 | | `startup.session.instanceClaimed` | 10.7 ms | 10.9 ms | 9.86 ms | 20 | | `startup.comReady` | 12.2 ms | 12.6 ms | 11.3 ms | 20 | | `startup.session.comReady` | 12.3 ms | 12.6 ms | 11.3 ms | 20 | | `startup.settingsLoaded` | 13.1 ms | 13.6 ms | 12.2 ms | 20 | | `startup.session.settingsLoaded` | 13.3 ms | 13.7 ms | 12.2 ms | 20 | | `startup.migrated` | 14.6 ms | 15.2 ms | 13.7 ms | 20 | | `startup.session.migrated` | 14.7 ms | 15.4 ms | 13.6 ms | 20 | | `startup.servicesBuilt` | 15.5 ms | 16.1 ms | 14.6 ms | 20 | | `startup.session.servicesBuilt` | 15.6 ms | 16.4 ms | 14.4 ms | 20 | | `startup.themeReady` | 15.8 ms | 16.4 ms | 14.9 ms | 20 | | `startup.appCreated` | 15.8 ms | 16.4 ms | 14.9 ms | 20 | | `startup.session.themeReady` | 15.9 ms | 16.7 ms | 14.7 ms | 20 | | `startup.session.appCreated` | 15.9 ms | 16.8 ms | 14.8 ms | 20 | | `startup.deviceReady` | 23.9 ms | 27.5 ms | 22.5 ms | 20 | | `startup.session.deviceReady` | 23.9 ms | 28.4 ms | 22.1 ms | 20 | | `startup.session.windowCreated` | 28.8 ms | 33.3 ms | 27.0 ms | 20 | | `startup.windowCreated` | 28.9 ms | 32.6 ms | 27.4 ms | 20 | | `startup.session.mainViewBuilt` | 32.8 ms | 37.3 ms | 31.0 ms | 20 | | `startup.mainViewBuilt` | 32.9 ms | 36.6 ms | 31.4 ms | 20 | | `startup.session.listingLanded` | 34.0 ms | 38.4 ms | 32.1 ms | 20 | | `startup.listingLanded` | 34.9 ms | 38.8 ms | 33.5 ms | 20 | | `startup.sessionStarted` | 39.7 ms | 43.4 ms | 38.6 ms | 20 | | `startup.windowBuilt` | 39.7 ms | 43.4 ms | 38.6 ms | 20 | | `startup.session.sessionStarted` | 40.8 ms | 45.7 ms | 38.7 ms | 20 | | `startup.session.windowBuilt` | 40.8 ms | 45.7 ms | 38.7 ms | 20 | | `startup.listingPainted` | 68.9 ms | 72.6 ms | 66.9 ms | 20 | | `startup.contentRendered` | 68.9 ms | 72.6 ms | 66.9 ms | 20 | | `startup.windowShown` | 70.8 ms | 74.5 ms | 68.9 ms | 20 | | `startup.session.listingPainted` | 71.6 ms | 77.2 ms | 69.4 ms | 20 | | `startup.session.contentRendered` | 71.6 ms | 77.2 ms | 69.4 ms | 20 | | `startup.session.windowShown` | 74.3 ms | 79.8 ms | 72.0 ms | 20 | | `startup.firstListing` | 78.2 ms | 82.9 ms | 76.1 ms | 20 | | `startup.session.firstListing` | 81.6 ms | 88.0 ms | 79.2 ms | 20 | | `startup.gfxHardware` | 269 ms | 275 ms | 266 ms | 20 | | `startup.gfxSettled` | 269 ms | 275 ms | 266 ms | 20 | | `startup.session.gfxHardware` | 274 ms | 280 ms | 270 ms | 20 | | `startup.session.gfxSettled` | 274 ms | 280 ms | 270 ms | 20 | | `startup.processLifetime` | 515 ms | 529 ms | 500 ms | 20 | | `startup.session.processLifetime` | 520 ms | 540 ms | 509 ms | 20 | | Memory snapshot | Rust allocator | Process heap | Private bytes | Working set | Peak working set | n | |---|---:|---:|---:|---:|---:|---:| | `startup.memory.collected` | 926 KB | 8.40 MB | 90.3 MB | 79.0 MB | 102 MB | 20 | | `startup.memory.firstListing` | 925 KB | 8.40 MB | 90.7 MB | 79.2 MB | 102 MB | 20 | | `startup.session.memory.collected` | 10.6 MB | 8.23 MB | 108 MB | 89.3 MB | 116 MB | 20 | | `startup.session.memory.firstListing` | 10.6 MB | 8.23 MB | 118 MB | 91.6 MB | 116 MB | 20 | ## What the numbers do and do not mean - **Tier A** is `bb-bench`'s own runner over `bb-core` with a synthetic corpus unless marked real. Disk-reading benchmarks run against files the OS has cached, so they measure the code, not the disk. `Allocated/op` is exact for pure code; benchmarks over SQLite, the thread pool or disk declare a tolerance, which the compare tool honours. - **Tier B** drives the real window through the harness on WARP, the software rasteriser, parked outside every monitor at 1400×900. It is a regression signal for core and layout work, not the GPU path a user sees. A `search.*` time includes the 200 ms typing debounce. Each scenario is a fresh process. - **Tier C** launches the built `BertBrowser.exe` against a scratch data directory and reads marks the app writes under `BERTBROWSER_STARTUP_TRACE`. The window is parked offscreen and the post-window side effects (index-helper attach, change-log policy, update check) are skipped, so the headline is "process start to the rows on screen" (`listingPainted`), not "to idle". The first launch is discarded as cold. - **Memory** is three different measurements. Tier A's `Allocated/op` is what one call allocates. A Tier B *memory snapshot* is the harness process at a named point in a scenario, after dropping the text layout cache and asking the allocator to hand back what it can; its working set and private bytes include the harness and the software rasteriser. In both snapshot tables **Rust allocator** is the bytes Rust holds, counted at the allocator. **Process heap** is what is in use in the Windows heap: the C++ side and the system DLLs, never Rust. Neither contains the other, and **private bytes** contains both, the free pages allocators keep, and everything else. `ui.memory.*` is the scenario written for this: idle, ten thousand rows, twenty thousand flat, after leaving them, and after two soaks (25 navigations, 15 tabs opened and closed) that must not grow. Tier C's `startup.memory.*` is the real executable reading itself with the first listing up: `firstListing` as it stood, which is what Task Manager shows, and `collected` after the allocator has handed back what it can. A later run is held to the Rust allocator and the process heap within 10% and private bytes within 25%; the working set is reported and not judged, because Windows trims it for its own reasons. - Medians are reported because a single slow sample is the machine, not the code; p95 is nearest-rank.