Skip to content

Conversation

@cce
Copy link
Contributor

@cce cce commented Oct 17, 2025

Summary

This provides benchmark code and algodump tooling for capturing network traffic and running compression on it with different window sizes, used during the development of #6351 and #6276.

Context: Previous Release (Stateless Compression)

PR #6276 and the v4.1.1 release added stateless vote compression (enabled by default with EnableVoteCompression), achieving ~25% bandwidth reduction for vote traffic with zero memory overhead and no per-connection state. Since not everyone upgrades unless necessary, the consensus upgrade in the v4.3.0 release had a side effect of ensuring all nodes on the network are now using stateless vote compression.

Stateful Compression: Additional Savings

PR #6351 and the upcoming v4.4.1 release adds optional stateful vote compression and introduces a new configuration option StatefulVoteCompressionTableSize that defaults to 2048, a suitable maximum table size for regular nodes that maintain ~4 connections. (The encoder and decoder both require StatefulVoteCompressionTableSize*224 bytes, plus 800 bytes of fixed overhead per direction.) With the default table size of 2048, the memory overhead for regular nodes is ~3.5 MB for 4 connections or ~7 MB for 8 connections.

Relays and nodes that maintain many connections may want to set a lower StatefulVoteCompressionTableSize, based on memory budget and bandwidth costs.

How it works: Stateful vote compression (#6351) maintains LRU tables on both ends of a connection to cache recently seen sender addresses, public keys, and signatures, converting them to short references. (Proposal values are also cached by a small sliding window.) Larger tables remember more past data, improving compression when votes from the same validators repeat across rounds. Memory cost is per bidirectional connection (encoder + decoder state for both send and receive directions).

Note: These memory estimates assume votes are flowing in both directions on all 2400 connections. Since most connected nodes are non-participating (and only receive votes to follow the chain, requiring compression state for just one direction), actual relay memory usage will typically be lower than these maximums.

Benchmark Results

Since compression performance is dependent on the distribution of stake, this is from a fresh capture of 98,170 vote messages from mainnet today (2025-11-06).

For a relay with 2400 connections (maximum):

Table size Memory per bidirectional connection Max possible overhead (for 2400 conns) Additional bandwidth saved over current stateless compression Total bandwidth saved over uncompressed votes (before v4.3.0)
0 (stateless) 0 KB 0 MB baseline from v4.3.0 ~25%
128 57 KB 137 MB 24.0% 42.9%
256 114 KB 273 MB 30.0% 47.4%
512 226 KB 542 MB 38.1% 53.4%
1024 450 KB 1.08 GB 45.1% 58.7%
2048 898 KB 2.15 GB 49.0% 61.7%

All configurations achieve ~1800 MB/s compression throughput and ~3800 MB/s decompression throughput, with zero allocs/op (after the tables are allocated).

Raw Benchmark Output

ALGODUMP_TEST_MESSAGES="./av-20251106" ALGODUMP_VPACK_WINDOWS="128,256,512,1024,2048" go test -run=^$ -bench='BenchmarkVPackDynamic(Dec|C)ompression' -benchtime=2s -benchmem
goos: darwin
goarch: arm64
pkg: github.com/algorand/go-algorand/tools/debug/algodump
cpu: Apple M2 Max
BenchmarkVPackDynamicCompression/window=128-12         	 6979465	       342.2 ns/op	1832.07 MB/s	        24.02 %addl_smaller	        42.89 %smaller	         1.316 addl_ratio	         1.751 ratio	       0 B/op	       0 allocs/op
BenchmarkVPackDynamicCompression/window=256-12         	 6951214	       343.8 ns/op	1823.92 MB/s	        29.96 %addl_smaller	        47.36 %smaller	         1.428 addl_ratio	         1.900 ratio	       0 B/op	       0 allocs/op
BenchmarkVPackDynamicCompression/window=512-12         	 6859497	       348.1 ns/op	1801.31 MB/s	        38.05 %addl_smaller	        53.44 %smaller	         1.614 addl_ratio	         2.148 ratio	       0 B/op	       0 allocs/op
BenchmarkVPackDynamicCompression/window=1024-12        	 6896420	       345.7 ns/op	1813.64 MB/s	        45.06 %addl_smaller	        58.70 %smaller	         1.820 addl_ratio	         2.422 ratio	       0 B/op	       0 allocs/op
BenchmarkVPackDynamicCompression/window=2048-12        	 7047230	       339.9 ns/op	1844.61 MB/s	        49.04 %addl_smaller	        61.69 %smaller	         1.962 addl_ratio	         2.611 ratio	       0 B/op	       0 allocs/op
BenchmarkVPackDynamicDecompression-12                  	14586291	       164.5 ns/op	3811.05 MB/s	       0 B/op	       0 allocs/op
PASS
ok  	github.com/algorand/go-algorand/tools/debug/algodump	14.118s

algorandskiy
algorandskiy previously approved these changes Oct 17, 2025
jannotti
jannotti previously approved these changes Oct 21, 2025
Copy link
Contributor

@jannotti jannotti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess! That's a lot of code. I guess it benchmarks?

I don't see much reason not to approve a tooling addition.

@cce cce dismissed stale reviews from jannotti and algorandskiy via 4c9fd51 October 24, 2025 17:17
@cce
Copy link
Contributor Author

cce commented Oct 24, 2025

@jannotti removed/shrunk some things and it is now less code

@cce cce marked this pull request as draft October 24, 2025 17:20
@codecov
Copy link

codecov bot commented Oct 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 47.41%. Comparing base (da20eba) to head (e7900bd).
⚠️ Report is 4 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6467      +/-   ##
==========================================
- Coverage   47.54%   47.41%   -0.14%     
==========================================
  Files         666      659       -7     
  Lines       88500    88393     -107     
==========================================
- Hits        42081    41908     -173     
- Misses      43658    43710      +52     
- Partials     2761     2775      +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

jannotti
jannotti previously approved these changes Oct 24, 2025
@cce cce force-pushed the vpack-dynamic-bench branch from f0045e9 to 4eae592 Compare October 24, 2025 18:29
@cce cce marked this pull request as ready for review November 6, 2025 21:21
@cce cce requested review from algorandskiy and jannotti November 6, 2025 21:21
@cce cce mentioned this pull request Nov 6, 2025
2 tasks
@cce cce changed the title network: add vote compression benchmarks and related algodump flags network: stateful vote compression benchmarks and tooling Nov 6, 2025
@cce cce changed the title network: stateful vote compression benchmarks and tooling network: vote compression benchmarks and tooling Nov 6, 2025
@algorandskiy algorandskiy merged commit f2da11f into algorand:master Nov 6, 2025
55 of 56 checks passed
@cce cce deleted the vpack-dynamic-bench branch November 6, 2025 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants