← all articlesEXECUTION · STATE DB
// REPORT

How can two reth databases differ 64× on the same benchmarks, and then agree?

Ethereum · reth · MDBX · benchmarking · 2026 · reproducible pipeline & data →

The same EEST benchmarks ran up to 64× slower on a generated reth database than on a mainnet snapshot. None of the causes were in reth. With all six fixed and three refinements on top, 153 of the 154 tests that run half a second or more agree within ±10%.

jochemnet is a mainnet shadowfork snapshot. state-actor writes synthetic state straight into reth's tables. benchmarkoor runs the same 266 EEST bloatnet tests against both, restoring the store before each one. Every ratio below is state-actor's throughput over jochemnet's, so 1.00 is parity, and a test is in band within ±10% on two independent pairs of runs. Tests under half a second are shown but not scored: they barely reproduce against themselves.

The problem: up to 64× apart

buffered loops, jochemnet as published: throughput ratio per test categorytests over a second (by the first jochemnet run)existing EOAs0.797median 0.797absent accounts0.847median 0.847minimal contracts0.8300.9170.8520.8250.8360.8350.8290.826median 0.833one reused contract0.8340.9170.8460.8290.8380.8390.8320.835median 0.837distinct 24 KB contracts0.7020.7850.6530.7030.6880.7070.6940.694median 0.698jumpdest contracts0.7110.7870.6610.7010.6960.7160.7000.699median 0.701ether transfers0.930median 0.930sstore, bloated contract0.892median 0.892tests under a secondexisting EOAs0.0190.0250.0200.0190.0200.0190.0190.026median 0.020absent accounts0.0160.0190.0180.0160.0170.0160.0160.019median 0.016minimal contracts0.9591.0461.1381.0381.2411.2911.2581.024median 1.092one reused contract1.1271.0891.1781.0781.0731.0331.1781.072median 1.083distinct 24 KB contracts1.0421.1611.0151.1811.2391.0121.1281.204median 1.145jumpdest contracts1.0120.9961.1321.0061.0541.3021.1401.076median 1.065sload, bloated contract0.019median 0.019sstore, bloated contract0.018median 0.018warm account query1.016median 1.016sload, same key0.931median 0.9310.010.030.10.312one opcode or receiver category (geomean of two pairs)
Figure 1. The first measurement, before any fix, one dot per test category. Sequential-account lookups ran 39–64× slower, and calls into distinct 24 KB contracts at 0.65–0.79. Each store measured against itself agreed, so the gap was real.
six causes: where each sat, and what fixed itwherecausefix1disk setupreads reach the disk one at a timedirect I/O2storage layoutjochemnet is v1, state-actor writes v2convert jochemnet to v23table rowsrows out of key order; extra trie rowsPR1, PR24table pagesevery page packed full; mainnet's aren'tPR3, PR45stored stateevery contract holds a few hundred slotsPR5: mainnet storage shape5stored state21% more accounts than mainnetgenerate at mainnet's countfixed in the test setupfixed in state-actor
Figure 2. The six causes, from the disk up. The numbers are this article's sections.

1. The test rig read the disk one request at a time

random 4 KiB reads per second, fio psync, by parallel jobs10k100k1Mloop, buffered, 1 jobs: 11,439 IOPSloop, buffered, 4 jobs: 13,683 IOPSloop, buffered, 16 jobs: 13,657 IOPSloop, buffered, 64 jobs: 13,652 IOPSloop, buffered 13.7kloop, direct-io, 1 jobs: 11,470 IOPSloop, direct-io, 4 jobs: 40,856 IOPSloop, direct-io, 16 jobs: 127,118 IOPSloop, direct-io, 64 jobs: 130,402 IOPSloop, direct-io 130.4kraw file, O_DIRECT, 1 jobs: 13,812 IOPSraw file, O_DIRECT, 4 jobs: 54,367 IOPSraw file, O_DIRECT, 16 jobs: 212,314 IOPSraw file, O_DIRECT, 64 jobs: 763,232 IOPSraw file, O_DIRECT 763.2k141664parallel psync jobs
Figure 3. Reads per second through a test copy of the same disk setup. In its default mode it stays at 13.7k however many readers there are; with direct I/O it reaches 130.4k.

Both databases lived inside a disk image, attached through Linux's loop device. In its default mode the loop device passes reads to the disk one at a time, so reth's many parallel reads waited in line. It also read ahead, fetching data nobody asked for, which hurt state-actor's layout of contract code most.

Switching it to direct I/O fixed both: every test that reads state got 2–9× faster. Everything below is measured that way. Our earlier geth and Besu runs on this host used the same default.

2. The two stores used different storage layouts

the same six sequential accounts, looked up in two layoutsv1: PlainAccountState, keyed by addressjochemnet as published0x10000x10010x10020x10030x10040x1005leaf pages (each square one 4 KiB page)measured, BALANCE on 52k existing EOAs: 1,284 pagesv2: HashedAccounts, keyed by keccak(address)after reth db migrate-v2k(00)k(01)k(02)k(03)k(04)k(05)leaf pages (each square one 4 KiB page)measured, BALANCE on 52k existing EOAs: 95,664 pages
Figure 4. The same six neighbouring accounts in each layout. By address (v1) they share a page; by hash (v2) each lands on a different one. Switching jochemnet to the hashed lookups alone made its sequential tests 7× slower.

jochemnet was a v1 store; state-actor writes v2. reth has two storage layouts: the older v1 looks accounts up by address, the current v2 by hash. EEST's sequential tests read neighbouring addresses, which v1 finds together and v2 scatters. So the two stores weren't doing the same work, and that was most of the gap.

New reth nodes use v2, so we converted jochemnet. From here on, every gap is state-actor's.

3. Rows out of order, and trie rows reth never stores

what a full leaf does with one more keyrandom order (how state-actor wrote HashedAccounts)key d lands inside the range: split in the middleaceg+1acdegx Nevery leaf ends about half fullkey order (PR1)key h lands past the end: split at the edgeaceg+1aceghx Nevery leaf but the last stays fullmeasured, 2M keys in the same libmdbx: random order 79,846 leaf pages, key order 40,817state-actor's HashedAccounts: h6, leaf fill 0.50; the same rows in key order: h5, leaf fill 0.99
Figure 5. A full page splits where the new key lands: in the middle for a key inside its range, at the edge for a key past its end.

state-actor wrote accounts in the order it generated them, which is random against the table's hash order, so nearly every insert split a page in half. PR1 writes them in key order.

which branch nodes of an account trie get a stored rowroot'0''7''c''72''c0''c5'row reth stores (has a branch below it)row only state-actor stored (only leaves below)leafmeasured, AccountsTrie leaf pages: 6.1M as state-actor wrote them, 2.9M after PR1, PR2before the fix, CALL with value to 52k EOAs read 1.86x jochemnet's AccountsTrie branch pages
Figure 6. reth only stores a trie node that has another branch below it; the bottom ones it rebuilds from the leaves it reads anyway.

state-actor stored every node, so state-root updates read rows reth would never have written. PR2 stores only what reth would. Neither PR changes the state root.

4. Page fill is a dial, and mainnet's pages aren't full

how full a page stays, against the room left free when it splits0.40.50.60.70.80.91.0fill left behind0%12.5%25%37.5%50%room left free on a page when it splitsmeasured HashedAccounts leaf fillPR1+2 (key order): 0.9930.99 PR1+2 (key order)PR1-4 migrated: 0.5910.59 PR1-4 migratedPR1-5: 0.5910.59 PR1-5jochemnet: 0.5830.58 jochemnetoriginal (random order): 0.5010.50 original (random order)
Figure 7. libmdbx can leave room free on a page when it splits: none packs it full, the most leaves it half full. The dots are each store's measured account table.

Once writes arrive in key order, how full each page ends up is a choice, and it decides how many pages a lookup touches. jochemnet's account and storage tables carry years of random inserts, so their pages are well short of full.

PR3 puts the rest of state-actor's writes in key order. PR4 lets it choose how full each table's pages end up, with a migrated setting that matches a node converted to v2.

leaf fill per table (bar), height and leaf pages (text)HashedAccounts0.58 h5 8.2M leaves jochemnet (v2)0.50 h6 11.7M leaves original store0.99 h5 5.9M leaves PR1+20.59 h5 10M leaves PR1-40.59 h5 8.5M leaves PR1-50.59 h5 8.1M leaves PR1-8AccountsTrie0.97 h5 1.4M leaves jochemnet (v2)0.52 h5 6.1M leaves original store0.57 h5 2.9M leaves PR1+20.97 h5 1.7M leaves PR1-40.97 h5 1.4M leaves PR1-50.97 h5 1.4M leaves PR1-8HashedStorages0.67 h5 31.5M leaves jochemnet (v2)0.27 h5 71.6M leaves original store0.27 h5 71.6M leaves PR1+20.29 h5 54.7M leaves PR1-40.60 h5 37.6M leaves PR1-50.60 h5 38.9M leaves PR1-8StoragesTrie0.77 h4 6.8M leaves jochemnet (v2)0.24 h5 26.7M leaves original store0.29 h5 12.6M leaves PR1+20.31 h5 11.1M leaves PR1-40.42 h4 6.9M leaves PR1-50.78 h4 7.1M leaves PR1-8Bytecodes0.62 h4 229.1k leaves jochemnet (v2)0.41 h4 20.2k leaves original store0.53 h4 20.2k leaves PR1+20.69 h4 16.4k leaves PR1-40.64 h4 38k leaves PR1-50.63 h4 71.6k leaves PR1-8jochemnet (v2)original storePR1+2PR1-4PR1-5PR1-8
Figure 8. Every store's five state tables. For the two storage tables the fill bar samples the top-level tree only, while the page count includes each contract's own sub-tree. PR7 brings StoragesTrie's bar up to jochemnet's, and value-transfer tests read about 1.8k fewer of its pages.

5. The wrong storage shape, and too many accounts

share of storage-holding accounts with at most x slots0.000.250.500.751.0028 slots: inline limitjochemnet: F(1) = 0.550jochemnet: F(2) = 0.702jochemnet: F(3) = 0.732jochemnet: F(5) = 0.845jochemnet: F(10) = 0.908jochemnet: F(20) = 0.962jochemnet: F(28) = 0.971jochemnet: F(50) = 0.980jochemnet: F(100) = 0.987jochemnet: F(200) = 0.992jochemnet: F(500) = 0.995jochemnet: F(1,000) = 0.997jochemnet: F(4,000) = 0.999jochemnet: F(10,000) = 0.999jochemnet: F(100,000) = 1.000jochemnet: F(1,000,000) = 1.000jochemnet: F(10,000,000) = 1.000jochemnet: F(16,777,216) = 1.000jochemnet: F(335,545,082) = 1.000PR1-8: F(1) = 0.552PR1-8: F(2) = 0.704PR1-8: F(3) = 0.734PR1-8: F(5) = 0.846PR1-8: F(10) = 0.908PR1-8: F(20) = 0.963PR1-8: F(28) = 0.971PR1-8: F(50) = 0.980PR1-8: F(100) = 0.987PR1-8: F(200) = 0.992PR1-8: F(500) = 0.995PR1-8: F(1,000) = 0.997PR1-8: F(4,000) = 0.999PR1-8: F(10,000) = 0.999PR1-8: F(100,000) = 1.000PR1-8: F(1,000,000) = 1.000PR1-8: F(10,000,000) = 1.000PR1-8: F(16,777,216) = 1.000PR1-8: F(335,545,083) = 1.000jochemnetPR1-4 (sample)PR1-81101001k10k100k1M10M100Mslots per storage account (log)
Figure 9. Slots per storage-holding account. jochemnet: median 1, 55% with exactly one, 97% with at most 28. The PR1-4 store (a 5,000-account sample): median 252. The final store traces jochemnet's curve, tail included: 7 accounts above 16.8M slots, jochemnet 5, each counting the big test contract.

state-actor gave every contract a few hundred slots. Mainnet storage is heavy-tailed: most contracts hold one slot, a few hold millions.

The shape matters because reth stores no storage roots:

one modified account, its siblings, and what reth reads to re-hash themjochemnet-shaped siblingsbranch on the changed pathEOAno storage1 slotinline in themain-tree leafchanged<= 28 slotsinline in themain-tree leafEOAno storageautofill siblings (before PR5)branch on the changed pathEOAno storage~250 slots:nested sub-treechanged~250 slots:nested sub-treeEOAno storagethe walk happens for every modified account's siblings, at every level that has no stored trie rowblue: account leaves; amber: storage read in place; pink: pages of a nested storage tree (traced as 'other')
Figure 10. One modified account, its siblings, and what reth reads to re-hash them. The sub-tree walks are the pages the tracer labels 'other'.
distinct mdbx pages per traced test, by table (mean over the family's traced tests)HashedAccountsAccountsTrieHashedStorages mainHashedStorages bloatedStoragesTrieBytecodesother (nested storage walks)unlistedaccount reads (6 traced)jochemnetHashedAccounts: 94,546AccountsTrie: 104HashedStorages main: 36StoragesTrie: 14Bytecodes: 24other (nested storage walks): 9194.8kPR1-4HashedAccounts: 99,214AccountsTrie: 109HashedStorages main: 34StoragesTrie: 1Bytecodes: 19other (nested storage walks): 299.4kPR1-5HashedAccounts: 97,657AccountsTrie: 103HashedStorages main: 37StoragesTrie: 6Bytecodes: 20other (nested storage walks): 297.8kPR1-8HashedAccounts: 97,191AccountsTrie: 105HashedStorages main: 38StoragesTrie: 14Bytecodes: 21other (nested storage walks): 297.4kCALL / CALLCODE with value (3 traced)jochemnetHashedAccounts: 29,993AccountsTrie: 44,152HashedStorages main: 23,185StoragesTrie: 5,763Bytecodes: 25other (nested storage walks): 1,012104.1kPR1-4HashedAccounts: 32,537AccountsTrie: 46,498HashedStorages main: 18,827StoragesTrie: 3,013Bytecodes: 21other (nested storage walks): 11,999112.9kPR1-5HashedAccounts: 31,511AccountsTrie: 44,212HashedStorages main: 24,166StoragesTrie: 7,971Bytecodes: 21other (nested storage walks): 1,165109kPR1-8HashedAccounts: 31,117AccountsTrie: 44,101HashedStorages main: 24,001StoragesTrie: 6,105Bytecodes: 22other (nested storage walks): 1,154106.5kcode-heavy reads (24 KB code) (3 traced)jochemnetHashedAccounts: 94,066AccountsTrie: 70HashedStorages main: 24StoragesTrie: 9Bytecodes: 399,161other (nested storage walks): 64493.4kPR1-4HashedAccounts: 98,607AccountsTrie: 109HashedStorages main: 34StoragesTrie: 2Bytecodes: 373,381other (nested storage walks): 4472.1kPR1-5HashedAccounts: 97,090AccountsTrie: 103HashedStorages main: 37StoragesTrie: 5Bytecodes: 382,566other (nested storage walks): 2479.8kPR1-8HashedAccounts: 96,613AccountsTrie: 70HashedStorages main: 26StoragesTrie: 10Bytecodes: 391,063other (nested storage walks): 1487.8kether transfers (4 traced)jochemnetHashedAccounts: 43,345AccountsTrie: 42,514HashedStorages main: 22,118StoragesTrie: 5,526Bytecodes: 20other (nested storage walks): 754114.3kPR1-4HashedAccounts: 46,287AccountsTrie: 44,700HashedStorages main: 18,018StoragesTrie: 2,905Bytecodes: 18other (nested storage walks): 11,596123.5kPR1-5HashedAccounts: 45,109AccountsTrie: 42,326HashedStorages main: 23,050StoragesTrie: 7,574Bytecodes: 18other (nested storage walks): 1,122119.2kPR1-8HashedAccounts: 44,712AccountsTrie: 42,471HashedStorages main: 22,875StoragesTrie: 5,895Bytecodes: 19other (nested storage walks): 1,044117ksload, bloated contract (2 traced)jochemnetHashedAccounts: 60AccountsTrie: 137HashedStorages main: 48HashedStorages bloated: 115,337StoragesTrie: 114Bytecodes: 23other (nested storage walks): 102115.8kPR1-4HashedAccounts: 62AccountsTrie: 144HashedStorages main: 46HashedStorages bloated: 112,803StoragesTrie: 102Bytecodes: 17other (nested storage walks): 2113.2kPR1-5HashedAccounts: 58AccountsTrie: 138HashedStorages main: 52HashedStorages bloated: 114,322StoragesTrie: 114Bytecodes: 17other (nested storage walks): 2114.7kPR1-8HashedAccounts: 64AccountsTrie: 140HashedStorages main: 52HashedStorages bloated: 114,322StoragesTrie: 114Bytecodes: 18other (nested storage walks): 2114.7ksstore, no-op write (1 traced)jochemnetHashedAccounts: 61AccountsTrie: 143HashedStorages main: 49HashedStorages bloated: 95,758StoragesTrie: 118Bytecodes: 23other (nested storage walks): 10296.3kPR1-4HashedAccounts: 65AccountsTrie: 144HashedStorages main: 47HashedStorages bloated: 93,841StoragesTrie: 102Bytecodes: 17other (nested storage walks): 294.2kPR1-5HashedAccounts: 59AccountsTrie: 137HashedStorages main: 52HashedStorages bloated: 94,918StoragesTrie: 105Bytecodes: 17other (nested storage walks): 295.3kPR1-8HashedAccounts: 63AccountsTrie: 137HashedStorages main: 51HashedStorages bloated: 94,919StoragesTrie: 113Bytecodes: 18other (nested storage walks): 295.3ksstore, new value (1 traced)jochemnetHashedAccounts: 60AccountsTrie: 133HashedStorages main: 48HashedStorages bloated: 4,805StoragesTrie: 13,000Bytecodes: 23other (nested storage walks): 10218.2kPR1-4HashedAccounts: 63AccountsTrie: 140HashedStorages main: 46HashedStorages bloated: 4,692StoragesTrie: 12,946Bytecodes: 17other (nested storage walks): 1417.9kPR1-5HashedAccounts: 58AccountsTrie: 133HashedStorages main: 51HashedStorages bloated: 4,750StoragesTrie: 12,949Bytecodes: 17other (nested storage walks): 218kPR1-8HashedAccounts: 63AccountsTrie: 138HashedStorages main: 50HashedStorages bloated: 4,750StoragesTrie: 12,956Bytecodes: 18other (nested storage walks): 218koverhead control (1 traced)jochemnetHashedAccounts: 44AccountsTrie: 104HashedStorages main: 36StoragesTrie: 12Bytecodes: 21other (nested storage walks): 91308PR1-4HashedAccounts: 43AccountsTrie: 109HashedStorages main: 34Bytecodes: 17other (nested storage walks): 2205PR1-5HashedAccounts: 42AccountsTrie: 105HashedStorages main: 38StoragesTrie: 4Bytecodes: 17other (nested storage walks): 2208PR1-8HashedAccounts: 45AccountsTrie: 105HashedStorages main: 38StoragesTrie: 13Bytecodes: 18other (nested storage walks): 2221
Figure 11. The same traced tests on jochemnet, the PR1-4, PR1-5 and PR1-8 stores, by table. The pink 'other' segment is the sub-tree walk: on the transfer tests, 0.8k pages on jochemnet, 11.6k on PR1-4, 1.1k after PR5, 1.0k on PR1-8.

PR5 draws each contract's size from the distribution measured on jochemnet. We also generated the store at jochemnet's account count (the original had 21% more) and matched the fill of the one big test contract. The new state needed new fixtures, which reth itself filled, and reth checked every trie node of the new store: nothing to repair. PR6 draws the largest contracts too, with no cap, so they grow with the store.

Then: accounts that look like mainnet's

what an account row holds, and what reading one costsaccount row value, mean sizejochemnet (v2)12.2 bytesPR1-515.0 bytesPR1-812.4 bytesaccounts with code, by kindjochemnet (v2)code only: 61.9% of rows with codecode + storage: 35.6% of rows with codedelegation: 1.7% of rows with codedelegation + storage: 0.9% of rows with code19.1% of accountsPR1-5code only: 1.6% of rows with codecode + storage: 80.3% of rows with codedelegation: 18.1% of rows with code9.9% of accountsPR1-8code only: 59.6% of rows with codecode + storage: 38.8% of rows with codedelegation: 1.7% of rows with code19.6% of accountscode onlycode + storagedelegationdelegation + storagepages per traced account-read testjochemnet (v2)43.0k + 51.5kPR1-546.1k + 51.5kPR1-845.7k + 51.5kindex pagesrow pages
Figure 12. jochemnet, PR1-5 and PR1-8. 87% of PR1-5's balances took 9 bytes, where 50% of jochemnet's are zero, and its median nonce was 497, two bytes on 74% of accounts. Pages are the mean over the 6 traced account-read tests. Account reads ran at 0.970 on PR1-5 and 0.976 on PR1-8.

state-actor's accounts didn't look like mainnet's: big balances and nonces, and almost no contracts with code but no storage. PR8 fixes that, but account reads barely get faster.

A block that reads accounts touches one row page per account it reads, however small the row, so smaller rows don't help. What still differs is the index above the rows: jochemnet's index pages are fuller, so state-actor's index has about 16% more pages.

PR7 writes each contract's trie rows in address order, so the top level of the contract-trie table now fills like jochemnet's (Figure 8, StoragesTrie).

Where it stands

tests of 0.5 s or more within ±10% of jochemnet, out of 1540%50%100%original store46.1% 71/154+ PR1, PR2: key order, reth's trie rows77.3% 119/154+ PR3, PR4: key order everywhere, mainnet's page fill97.4% 150/154+ PR5: mainnet's storage shape and account count99.4% 153/154+ PR6-8: mainnet's account shape, contract trie order, storage tail99.4% 153/154
Figure 13. Share of the 154 tests that run half a second or more landing within ±10% of jochemnet, store by store, all against v2 jochemnet under direct-io. PR6-8 refine the store: they fix no cause of the 64×, and the share holds.
per-family median of each test's pair geomean, store by storejochemnet step time >= 1 s (gated)account reads (32)original store: 0.912PR1+2: 1.094PR1-4: 0.951PR1-5: 0.970PR1-8: 0.9740.91 → 0.97 32/32CALL / CALLCODE with value (3)original store: 0.775PR1+2: 0.905PR1-4: 0.941PR1-5: 0.982PR1-8: 0.9990.78 → 1.00 3/3code-heavy reads (24 KB code) (32)original store: 1.034PR1+2: 1.090PR1-4: 1.057PR1-5: 1.034PR1-8: 1.0191.03 → 1.02 32/32code-heavy CALL with value (8)original store: 0.958PR1+2: 1.034PR1-4: 1.014PR1-5: 1.020PR1-8: 1.0020.96 → 1.00 8/8ether transfers (34)original store: 0.839PR1+2: 0.978PR1-4: 0.994PR1-5: 1.033PR1-8: 1.0400.84 → 1.04 34/34sload, bloated contract (2)original store: 1.190PR1+2: 1.185PR1-4: 1.072PR1-5: 1.054PR1-8: 1.0531.19 → 1.05 1/2sstore, no-op write (2)original store: 1.189PR1+2: 1.197PR1-4: 1.065PR1-5: 1.042PR1-8: 1.0441.19 → 1.04 2/2sstore, new value (1)original store: 0.733PR1+2: 0.832PR1-4: 1.040PR1-5: 1.025PR1-8: 1.0150.73 → 1.02 1/10.5 - 1 s (gated)account reads (32)original store: 0.902PR1+2: 1.076PR1-4: 0.952PR1-5: 0.970PR1-8: 0.9770.90 → 0.98 32/32CALL / CALLCODE with value (3)original store: 0.787PR1+2: 0.926PR1-4: 0.945PR1-5: 0.984PR1-8: 1.0040.79 → 1.00 3/3sload, bloated contract (2)original store: 1.156PR1+2: 1.189PR1-4: 1.065PR1-5: 1.051PR1-8: 1.0461.16 → 1.05 2/2sstore, no-op write (2)original store: 1.166PR1+2: 1.198PR1-4: 1.063PR1-5: 1.063PR1-8: 1.0481.17 → 1.05 2/2sstore, new value (1)original store: 0.773PR1+2: 0.812PR1-4: 1.054PR1-5: 1.043PR1-8: 1.0260.77 → 1.03 1/1under 0.5 s: shown, not countedCALL / CALLCODE with value (10)original store: 0.870PR1+2: 1.046PR1-4: 0.961PR1-5: 1.001PR1-8: 0.9910.87 → 0.99 8/10ether transfers (2)original store: 1.062PR1+2: 1.264PR1-4: 1.266PR1-5: 1.301PR1-8: 1.3041.06 → 1.30 0/2sstore, new value (2)original store: 0.786PR1+2: 0.828PR1-4: 1.068PR1-5: 1.049PR1-8: 1.0280.79 → 1.03 2/2warm account query (14)original store: 1.006PR1+2: 1.005PR1-4: 0.980PR1-5: 1.024PR1-8: 1.0281.01 → 1.03 10/14sload, same key (4)original store: 1.035PR1+2: 0.995PR1-4: 1.054PR1-5: 1.087PR1-8: 0.9841.03 → 0.98 3/4overhead control (80)original store: 1.144PR1+2: 1.135PR1-4: 1.073PR1-5: 1.135PR1-8: 1.1241.14 → 1.12 31/800.60.80.9111.11.251.5original storePR1+2PR1-4PR1-5PR1-8
Figure 14. Every family, store by store. The right column shows original → PR1-8 and how many of the family's tests PR1-8 leaves in band.

Over a second, 113 and 113 of 114 tests are in band on the two pairs; each store against itself manages all 114. state-actor leans 1.4% fast there, under the 3% we set out not to chase.

What's left

Four of the six causes change nothing a state root can see, and none was in reth. A comparison between a generated store and a real one should state how each was laid out, not just what it holds.

← all articlessource & data →