Seen from accumulate's soak 20260906T134054Z (BlockchainDB as the node store, 8 shards, 1 s blocks, ~250 user tx per block; accumulate review docs/reviews/throughput-latency-2026-09-06.md, finding F1).
Measured on one node (bvnn stats.json after 5600 commits): perm LookupTotal 95.7M (FilterAbsent 94.6M), dyna LookupTotal 78.9M (LiveHit 11.7M, FilterAbsent 62.5M, FilterWalked 4.7M) — ~31k lookups per commit; 11,152 filter-absent lookups per commit fall through to a full dyna-history walk. Process-wide 77.5k read syscalls/s; the block-producing goroutine sampled 36 times was in pread 24 times (segment.lookup bloom/index probes, SegmentStore.lookupHistory, readValue). In the 30 s CPU profile SegmentStore.lookupHistory is 77% of getAt; segment.bloomTest 0.92 s, segment.lookup 1.28 s, pread 2.54 s.
Cause (code): KV2.Get (kv_2.go:281-289) asks the dynamic layer first; the mutable store never short-circuits a miss — segstore.go:1791-1795 walks lookupHistory for anything outside the live window; handoffBelowWindow (segstore.go:1085) frees the bloom of every history segment, so each probe is K=3 one-byte ReadAts per history segment (segstore.go:289-313) plus a ~14-ReadAt binary search of the index on a maybe (:347-357); loadBloom runs only for the active segment (seal.go:447). #64 freed blooms for perm history, which grows without bound; dyna history does not, so its blooms (~19 KB per 12.5k-record segment) can stay resident, or a single resident key filter over dyna history can answer absence in memory.
Also: per commit the seal issues ~3-5 fsync barriers per shard that took writes (perm tail seal.go:394, finish :559, index indexmerge.go:237, manifest segstore.go:1680, dyna tail) — ~30-40 per commit — and their duration is not measured (fsyncs are counted). Please add an fsync/seal duration histogram and a pread counter per Get so the next review measures instead of sampling goroutines.
Accumulate-side counterpart (routing write-once shapes to perm first, negative cache, dead probes): accumulatenetwork/accumulate#4249.
Seen from accumulate's soak 20260906T134054Z (BlockchainDB as the node store, 8 shards, 1 s blocks, ~250 user tx per block; accumulate review docs/reviews/throughput-latency-2026-09-06.md, finding F1).
Measured on one node (bvnn stats.json after 5600 commits): perm LookupTotal 95.7M (FilterAbsent 94.6M), dyna LookupTotal 78.9M (LiveHit 11.7M, FilterAbsent 62.5M, FilterWalked 4.7M) — ~31k lookups per commit; 11,152 filter-absent lookups per commit fall through to a full dyna-history walk. Process-wide 77.5k read syscalls/s; the block-producing goroutine sampled 36 times was in
pread24 times (segment.lookup bloom/index probes, SegmentStore.lookupHistory, readValue). In the 30 s CPU profileSegmentStore.lookupHistoryis 77% ofgetAt;segment.bloomTest0.92 s,segment.lookup1.28 s,pread2.54 s.Cause (code):
KV2.Get(kv_2.go:281-289) asks the dynamic layer first; the mutable store never short-circuits a miss — segstore.go:1791-1795 walkslookupHistoryfor anything outside the live window;handoffBelowWindow(segstore.go:1085) frees the bloom of every history segment, so each probe is K=3 one-byteReadAts per history segment (segstore.go:289-313) plus a ~14-ReadAtbinary search of the index on a maybe (:347-357);loadBloomruns only for the active segment (seal.go:447). #64 freed blooms for perm history, which grows without bound; dyna history does not, so its blooms (~19 KB per 12.5k-record segment) can stay resident, or a single resident key filter over dyna history can answer absence in memory.Also: per commit the seal issues ~3-5 fsync barriers per shard that took writes (perm tail seal.go:394, finish :559, index indexmerge.go:237, manifest segstore.go:1680, dyna tail) — ~30-40 per commit — and their duration is not measured (fsyncs are counted). Please add an fsync/seal duration histogram and a pread counter per Get so the next review measures instead of sampling goroutines.
Accumulate-side counterpart (routing write-once shapes to perm first, negative cache, dead probes): accumulatenetwork/accumulate#4249.