optimize e and p tags

This commit is contained in:
2025-11-22 19:40:48 +00:00
parent 5c12c467b7
commit ef51382760
15 changed files with 2564 additions and 6 deletions

View File

@@ -115,7 +115,8 @@
"Bash(lynx:*)",
"Bash(sed:*)",
"Bash(docker stop:*)",
"Bash(grep:*)"
"Bash(grep:*)",
"Bash(timeout 30 go test:*)"
],
"deny": [],
"ask": []

View File

@@ -0,0 +1,194 @@
================================================================
NOSTR RELAY BENCHMARK AGGREGATE REPORT
================================================================
Generated: 2025-11-22T19:37:27+00:00
Benchmark Configuration:
Events per test: 50000
Concurrent workers: 24
Test duration: 60s
Relays tested: 9
================================================================
SUMMARY BY RELAY
================================================================
Relay: rely-sqlite
----------------------------------------
Status: COMPLETED
Events/sec: 15903.28
Events/sec: 6308.59
Events/sec: 15903.28
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.399274ms
Bottom 10% Avg Latency: 746.992µs
Avg Latency: 1.174853ms
P95 Latency: 2.34974ms
P95 Latency: 1.933092ms
P95 Latency: 897.528µs
Relay: next-orly-badger
----------------------------------------
Status: COMPLETED
Events/sec: 16607.66
Events/sec: 5941.60
Events/sec: 16607.66
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.338951ms
Bottom 10% Avg Latency: 757.49µs
Avg Latency: 1.490934ms
P95 Latency: 2.047963ms
P95 Latency: 2.961357ms
P95 Latency: 928.904µs
Relay: next-orly-dgraph
----------------------------------------
Status: COMPLETED
Events/sec: 16030.75
Events/sec: 6221.38
Events/sec: 16030.75
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.395117ms
Bottom 10% Avg Latency: 759.404µs
Avg Latency: 1.256755ms
P95 Latency: 2.2327ms
P95 Latency: 2.095959ms
P95 Latency: 890.448µs
Relay: next-orly-neo4j
----------------------------------------
Status: COMPLETED
Events/sec: 16565.07
Events/sec: 6026.51
Events/sec: 16565.07
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.32858ms
Bottom 10% Avg Latency: 724.65µs
Avg Latency: 1.392811ms
P95 Latency: 2.11453ms
P95 Latency: 2.568976ms
P95 Latency: 910.826µs
Relay: khatru-sqlite
----------------------------------------
Status: COMPLETED
Events/sec: 13273.11
Events/sec: 6204.61
Events/sec: 13273.11
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.732057ms
Bottom 10% Avg Latency: 803.833µs
Avg Latency: 1.263843ms
P95 Latency: 3.370931ms
P95 Latency: 2.195471ms
P95 Latency: 905.805µs
Relay: khatru-badger
----------------------------------------
Status: COMPLETED
Events/sec: 15590.07
Events/sec: 6139.02
Events/sec: 15590.07
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.451694ms
Bottom 10% Avg Latency: 793.994µs
Avg Latency: 1.324245ms
P95 Latency: 2.351317ms
P95 Latency: 2.291241ms
P95 Latency: 901.036µs
Relay: relayer-basic
----------------------------------------
Status: COMPLETED
Events/sec: 15076.33
Events/sec: 6071.70
Events/sec: 15076.33
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.517087ms
Bottom 10% Avg Latency: 821.229µs
Avg Latency: 1.385607ms
P95 Latency: 2.48546ms
P95 Latency: 2.478156ms
P95 Latency: 916.474µs
Relay: strfry
----------------------------------------
Status: COMPLETED
Events/sec: 16279.08
Events/sec: 6097.81
Events/sec: 16279.08
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.369757ms
Bottom 10% Avg Latency: 764.155µs
Avg Latency: 1.369895ms
P95 Latency: 2.13361ms
P95 Latency: 2.341095ms
P95 Latency: 894.733µs
Relay: nostr-rs-relay
----------------------------------------
Status: COMPLETED
Events/sec: 14836.18
Events/sec: 6111.29
Events/sec: 14836.18
Success Rate: 100.0%
Success Rate: 100.0%
Success Rate: 100.0%
Avg Latency: 1.545053ms
Bottom 10% Avg Latency: 829.94µs
Avg Latency: 1.336805ms
P95 Latency: 2.562666ms
P95 Latency: 2.417039ms
P95 Latency: 936.832µs
================================================================
DETAILED RESULTS
================================================================
Individual relay reports are available in:
- /reports/run_20251122_190700/khatru-badger_results.txt
- /reports/run_20251122_190700/khatru-sqlite_results.txt
- /reports/run_20251122_190700/next-orly-badger_results.txt
- /reports/run_20251122_190700/next-orly-dgraph_results.txt
- /reports/run_20251122_190700/next-orly-neo4j_results.txt
- /reports/run_20251122_190700/nostr-rs-relay_results.txt
- /reports/run_20251122_190700/relayer-basic_results.txt
- /reports/run_20251122_190700/rely-sqlite_results.txt
- /reports/run_20251122_190700/strfry_results.txt
================================================================
BENCHMARK COMPARISON TABLE
================================================================
Relay Status Peak Tput/s Avg Latency Success Rate
---- ------ ----------- ----------- ------------
rely-sqlite OK 15903.28 1.399274ms 100.0%
next-orly-badger OK 16607.66 1.338951ms 100.0%
next-orly-dgraph OK 16030.75 1.395117ms 100.0%
next-orly-neo4j OK 16565.07 1.32858ms 100.0%
khatru-sqlite OK 13273.11 1.732057ms 100.0%
khatru-badger OK 15590.07 1.451694ms 100.0%
relayer-basic OK 15076.33 1.517087ms 100.0%
strfry OK 16279.08 1.369757ms 100.0%
nostr-rs-relay OK 14836.18 1.545053ms 100.0%
================================================================
End of Report
================================================================

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_khatru-badger_8
Events: 50000, Workers: 24, Duration: 1m0s
1763839435106544 migrating to version 1... /build/pkg/database/migrations.go:66
1763839435106604 migrating to version 2... /build/pkg/database/migrations.go:73
1763839435106631 migrating to version 3... /build/pkg/database/migrations.go:80
1763839435106637 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763839435106651 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763839435106670 migrating to version 4... /build/pkg/database/migrations.go:87
1763839435106676 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763839435106697 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763839435106704 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763839435106780 migrating to version 5... /build/pkg/database/migrations.go:94
1763839435106787 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763839435106802 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763839435106808 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:23:55 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:23:55 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.207170539s
Events/sec: 15590.07
Avg latency: 1.451694ms
P90 latency: 1.980821ms
P95 latency: 2.351317ms
P99 latency: 3.85562ms
Bottom 10% Avg latency: 793.994µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 285.869262ms
Burst completed: 5000 events in 342.789614ms
Burst completed: 5000 events in 294.148662ms
Burst completed: 5000 events in 312.162616ms
Burst completed: 5000 events in 285.282311ms
Burst completed: 5000 events in 401.532953ms
Burst completed: 5000 events in 303.869144ms
Burst completed: 5000 events in 319.670695ms
Burst completed: 5000 events in 325.238604ms
Burst completed: 5000 events in 269.150105ms
Burst test completed: 50000 events in 8.144623588s, errors: 0
Events/sec: 6139.02
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.634143457s
Combined ops/sec: 2029.70
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 383293 queries in 1m0.006743126s
Queries/sec: 6387.50
Avg query latency: 1.745128ms
P95 query latency: 7.082542ms
P99 query latency: 11.228263ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 314586 operations (264586 queries, 50000 writes) in 1m0.003644928s
Operations/sec: 5242.78
Avg latency: 1.487422ms
Avg query latency: 1.448842ms
Avg write latency: 1.691574ms
P95 latency: 3.789773ms
P99 latency: 6.325059ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.207170539s
Total Events: 50000
Events/sec: 15590.07
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 98 MB
Avg Latency: 1.451694ms
P90 Latency: 1.980821ms
P95 Latency: 2.351317ms
P99 Latency: 3.85562ms
Bottom 10% Avg Latency: 793.994µs
----------------------------------------
Test: Burst Pattern
Duration: 8.144623588s
Total Events: 50000
Events/sec: 6139.02
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 178 MB
Avg Latency: 1.324245ms
P90 Latency: 1.946456ms
P95 Latency: 2.291241ms
P99 Latency: 3.488291ms
Bottom 10% Avg Latency: 514.259µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.634143457s
Total Events: 50000
Events/sec: 2029.70
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 142 MB
Avg Latency: 389.015µs
P90 Latency: 806.956µs
P95 Latency: 901.036µs
P99 Latency: 1.133428ms
Bottom 10% Avg Latency: 1.055235ms
----------------------------------------
Test: Query Performance
Duration: 1m0.006743126s
Total Events: 383293
Events/sec: 6387.50
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 159 MB
Avg Latency: 1.745128ms
P90 Latency: 5.322842ms
P95 Latency: 7.082542ms
P99 Latency: 11.228263ms
Bottom 10% Avg Latency: 7.913494ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.003644928s
Total Events: 314586
Events/sec: 5242.78
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 107 MB
Avg Latency: 1.487422ms
P90 Latency: 2.95774ms
P95 Latency: 3.789773ms
P99 Latency: 6.325059ms
Bottom 10% Avg Latency: 4.427784ms
----------------------------------------
Report saved to: /tmp/benchmark_khatru-badger_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_khatru-badger_8/benchmark_report.adoc
RELAY_NAME: khatru-badger
RELAY_URL: ws://khatru-badger:3334
TEST_TIMESTAMP: 2025-11-22T19:27:12+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_khatru-sqlite_8
Events: 50000, Workers: 24, Duration: 1m0s
1763839231750842 migrating to version 1... /build/pkg/database/migrations.go:66
1763839231750901 migrating to version 2... /build/pkg/database/migrations.go:73
1763839231750925 migrating to version 3... /build/pkg/database/migrations.go:80
1763839231750931 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763839231750941 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763839231750956 migrating to version 4... /build/pkg/database/migrations.go:87
1763839231750961 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763839231750983 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763839231750993 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763839231751016 migrating to version 5... /build/pkg/database/migrations.go:94
1763839231751021 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763839231751033 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763839231751038 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:20:31 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:20:31 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.76701384s
Events/sec: 13273.11
Avg latency: 1.732057ms
P90 latency: 2.725001ms
P95 latency: 3.370931ms
P99 latency: 5.636846ms
Bottom 10% Avg latency: 803.833µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 324.962224ms
Burst completed: 5000 events in 319.788529ms
Burst completed: 5000 events in 292.223747ms
Burst completed: 5000 events in 297.968607ms
Burst completed: 5000 events in 285.831691ms
Burst completed: 5000 events in 385.949074ms
Burst completed: 5000 events in 290.335776ms
Burst completed: 5000 events in 276.875448ms
Burst completed: 5000 events in 304.201963ms
Burst completed: 5000 events in 273.277754ms
Burst test completed: 50000 events in 8.058529464s, errors: 0
Events/sec: 6204.61
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.559984136s
Combined ops/sec: 2035.83
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 382812 queries in 1m0.004759428s
Queries/sec: 6379.69
Avg query latency: 1.753564ms
P95 query latency: 7.120429ms
P99 query latency: 11.234021ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 310209 operations (260209 queries, 50000 writes) in 1m0.002874017s
Operations/sec: 5169.90
Avg latency: 1.497119ms
Avg query latency: 1.472534ms
Avg write latency: 1.625063ms
P95 latency: 3.842736ms
P99 latency: 6.293151ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.76701384s
Total Events: 50000
Events/sec: 13273.11
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 133 MB
Avg Latency: 1.732057ms
P90 Latency: 2.725001ms
P95 Latency: 3.370931ms
P99 Latency: 5.636846ms
Bottom 10% Avg Latency: 803.833µs
----------------------------------------
Test: Burst Pattern
Duration: 8.058529464s
Total Events: 50000
Events/sec: 6204.61
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 196 MB
Avg Latency: 1.263843ms
P90 Latency: 1.851055ms
P95 Latency: 2.195471ms
P99 Latency: 3.218951ms
Bottom 10% Avg Latency: 504.149µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.559984136s
Total Events: 50000
Events/sec: 2035.83
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 127 MB
Avg Latency: 390.903µs
P90 Latency: 809.291µs
P95 Latency: 905.805µs
P99 Latency: 1.149089ms
Bottom 10% Avg Latency: 1.046555ms
----------------------------------------
Test: Query Performance
Duration: 1m0.004759428s
Total Events: 382812
Events/sec: 6379.69
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 118 MB
Avg Latency: 1.753564ms
P90 Latency: 5.356742ms
P95 Latency: 7.120429ms
P99 Latency: 11.234021ms
Bottom 10% Avg Latency: 7.946956ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.002874017s
Total Events: 310209
Events/sec: 5169.90
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 123 MB
Avg Latency: 1.497119ms
P90 Latency: 2.998239ms
P95 Latency: 3.842736ms
P99 Latency: 6.293151ms
Bottom 10% Avg Latency: 4.449237ms
----------------------------------------
Report saved to: /tmp/benchmark_khatru-sqlite_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_khatru-sqlite_8/benchmark_report.adoc
RELAY_NAME: khatru-sqlite
RELAY_URL: ws://khatru-sqlite:3334
TEST_TIMESTAMP: 2025-11-22T19:23:50+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_next-orly-badger_8
Events: 50000, Workers: 24, Duration: 1m0s
1763838623230113 migrating to version 1... /build/pkg/database/migrations.go:66
1763838623230189 migrating to version 2... /build/pkg/database/migrations.go:73
1763838623230211 migrating to version 3... /build/pkg/database/migrations.go:80
1763838623230216 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763838623230227 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763838623230248 migrating to version 4... /build/pkg/database/migrations.go:87
1763838623230253 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763838623230263 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763838623230268 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763838623230283 migrating to version 5... /build/pkg/database/migrations.go:94
1763838623230287 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763838623230296 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763838623230301 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:10:23 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:10:23 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.010658794s
Events/sec: 16607.66
Avg latency: 1.338951ms
P90 latency: 1.788958ms
P95 latency: 2.047963ms
P99 latency: 2.856809ms
Bottom 10% Avg latency: 757.49µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 291.670556ms
Burst completed: 5000 events in 360.87238ms
Burst completed: 5000 events in 301.408062ms
Burst completed: 5000 events in 316.375958ms
Burst completed: 5000 events in 376.937291ms
Burst completed: 5000 events in 566.001876ms
Burst completed: 5000 events in 315.464051ms
Burst completed: 5000 events in 317.465099ms
Burst completed: 5000 events in 278.045601ms
Burst completed: 5000 events in 284.298545ms
Burst test completed: 50000 events in 8.415248481s, errors: 0
Events/sec: 5941.60
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.625034214s
Combined ops/sec: 2030.45
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 381027 queries in 1m0.006635598s
Queries/sec: 6349.75
Avg query latency: 1.772811ms
P95 query latency: 7.236356ms
P99 query latency: 11.279564ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 305823 operations (255823 queries, 50000 writes) in 1m0.003583098s
Operations/sec: 5096.75
Avg latency: 1.56258ms
Avg query latency: 1.51784ms
Avg write latency: 1.791487ms
P95 latency: 4.018388ms
P99 latency: 7.130801ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.010658794s
Total Events: 50000
Events/sec: 16607.66
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 129 MB
Avg Latency: 1.338951ms
P90 Latency: 1.788958ms
P95 Latency: 2.047963ms
P99 Latency: 2.856809ms
Bottom 10% Avg Latency: 757.49µs
----------------------------------------
Test: Burst Pattern
Duration: 8.415248481s
Total Events: 50000
Events/sec: 5941.60
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 211 MB
Avg Latency: 1.490934ms
P90 Latency: 2.351964ms
P95 Latency: 2.961357ms
P99 Latency: 5.082311ms
Bottom 10% Avg Latency: 562.053µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.625034214s
Total Events: 50000
Events/sec: 2030.45
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 131 MB
Avg Latency: 399.173µs
P90 Latency: 823.303µs
P95 Latency: 928.904µs
P99 Latency: 1.225059ms
Bottom 10% Avg Latency: 1.081556ms
----------------------------------------
Test: Query Performance
Duration: 1m0.006635598s
Total Events: 381027
Events/sec: 6349.75
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 100 MB
Avg Latency: 1.772811ms
P90 Latency: 5.462421ms
P95 Latency: 7.236356ms
P99 Latency: 11.279564ms
Bottom 10% Avg Latency: 8.018763ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.003583098s
Total Events: 305823
Events/sec: 5096.75
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 99 MB
Avg Latency: 1.56258ms
P90 Latency: 3.106468ms
P95 Latency: 4.018388ms
P99 Latency: 7.130801ms
Bottom 10% Avg Latency: 4.803925ms
----------------------------------------
Report saved to: /tmp/benchmark_next-orly-badger_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_next-orly-badger_8/benchmark_report.adoc
RELAY_NAME: next-orly-badger
RELAY_URL: ws://next-orly-badger:8080
TEST_TIMESTAMP: 2025-11-22T19:13:41+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_next-orly-dgraph_8
Events: 50000, Workers: 24, Duration: 1m0s
1763838826199118 migrating to version 1... /build/pkg/database/migrations.go:66
1763838826199210 migrating to version 2... /build/pkg/database/migrations.go:73
1763838826199247 migrating to version 3... /build/pkg/database/migrations.go:80
1763838826199256 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763838826199269 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763838826199289 migrating to version 4... /build/pkg/database/migrations.go:87
1763838826199295 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763838826199309 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763838826199316 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763838826199335 migrating to version 5... /build/pkg/database/migrations.go:94
1763838826199341 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763838826199351 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763838826199356 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:13:46 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:13:46 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.119005212s
Events/sec: 16030.75
Avg latency: 1.395117ms
P90 latency: 1.905706ms
P95 latency: 2.2327ms
P99 latency: 3.309945ms
Bottom 10% Avg latency: 759.404µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 303.869245ms
Burst completed: 5000 events in 306.183047ms
Burst completed: 5000 events in 276.458606ms
Burst completed: 5000 events in 304.076404ms
Burst completed: 5000 events in 307.511965ms
Burst completed: 5000 events in 369.956481ms
Burst completed: 5000 events in 307.122565ms
Burst completed: 5000 events in 282.994622ms
Burst completed: 5000 events in 288.818591ms
Burst completed: 5000 events in 285.099724ms
Burst test completed: 50000 events in 8.036803222s, errors: 0
Events/sec: 6221.38
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.499088429s
Combined ops/sec: 2040.89
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 382175 queries in 1m0.005131728s
Queries/sec: 6369.04
Avg query latency: 1.76377ms
P95 query latency: 7.181013ms
P99 query latency: 11.361846ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 304137 operations (254137 queries, 50000 writes) in 1m0.003447398s
Operations/sec: 5068.66
Avg latency: 1.531621ms
Avg query latency: 1.527187ms
Avg write latency: 1.554157ms
P95 latency: 4.058867ms
P99 latency: 6.578532ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.119005212s
Total Events: 50000
Events/sec: 16030.75
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 90 MB
Avg Latency: 1.395117ms
P90 Latency: 1.905706ms
P95 Latency: 2.2327ms
P99 Latency: 3.309945ms
Bottom 10% Avg Latency: 759.404µs
----------------------------------------
Test: Burst Pattern
Duration: 8.036803222s
Total Events: 50000
Events/sec: 6221.38
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 201 MB
Avg Latency: 1.256755ms
P90 Latency: 1.81348ms
P95 Latency: 2.095959ms
P99 Latency: 3.000094ms
Bottom 10% Avg Latency: 457.006µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.499088429s
Total Events: 50000
Events/sec: 2040.89
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 174 MB
Avg Latency: 381.925µs
P90 Latency: 793.654µs
P95 Latency: 890.448µs
P99 Latency: 1.114536ms
Bottom 10% Avg Latency: 1.055638ms
----------------------------------------
Test: Query Performance
Duration: 1m0.005131728s
Total Events: 382175
Events/sec: 6369.04
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 145 MB
Avg Latency: 1.76377ms
P90 Latency: 5.387866ms
P95 Latency: 7.181013ms
P99 Latency: 11.361846ms
Bottom 10% Avg Latency: 8.012278ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.003447398s
Total Events: 304137
Events/sec: 5068.66
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 88 MB
Avg Latency: 1.531621ms
P90 Latency: 3.143653ms
P95 Latency: 4.058867ms
P99 Latency: 6.578532ms
Bottom 10% Avg Latency: 4.628862ms
----------------------------------------
Report saved to: /tmp/benchmark_next-orly-dgraph_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_next-orly-dgraph_8/benchmark_report.adoc
RELAY_NAME: next-orly-dgraph
RELAY_URL: ws://next-orly-dgraph:8080
TEST_TIMESTAMP: 2025-11-22T19:17:03+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_next-orly-neo4j_8
Events: 50000, Workers: 24, Duration: 1m0s
1763839028914848 migrating to version 1... /build/pkg/database/migrations.go:66
1763839028914921 migrating to version 2... /build/pkg/database/migrations.go:73
1763839028914942 migrating to version 3... /build/pkg/database/migrations.go:80
1763839028914948 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763839028914958 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763839028914973 migrating to version 4... /build/pkg/database/migrations.go:87
1763839028914989 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763839028915007 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763839028915013 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763839028915036 migrating to version 5... /build/pkg/database/migrations.go:94
1763839028915041 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763839028915050 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763839028915055 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:17:08 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:17:08 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.018399124s
Events/sec: 16565.07
Avg latency: 1.32858ms
P90 latency: 1.828555ms
P95 latency: 2.11453ms
P99 latency: 2.990871ms
Bottom 10% Avg latency: 724.65µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 293.405025ms
Burst completed: 5000 events in 361.620316ms
Burst completed: 5000 events in 345.575904ms
Burst completed: 5000 events in 316.292611ms
Burst completed: 5000 events in 295.528334ms
Burst completed: 5000 events in 358.255713ms
Burst completed: 5000 events in 442.869494ms
Burst completed: 5000 events in 301.13784ms
Burst completed: 5000 events in 284.850497ms
Burst completed: 5000 events in 291.965255ms
Burst test completed: 50000 events in 8.29667615s, errors: 0
Events/sec: 6026.51
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.529156295s
Combined ops/sec: 2038.39
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 397591 queries in 1m0.004044242s
Queries/sec: 6626.07
Avg query latency: 1.67631ms
P95 query latency: 6.658216ms
P99 query latency: 10.435254ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 312697 operations (262697 queries, 50000 writes) in 1m0.003549163s
Operations/sec: 5211.31
Avg latency: 1.489002ms
Avg query latency: 1.46537ms
Avg write latency: 1.613163ms
P95 latency: 3.830988ms
P99 latency: 6.471326ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.018399124s
Total Events: 50000
Events/sec: 16565.07
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 204 MB
Avg Latency: 1.32858ms
P90 Latency: 1.828555ms
P95 Latency: 2.11453ms
P99 Latency: 2.990871ms
Bottom 10% Avg Latency: 724.65µs
----------------------------------------
Test: Burst Pattern
Duration: 8.29667615s
Total Events: 50000
Events/sec: 6026.51
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 205 MB
Avg Latency: 1.392811ms
P90 Latency: 2.088531ms
P95 Latency: 2.568976ms
P99 Latency: 4.193773ms
Bottom 10% Avg Latency: 462.345µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.529156295s
Total Events: 50000
Events/sec: 2038.39
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 132 MB
Avg Latency: 388.158µs
P90 Latency: 813.891µs
P95 Latency: 910.826µs
P99 Latency: 1.152085ms
Bottom 10% Avg Latency: 1.025153ms
----------------------------------------
Test: Query Performance
Duration: 1m0.004044242s
Total Events: 397591
Events/sec: 6626.07
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 116 MB
Avg Latency: 1.67631ms
P90 Latency: 5.072074ms
P95 Latency: 6.658216ms
P99 Latency: 10.435254ms
Bottom 10% Avg Latency: 7.422142ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.003549163s
Total Events: 312697
Events/sec: 5211.31
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 139 MB
Avg Latency: 1.489002ms
P90 Latency: 2.962995ms
P95 Latency: 3.830988ms
P99 Latency: 6.471326ms
Bottom 10% Avg Latency: 4.527291ms
----------------------------------------
Report saved to: /tmp/benchmark_next-orly-neo4j_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_next-orly-neo4j_8/benchmark_report.adoc
RELAY_NAME: next-orly-neo4j
RELAY_URL: ws://next-orly-neo4j:8080
TEST_TIMESTAMP: 2025-11-22T19:20:26+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_nostr-rs-relay_8
Events: 50000, Workers: 24, Duration: 1m0s
1763840044071805 migrating to version 1... /build/pkg/database/migrations.go:66
1763840044071886 migrating to version 2... /build/pkg/database/migrations.go:73
1763840044071912 migrating to version 3... /build/pkg/database/migrations.go:80
1763840044071918 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763840044071926 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763840044071941 migrating to version 4... /build/pkg/database/migrations.go:87
1763840044071946 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763840044071959 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763840044071965 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763840044071993 migrating to version 5... /build/pkg/database/migrations.go:94
1763840044072003 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763840044072012 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763840044072017 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:34:04 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:34:04 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.370139282s
Events/sec: 14836.18
Avg latency: 1.545053ms
P90 latency: 2.163496ms
P95 latency: 2.562666ms
P99 latency: 3.871045ms
Bottom 10% Avg latency: 829.94µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 291.316304ms
Burst completed: 5000 events in 318.38321ms
Burst completed: 5000 events in 369.717856ms
Burst completed: 5000 events in 386.679947ms
Burst completed: 5000 events in 313.894228ms
Burst completed: 5000 events in 375.7593ms
Burst completed: 5000 events in 300.682893ms
Burst completed: 5000 events in 270.421689ms
Burst completed: 5000 events in 281.989788ms
Burst completed: 5000 events in 265.54975ms
Burst test completed: 50000 events in 8.181579562s, errors: 0
Events/sec: 6111.29
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.611048938s
Combined ops/sec: 2031.61
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 388576 queries in 1m0.007765782s
Queries/sec: 6475.43
Avg query latency: 1.737292ms
P95 query latency: 7.011739ms
P99 query latency: 11.25404ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 320770 operations (270770 queries, 50000 writes) in 1m0.003815149s
Operations/sec: 5345.83
Avg latency: 1.418636ms
Avg query latency: 1.407911ms
Avg write latency: 1.476716ms
P95 latency: 3.545655ms
P99 latency: 5.727035ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.370139282s
Total Events: 50000
Events/sec: 14836.18
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 131 MB
Avg Latency: 1.545053ms
P90 Latency: 2.163496ms
P95 Latency: 2.562666ms
P99 Latency: 3.871045ms
Bottom 10% Avg Latency: 829.94µs
----------------------------------------
Test: Burst Pattern
Duration: 8.181579562s
Total Events: 50000
Events/sec: 6111.29
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 205 MB
Avg Latency: 1.336805ms
P90 Latency: 2.051133ms
P95 Latency: 2.417039ms
P99 Latency: 3.368018ms
Bottom 10% Avg Latency: 499.404µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.611048938s
Total Events: 50000
Events/sec: 2031.61
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 112 MB
Avg Latency: 397.462µs
P90 Latency: 827.995µs
P95 Latency: 936.832µs
P99 Latency: 1.2249ms
Bottom 10% Avg Latency: 1.08713ms
----------------------------------------
Test: Query Performance
Duration: 1m0.007765782s
Total Events: 388576
Events/sec: 6475.43
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 117 MB
Avg Latency: 1.737292ms
P90 Latency: 5.250359ms
P95 Latency: 7.011739ms
P99 Latency: 11.25404ms
Bottom 10% Avg Latency: 7.872769ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.003815149s
Total Events: 320770
Events/sec: 5345.83
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 112 MB
Avg Latency: 1.418636ms
P90 Latency: 2.830856ms
P95 Latency: 3.545655ms
P99 Latency: 5.727035ms
Bottom 10% Avg Latency: 4.081447ms
----------------------------------------
Report saved to: /tmp/benchmark_nostr-rs-relay_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_nostr-rs-relay_8/benchmark_report.adoc
RELAY_NAME: nostr-rs-relay
RELAY_URL: ws://nostr-rs-relay:8080
TEST_TIMESTAMP: 2025-11-22T19:37:22+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_relayer-basic_8
Events: 50000, Workers: 24, Duration: 1m0s
1763839638031581 migrating to version 1... /build/pkg/database/migrations.go:66
1763839638031660 migrating to version 2... /build/pkg/database/migrations.go:73
1763839638031685 migrating to version 3... /build/pkg/database/migrations.go:80
1763839638031691 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763839638031697 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763839638031717 migrating to version 4... /build/pkg/database/migrations.go:87
1763839638031722 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763839638031734 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763839638031740 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763839638031756 migrating to version 5... /build/pkg/database/migrations.go:94
1763839638031761 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763839638031770 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763839638031775 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:27:18 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:27:18 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.316457481s
Events/sec: 15076.33
Avg latency: 1.517087ms
P90 latency: 2.134693ms
P95 latency: 2.48546ms
P99 latency: 3.572901ms
Bottom 10% Avg latency: 821.229µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 276.700297ms
Burst completed: 5000 events in 392.081438ms
Burst completed: 5000 events in 314.563405ms
Burst completed: 5000 events in 397.214306ms
Burst completed: 5000 events in 322.96797ms
Burst completed: 5000 events in 373.044665ms
Burst completed: 5000 events in 296.191438ms
Burst completed: 5000 events in 271.613902ms
Burst completed: 5000 events in 287.329791ms
Burst completed: 5000 events in 296.745792ms
Burst test completed: 50000 events in 8.234927616s, errors: 0
Events/sec: 6071.70
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.561126307s
Combined ops/sec: 2035.74
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 382011 queries in 1m0.004538365s
Queries/sec: 6366.37
Avg query latency: 1.775143ms
P95 query latency: 7.266438ms
P99 query latency: 11.395836ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 315099 operations (265099 queries, 50000 writes) in 1m0.002672022s
Operations/sec: 5251.42
Avg latency: 1.462691ms
Avg query latency: 1.440796ms
Avg write latency: 1.578778ms
P95 latency: 3.739636ms
P99 latency: 6.381464ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.316457481s
Total Events: 50000
Events/sec: 15076.33
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 133 MB
Avg Latency: 1.517087ms
P90 Latency: 2.134693ms
P95 Latency: 2.48546ms
P99 Latency: 3.572901ms
Bottom 10% Avg Latency: 821.229µs
----------------------------------------
Test: Burst Pattern
Duration: 8.234927616s
Total Events: 50000
Events/sec: 6071.70
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 186 MB
Avg Latency: 1.385607ms
P90 Latency: 2.08644ms
P95 Latency: 2.478156ms
P99 Latency: 3.769153ms
Bottom 10% Avg Latency: 520.086µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.561126307s
Total Events: 50000
Events/sec: 2035.74
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 177 MB
Avg Latency: 394.452µs
P90 Latency: 821.172µs
P95 Latency: 916.474µs
P99 Latency: 1.143807ms
Bottom 10% Avg Latency: 1.056519ms
----------------------------------------
Test: Query Performance
Duration: 1m0.004538365s
Total Events: 382011
Events/sec: 6366.37
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 134 MB
Avg Latency: 1.775143ms
P90 Latency: 5.448168ms
P95 Latency: 7.266438ms
P99 Latency: 11.395836ms
Bottom 10% Avg Latency: 8.059404ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.002672022s
Total Events: 315099
Events/sec: 5251.42
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 107 MB
Avg Latency: 1.462691ms
P90 Latency: 2.897052ms
P95 Latency: 3.739636ms
P99 Latency: 6.381464ms
Bottom 10% Avg Latency: 4.413874ms
----------------------------------------
Report saved to: /tmp/benchmark_relayer-basic_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_relayer-basic_8/benchmark_report.adoc
RELAY_NAME: relayer-basic
RELAY_URL: ws://relayer-basic:7447
TEST_TIMESTAMP: 2025-11-22T19:30:36+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,199 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_rely-sqlite_8
Events: 50000, Workers: 24, Duration: 1m0s
1763838420592113 migrating to version 1... /build/pkg/database/migrations.go:66
1763838420592185 migrating to version 2... /build/pkg/database/migrations.go:73
1763838420592206 migrating to version 3... /build/pkg/database/migrations.go:80
1763838420592211 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763838420592221 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763838420592244 migrating to version 4... /build/pkg/database/migrations.go:87
1763838420592249 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763838420592260 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763838420592265 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763838420592279 migrating to version 5... /build/pkg/database/migrations.go:94
1763838420592284 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763838420592294 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763838420592300 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:07:00 INFO: Extracted embedded libsecp256k1 to /tmp/orly-libsecp256k1/libsecp256k1.so
2025/11/22 19:07:00 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:07:00 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.144005095s
Events/sec: 15903.28
Avg latency: 1.399274ms
P90 latency: 1.969161ms
P95 latency: 2.34974ms
P99 latency: 3.740183ms
Bottom 10% Avg latency: 746.992µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 289.665872ms
Burst completed: 5000 events in 298.189416ms
Burst completed: 5000 events in 284.248905ms
Burst completed: 5000 events in 299.878917ms
Burst completed: 5000 events in 290.195429ms
Burst completed: 5000 events in 335.211169ms
Burst completed: 5000 events in 306.221225ms
Burst completed: 5000 events in 280.945252ms
Burst completed: 5000 events in 270.701091ms
Burst completed: 5000 events in 265.342517ms
Burst test completed: 50000 events in 7.925705852s, errors: 0
Events/sec: 6308.59
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.557413391s
Combined ops/sec: 2036.05
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 388544 queries in 1m0.004756071s
Queries/sec: 6475.22
Avg query latency: 1.723827ms
P95 query latency: 6.917596ms
P99 query latency: 10.942489ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 309051 operations (259051 queries, 50000 writes) in 1m0.003409818s
Operations/sec: 5150.56
Avg latency: 1.532079ms
Avg query latency: 1.486246ms
Avg write latency: 1.769539ms
P95 latency: 4.004134ms
P99 latency: 6.701092ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.144005095s
Total Events: 50000
Events/sec: 15903.28
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 121 MB
Avg Latency: 1.399274ms
P90 Latency: 1.969161ms
P95 Latency: 2.34974ms
P99 Latency: 3.740183ms
Bottom 10% Avg Latency: 746.992µs
----------------------------------------
Test: Burst Pattern
Duration: 7.925705852s
Total Events: 50000
Events/sec: 6308.59
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 188 MB
Avg Latency: 1.174853ms
P90 Latency: 1.682332ms
P95 Latency: 1.933092ms
P99 Latency: 2.630546ms
Bottom 10% Avg Latency: 472.317µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.557413391s
Total Events: 50000
Events/sec: 2036.05
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 130 MB
Avg Latency: 385.432µs
P90 Latency: 801.624µs
P95 Latency: 897.528µs
P99 Latency: 1.136145ms
Bottom 10% Avg Latency: 1.031469ms
----------------------------------------
Test: Query Performance
Duration: 1m0.004756071s
Total Events: 388544
Events/sec: 6475.22
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 132 MB
Avg Latency: 1.723827ms
P90 Latency: 5.21331ms
P95 Latency: 6.917596ms
P99 Latency: 10.942489ms
Bottom 10% Avg Latency: 7.705115ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.003409818s
Total Events: 309051
Events/sec: 5150.56
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 99 MB
Avg Latency: 1.532079ms
P90 Latency: 3.088572ms
P95 Latency: 4.004134ms
P99 Latency: 6.701092ms
Bottom 10% Avg Latency: 4.65921ms
----------------------------------------
Report saved to: /tmp/benchmark_rely-sqlite_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_rely-sqlite_8/benchmark_report.adoc
RELAY_NAME: rely-sqlite
RELAY_URL: ws://rely-sqlite:3334
TEST_TIMESTAMP: 2025-11-22T19:10:18+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -0,0 +1,198 @@
Starting Nostr Relay Benchmark (Badger Backend)
Data Directory: /tmp/benchmark_strfry_8
Events: 50000, Workers: 24, Duration: 1m0s
1763839841101245 migrating to version 1... /build/pkg/database/migrations.go:66
1763839841101335 migrating to version 2... /build/pkg/database/migrations.go:73
1763839841101370 migrating to version 3... /build/pkg/database/migrations.go:80
1763839841101377 cleaning up ephemeral events (kinds 20000-29999)... /build/pkg/database/migrations.go:294
1763839841101390 cleaned up 0 ephemeral events from database /build/pkg/database/migrations.go:339
1763839841101408 migrating to version 4... /build/pkg/database/migrations.go:87
1763839841101414 converting events to optimized inline storage (Reiser4 optimization)... /build/pkg/database/migrations.go:347
1763839841101428 found 0 events to convert (0 regular, 0 replaceable, 0 addressable) /build/pkg/database/migrations.go:436
1763839841101435 migration complete: converted 0 events to optimized inline storage, deleted 0 old keys /build/pkg/database/migrations.go:545
1763839841101455 migrating to version 5... /build/pkg/database/migrations.go:94
1763839841101462 re-encoding events with optimized tag binary format... /build/pkg/database/migrations.go:552
1763839841101469 found 0 events with e/p tags to re-encode /build/pkg/database/migrations.go:639
1763839841101476 no events need re-encoding /build/pkg/database/migrations.go:642
╔════════════════════════════════════════════════════════╗
║ BADGER BACKEND BENCHMARK SUITE ║
╚════════════════════════════════════════════════════════╝
=== Starting Badger benchmark ===
RunPeakThroughputTest (Badger)..
=== Peak Throughput Test ===
2025/11/22 19:30:41 WARN: Failed to load embedded library from /tmp/orly-libsecp256k1/libsecp256k1.so: Error relocating /tmp/orly-libsecp256k1/libsecp256k1.so: __fprintf_chk: symbol not found, falling back to system paths
2025/11/22 19:30:41 INFO: Successfully loaded libsecp256k1 v5.0.0 from system path: libsecp256k1.so.2
Events saved: 50000/50000 (100.0%), errors: 0
Duration: 3.071426372s
Events/sec: 16279.08
Avg latency: 1.369757ms
P90 latency: 1.839299ms
P95 latency: 2.13361ms
P99 latency: 3.209938ms
Bottom 10% Avg latency: 764.155µs
Wiping database between tests...
RunBurstPatternTest (Badger)..
=== Burst Pattern Test ===
Burst completed: 5000 events in 283.479669ms
Burst completed: 5000 events in 320.332742ms
Burst completed: 5000 events in 282.814191ms
Burst completed: 5000 events in 305.151074ms
Burst completed: 5000 events in 311.552363ms
Burst completed: 5000 events in 381.183959ms
Burst completed: 5000 events in 312.80669ms
Burst completed: 5000 events in 294.748789ms
Burst completed: 5000 events in 372.553415ms
Burst completed: 5000 events in 328.457439ms
Burst test completed: 50000 events in 8.199670789s, errors: 0
Events/sec: 6097.81
Wiping database between tests...
RunMixedReadWriteTest (Badger)..
=== Mixed Read/Write Test ===
Generating 1000 unique synthetic events (minimum 300 bytes each)...
Generated 1000 events:
Average content size: 312 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database for read tests...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Mixed test completed: 25000 writes, 25000 reads in 24.666176533s
Combined ops/sec: 2027.07
Wiping database between tests...
RunQueryTest (Badger)..
=== Query Test ===
Generating 10000 unique synthetic events (minimum 300 bytes each)...
Generated 10000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 10000 events for query tests...
Query test completed: 379410 queries in 1m0.006248896s
Queries/sec: 6322.84
Avg query latency: 1.765248ms
P95 query latency: 7.171725ms
P99 query latency: 11.436059ms
Wiping database between tests...
RunConcurrentQueryStoreTest (Badger)..
=== Concurrent Query/Store Test ===
Generating 5000 unique synthetic events (minimum 300 bytes each)...
Generated 5000 events:
Average content size: 313 bytes
All events are unique (incremental timestamps)
All events are properly signed
Pre-populating database with 5000 events for concurrent query/store test...
Generating 50000 unique synthetic events (minimum 300 bytes each)...
Generated 50000 events:
Average content size: 314 bytes
All events are unique (incremental timestamps)
All events are properly signed
Concurrent test completed: 305571 operations (255571 queries, 50000 writes) in 1m0.003361786s
Operations/sec: 5092.56
Avg latency: 1.593158ms
Avg query latency: 1.518193ms
Avg write latency: 1.976334ms
P95 latency: 4.090954ms
P99 latency: 7.169741ms
=== Badger benchmark completed ===
================================================================================
BENCHMARK REPORT
================================================================================
Test: Peak Throughput
Duration: 3.071426372s
Total Events: 50000
Events/sec: 16279.08
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 102 MB
Avg Latency: 1.369757ms
P90 Latency: 1.839299ms
P95 Latency: 2.13361ms
P99 Latency: 3.209938ms
Bottom 10% Avg Latency: 764.155µs
----------------------------------------
Test: Burst Pattern
Duration: 8.199670789s
Total Events: 50000
Events/sec: 6097.81
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 251 MB
Avg Latency: 1.369895ms
P90 Latency: 2.004985ms
P95 Latency: 2.341095ms
P99 Latency: 3.30014ms
Bottom 10% Avg Latency: 550.762µs
----------------------------------------
Test: Mixed Read/Write
Duration: 24.666176533s
Total Events: 50000
Events/sec: 2027.07
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 205 MB
Avg Latency: 381.997µs
P90 Latency: 798.95µs
P95 Latency: 894.733µs
P99 Latency: 1.134289ms
Bottom 10% Avg Latency: 1.013526ms
----------------------------------------
Test: Query Performance
Duration: 1m0.006248896s
Total Events: 379410
Events/sec: 6322.84
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 128 MB
Avg Latency: 1.765248ms
P90 Latency: 5.373945ms
P95 Latency: 7.171725ms
P99 Latency: 11.436059ms
Bottom 10% Avg Latency: 8.036698ms
----------------------------------------
Test: Concurrent Query/Store
Duration: 1m0.003361786s
Total Events: 305571
Events/sec: 5092.56
Success Rate: 100.0%
Concurrent Workers: 24
Memory Used: 102 MB
Avg Latency: 1.593158ms
P90 Latency: 3.181242ms
P95 Latency: 4.090954ms
P99 Latency: 7.169741ms
Bottom 10% Avg Latency: 4.862492ms
----------------------------------------
Report saved to: /tmp/benchmark_strfry_8/benchmark_report.txt
AsciiDoc report saved to: /tmp/benchmark_strfry_8/benchmark_report.adoc
RELAY_NAME: strfry
RELAY_URL: ws://strfry:8080
TEST_TIMESTAMP: 2025-11-22T19:33:59+00:00
BENCHMARK_CONFIG:
Events: 50000
Workers: 24
Duration: 60s

View File

@@ -16,7 +16,7 @@ import (
)
const (
currentVersion uint32 = 4
currentVersion uint32 = 5
)
func (d *D) RunMigrations() {
@@ -90,6 +90,13 @@ func (d *D) RunMigrations() {
// bump to version 4
_ = d.writeVersionTag(4)
}
if dbVersion < 5 {
log.I.F("migrating to version 5...")
// re-encode events with optimized tag binary format (e/p tags)
d.ReencodeEventsWithOptimizedTags()
// bump to version 5
_ = d.writeVersionTag(5)
}
}
// writeVersionTag writes a new version tag key to the database (no value)
@@ -537,3 +544,140 @@ func (d *D) ConvertSmallEventsToInline() {
log.I.F("migration complete: converted %d events to optimized inline storage, deleted %d old keys", convertedCount, deletedCount)
}
// ReencodeEventsWithOptimizedTags re-encodes all events to use the new binary
// tag format that stores e/p tag values as 33-byte binary (32-byte hash + null)
// instead of 64-byte hex strings. This reduces memory usage by ~48% for these tags.
func (d *D) ReencodeEventsWithOptimizedTags() {
log.I.F("re-encoding events with optimized tag binary format...")
var err error
type EventUpdate struct {
Key []byte
OldData []byte
NewData []byte
}
var updates []EventUpdate
var processedCount int
// Helper to collect event updates from iterator
// Only processes regular events (evt prefix) - inline storage already benefits
collectUpdates := func(it *badger.Iterator, prefix []byte) error {
for it.Rewind(); it.Valid(); it.Next() {
item := it.Item()
key := item.KeyCopy(nil)
var val []byte
if val, err = item.ValueCopy(nil); chk.E(err) {
continue
}
// Regular event storage - data is in value
eventData := val
if len(eventData) == 0 {
continue
}
// Decode the event
ev := new(event.E)
if err = ev.UnmarshalBinary(bytes.NewBuffer(eventData)); chk.E(err) {
continue
}
// Check if this event has e or p tags that could benefit from optimization
hasOptimizableTags := false
if ev.Tags != nil && ev.Tags.Len() > 0 {
for _, t := range *ev.Tags {
if t.Len() >= 2 {
key := t.Key()
if len(key) == 1 && (key[0] == 'e' || key[0] == 'p') {
hasOptimizableTags = true
break
}
}
}
}
if !hasOptimizableTags {
continue
}
// Re-encode the event (this will apply the new tag optimization)
newData := ev.MarshalBinaryToBytes(nil)
// Only update if the data actually changed
if !bytes.Equal(eventData, newData) {
updates = append(updates, EventUpdate{
Key: key,
OldData: eventData,
NewData: newData,
})
}
}
return nil
}
// Only process regular "evt" prefix events (not inline storage)
// Inline storage (sev, rev, aev) already benefits from the optimization
// because the binary data is stored directly in the key
prf := new(bytes.Buffer)
if err = indexes.EventEnc(nil).MarshalWrite(prf); chk.E(err) {
return
}
evtPrefix := prf.Bytes()
// Collect updates from regular events only
if err = d.View(func(txn *badger.Txn) error {
it := txn.NewIterator(badger.IteratorOptions{Prefix: evtPrefix})
defer it.Close()
return collectUpdates(it, evtPrefix)
}); chk.E(err) {
return
}
log.I.F("found %d events with e/p tags to re-encode", len(updates))
if len(updates) == 0 {
log.I.F("no events need re-encoding")
return
}
// Apply updates in batches
const batchSize = 1000
for i := 0; i < len(updates); i += batchSize {
end := i + batchSize
if end > len(updates) {
end = len(updates)
}
batch := updates[i:end]
if err = d.Update(func(txn *badger.Txn) error {
for _, upd := range batch {
// Since we're only processing regular events (evt prefix),
// we just update the value directly
if err = txn.Set(upd.Key, upd.NewData); chk.E(err) {
log.W.F("failed to update event: %v", err)
continue
}
processedCount++
}
return nil
}); chk.E(err) {
log.W.F("batch update failed: %v", err)
continue
}
if (i/batchSize)%10 == 0 && i > 0 {
log.I.F("progress: %d/%d events re-encoded", i, len(updates))
}
}
savedBytes := 0
for _, upd := range updates {
savedBytes += len(upd.OldData) - len(upd.NewData)
}
log.I.F("migration complete: re-encoded %d events, saved approximately %d bytes (%.2f KB)",
processedCount, savedBytes, float64(savedBytes)/1024.0)
}

View File

@@ -291,3 +291,43 @@ func BenchmarkTagsToSliceOfSliceOfStrings(b *testing.B) {
})
}
func BenchmarkTagEquals(b *testing.B) {
b.Run("BinaryToBinary", func(b *testing.B) {
b.ReportAllocs()
// Create two tags with same binary-encoded value
tag1 := New()
_, _ = tag1.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
tag2 := New()
_, _ = tag2.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = tag1.Equals(tag2)
}
})
b.Run("BinaryToHex", func(b *testing.B) {
b.ReportAllocs()
// One binary-encoded, one hex (simulate comparison with non-optimized tag)
tag1 := New()
_, _ = tag1.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
// Create hex version manually (simulating older format)
tag2 := NewFromBytesSlice([]byte("e"), []byte("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = tag1.Equals(tag2)
}
})
b.Run("HexToHex", func(b *testing.B) {
b.ReportAllocs()
// Both hex (non-optimized tags)
tag1 := NewFromBytesSlice([]byte("t"), []byte("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"))
tag2 := NewFromBytesSlice([]byte("t"), []byte("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"))
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = tag1.Equals(tag2)
}
})
}

View File

@@ -7,6 +7,7 @@ import (
"bytes"
"lol.mleku.dev/errorf"
"next.orly.dev/pkg/encoders/hex"
"next.orly.dev/pkg/encoders/text"
"next.orly.dev/pkg/utils"
)
@@ -18,6 +19,22 @@ const (
Relay
)
// Binary encoding constants for optimized storage of hex-encoded identifiers
const (
// BinaryEncodedLen is the length of a binary-encoded 32-byte hash with null terminator
BinaryEncodedLen = 33
// HexEncodedLen is the length of a hex-encoded 32-byte hash
HexEncodedLen = 64
// HashLen is the raw length of a hash (pubkey/event ID)
HashLen = 32
)
// Tags that use binary encoding optimization for their value field
var binaryOptimizedTags = map[string]bool{
"e": true, // event references
"p": true, // pubkey references
}
type T struct {
T [][]byte
}
@@ -76,6 +93,7 @@ func (t *T) Contains(s []byte) (b bool) {
}
// Marshal encodes a tag.T as standard minified JSON array of strings.
// Binary-encoded values (e/p tags) are automatically converted back to hex.
func (t *T) Marshal(dst []byte) (b []byte) {
b = dst
// Pre-allocate buffer if nil to reduce reallocations
@@ -83,14 +101,25 @@ func (t *T) Marshal(dst []byte) (b []byte) {
// Each field might be escaped, so estimate len(field) * 1.5 + 2 quotes + comma
if b == nil && len(t.T) > 0 {
estimatedSize := 2 // brackets
for _, s := range t.T {
estimatedSize += len(s)*3/2 + 4 // escaped field + quotes + comma
for i, s := range t.T {
fieldLen := len(s)
// Binary-encoded fields become hex (33 -> 64 chars)
if i == Value && isBinaryEncoded(s) {
fieldLen = HexEncodedLen
}
estimatedSize += fieldLen*3/2 + 4 // escaped field + quotes + comma
}
b = make([]byte, 0, estimatedSize)
}
b = append(b, '[')
for i, s := range t.T {
b = text.AppendQuote(b, s, text.NostrEscape)
// Convert binary-encoded value fields back to hex for JSON
if i == Value && isBinaryEncoded(s) {
hexVal := hex.EncAppend(nil, s[:HashLen])
b = text.AppendQuote(b, hexVal, text.NostrEscape)
} else {
b = text.AppendQuote(b, s, text.NostrEscape)
}
if i < len(t.T)-1 {
b = append(b, ',')
}
@@ -112,6 +141,8 @@ func (t *T) MarshalJSON() (b []byte, err error) {
}
// Unmarshal decodes a standard minified JSON array of strings to a tags.T.
// For "e" and "p" tags with 64-character hex values, it converts them to
// 33-byte binary format (32 bytes hash + null terminator) for efficiency.
func (t *T) Unmarshal(b []byte) (r []byte, err error) {
var inQuotes, openedBracket bool
var quoteStart int
@@ -135,7 +166,23 @@ func (t *T) Unmarshal(b []byte) (r []byte, err error) {
// original JSON buffer in-place (which would corrupt subsequent parsing).
copyBuf := make([]byte, i-quoteStart)
copy(copyBuf, b[quoteStart:i])
t.T = append(t.T, text.NostrUnescape(copyBuf))
unescaped := text.NostrUnescape(copyBuf)
// Optimize e/p tag values by converting hex to binary
fieldIdx := len(t.T)
if fieldIdx == Value && len(t.T) > 0 && shouldOptimize(t.T[Key], unescaped) {
// Decode hex to binary format: 32 bytes + null terminator
binVal := make([]byte, BinaryEncodedLen)
if _, err = hex.DecBytes(binVal[:HashLen], unescaped); err == nil {
binVal[HashLen] = 0 // null terminator
t.T = append(t.T, binVal)
} else {
// If decode fails, store as-is
t.T = append(t.T, unescaped)
}
} else {
t.T = append(t.T, unescaped)
}
}
}
if !openedBracket || inQuotes {
@@ -193,3 +240,148 @@ func (t *T) ToSliceOfStrings() (s []string) {
}
return
}
// isBinaryEncoded checks if a value field is stored in optimized binary format
// (32-byte hash + null terminator = 33 bytes total)
func isBinaryEncoded(val []byte) bool {
return len(val) == BinaryEncodedLen && val[HashLen] == 0
}
// shouldOptimize checks if a tag should use binary encoding optimization
func shouldOptimize(key []byte, val []byte) bool {
if len(key) != 1 {
return false
}
keyStr := string(key)
if !binaryOptimizedTags[keyStr] {
return false
}
// Only optimize if it's a valid 64-character hex string
return len(val) == HexEncodedLen && isValidHex(val)
}
// isValidHex checks if all bytes are valid hex characters
func isValidHex(b []byte) bool {
for _, c := range b {
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
return false
}
}
return true
}
// ValueHex returns the value field as hex string. If the value is stored in
// binary format, it converts it to hex. Otherwise, it returns the value as-is.
func (t *T) ValueHex() []byte {
if t == nil || len(t.T) <= Value {
return nil
}
val := t.T[Value]
if isBinaryEncoded(val) {
// Convert binary back to hex
return hex.EncAppend(nil, val[:HashLen])
}
return val
}
// ValueBinary returns the raw binary value if it's binary-encoded, or nil otherwise.
// This is useful for database operations that need the raw hash bytes.
func (t *T) ValueBinary() []byte {
if t == nil || len(t.T) <= Value {
return nil
}
val := t.T[Value]
if isBinaryEncoded(val) {
return val[:HashLen]
}
return nil
}
// Equals compares two tags for equality, handling both binary and hex encodings.
// This ensures that ["e", "abc..."] and ["e", <binary>] are equal if they
// represent the same hash. This method does NOT allocate memory.
func (t *T) Equals(other *T) bool {
if t == nil && other == nil {
return true
}
if t == nil || other == nil {
return false
}
if len(t.T) != len(other.T) {
return false
}
for i := range t.T {
if i == Value && len(t.T) > Value {
// Special handling for value field to compare binary vs hex without allocating
tVal := t.T[Value]
oVal := other.T[Value]
tIsBinary := isBinaryEncoded(tVal)
oIsBinary := isBinaryEncoded(oVal)
// Both binary - compare first 32 bytes directly
if tIsBinary && oIsBinary {
if !bytes.Equal(tVal[:HashLen], oVal[:HashLen]) {
return false
}
} else if tIsBinary || oIsBinary {
// One is binary, one is hex - need to compare carefully
// Compare the binary one's raw bytes with hex-decoded version of the other
var binBytes, hexBytes []byte
if tIsBinary {
binBytes = tVal[:HashLen]
hexBytes = oVal
} else {
binBytes = oVal[:HashLen]
hexBytes = tVal
}
// Decode hex inline without allocation by comparing byte by byte
if len(hexBytes) != HexEncodedLen {
return false
}
for j := 0; j < HashLen; j++ {
// Convert two hex chars to one byte and compare
hi := hexBytes[j*2]
lo := hexBytes[j*2+1]
var hiByte, loByte byte
if hi >= '0' && hi <= '9' {
hiByte = hi - '0'
} else if hi >= 'a' && hi <= 'f' {
hiByte = hi - 'a' + 10
} else if hi >= 'A' && hi <= 'F' {
hiByte = hi - 'A' + 10
} else {
return false
}
if lo >= '0' && lo <= '9' {
loByte = lo - '0'
} else if lo >= 'a' && lo <= 'f' {
loByte = lo - 'a' + 10
} else if lo >= 'A' && lo <= 'F' {
loByte = lo - 'A' + 10
} else {
return false
}
expectedByte := (hiByte << 4) | loByte
if binBytes[j] != expectedByte {
return false
}
}
} else {
// Both are regular (hex or other) - direct comparison
if !bytes.Equal(tVal, oVal) {
return false
}
}
} else {
if !bytes.Equal(t.T[i], other.T[i]) {
return false
}
}
}
return true
}

View File

@@ -30,3 +30,207 @@ func TestMarshalUnmarshal(t *testing.T) {
}
}
}
// TestBinaryEncodingOptimization verifies that e/p tags are stored in binary format
func TestBinaryEncodingOptimization(t *testing.T) {
testCases := []struct {
name string
json string
expectBinary bool
internalLen int // expected length of Value() field in internal storage
}{
{
name: "e tag with hex value",
json: `["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`,
expectBinary: true,
internalLen: BinaryEncodedLen, // 33 bytes (32 + null terminator)
},
{
name: "p tag with hex value",
json: `["p","fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"]`,
expectBinary: true,
internalLen: BinaryEncodedLen,
},
{
name: "e tag with relay",
json: `["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef","wss://relay.example.com"]`,
expectBinary: true,
internalLen: BinaryEncodedLen,
},
{
name: "t tag not optimized",
json: `["t","bitcoin"]`,
expectBinary: false,
internalLen: 7, // "bitcoin" as-is
},
{
name: "e tag with short value not optimized",
json: `["e","short"]`,
expectBinary: false,
internalLen: 5,
},
{
name: "e tag with invalid hex not optimized",
json: `["e","zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"]`,
expectBinary: false,
internalLen: 64,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tag := New()
_, err := tag.Unmarshal([]byte(tc.json))
if err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
// Check internal storage length
if tag.Len() < 2 {
t.Fatal("Tag should have at least 2 fields")
}
valueField := tag.T[Value]
if len(valueField) != tc.internalLen {
t.Errorf("Expected internal value length %d, got %d", tc.internalLen, len(valueField))
}
// Check if binary encoded as expected
if tc.expectBinary {
if !isBinaryEncoded(valueField) {
t.Error("Expected binary encoding, but tag is not binary encoded")
}
// Verify null terminator
if valueField[HashLen] != 0 {
t.Error("Binary encoded value should have null terminator at position 32")
}
} else {
if isBinaryEncoded(valueField) {
t.Error("Did not expect binary encoding, but tag is binary encoded")
}
}
// Marshal back to JSON and verify it matches original
marshaled := tag.Marshal(nil)
if string(marshaled) != tc.json {
t.Errorf("Marshaled JSON doesn't match original.\nExpected: %s\nGot: %s", tc.json, string(marshaled))
}
})
}
}
// TestValueHexMethod verifies ValueHex() correctly converts binary to hex
func TestValueHexMethod(t *testing.T) {
json := `["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`
tag := New()
_, err := tag.Unmarshal([]byte(json))
if err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
// Internal storage should be binary
if !isBinaryEncoded(tag.T[Value]) {
t.Fatal("Expected binary encoding")
}
// ValueHex should return the original hex string
hexVal := tag.ValueHex()
expectedHex := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
if string(hexVal) != expectedHex {
t.Errorf("ValueHex returned wrong value.\nExpected: %s\nGot: %s", expectedHex, string(hexVal))
}
}
// TestValueBinaryMethod verifies ValueBinary() returns raw hash bytes
func TestValueBinaryMethod(t *testing.T) {
json := `["p","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`
tag := New()
_, err := tag.Unmarshal([]byte(json))
if err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
// ValueBinary should return 32 bytes
binVal := tag.ValueBinary()
if binVal == nil {
t.Fatal("ValueBinary returned nil")
}
if len(binVal) != HashLen {
t.Errorf("Expected %d bytes, got %d", HashLen, len(binVal))
}
// It should match the first 32 bytes of the internal storage
if !utils.FastEqual(binVal, tag.T[Value][:HashLen]) {
t.Error("ValueBinary doesn't match internal storage")
}
}
// TestEqualsMethod verifies Equals() handles binary vs hex comparison
func TestEqualsMethod(t *testing.T) {
// Create tag from JSON (will be binary internally)
tag1 := New()
_, err := tag1.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
if err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
// Create identical tag
tag2 := New()
_, err = tag2.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
if err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if !tag1.Equals(tag2) {
t.Error("Identical tags should be equal")
}
// Create tag with different value
tag3 := New()
_, err = tag3.Unmarshal([]byte(`["e","fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"]`))
if err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if tag1.Equals(tag3) {
t.Error("Different tags should not be equal")
}
// Test with relay field
tag4 := New()
_, err = tag4.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef","wss://relay.example.com"]`))
if err != nil {
t.Fatalf("Unmarshal failed: %v", err)
}
if tag1.Equals(tag4) {
t.Error("Tags with different lengths should not be equal")
}
}
// TestBinaryEncodingSavesSpace verifies the optimization reduces memory usage
func TestBinaryEncodingSavesSpace(t *testing.T) {
// Tag without optimization (non-hex or non e/p tag)
tagNonOpt := New()
_, _ = tagNonOpt.Unmarshal([]byte(`["t","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
nonOptSize := len(tagNonOpt.T[Value])
// Tag with optimization
tagOpt := New()
_, _ = tagOpt.Unmarshal([]byte(`["e","0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]`))
optSize := len(tagOpt.T[Value])
// Binary should be smaller (33 vs 64 bytes)
if optSize >= nonOptSize {
t.Errorf("Binary encoding should save space. Non-opt: %d bytes, Opt: %d bytes", nonOptSize, optSize)
}
expectedSavings := HexEncodedLen - BinaryEncodedLen // 64 - 33 = 31 bytes
actualSavings := nonOptSize - optSize
if actualSavings != expectedSavings {
t.Errorf("Expected to save %d bytes, actually saved %d bytes", expectedSavings, actualSavings)
}
t.Logf("Space savings: %d bytes per e/p tag value (%.1f%% reduction)",
actualSavings, float64(actualSavings)/float64(nonOptSize)*100)
}