A comprehensive benchmarking system for testing and comparing the performance of multiple Nostr relay implementations, including:
- Tests maximum event ingestion rate - Concurrent workers pushing events as fast as possible - Measures events/second, latency distribution, success rate
- Simulates real-world traffic patterns - Alternating high-activity bursts and quiet periods - Tests relay behavior under varying loads
- Concurrent read and write operations - Tests query performance while events are being ingested - Measures combined throughput and latency
Run the setup script to download and configure all external relay repositories:
cd cmd/benchmark
./setup-external-relays.sh
This will:
Start all relays and run the benchmark suite:
docker compose up --build
The system will:
Results are stored in the reports/ directory with timestamps:
# View the aggregate report
cat reports/run_YYYYMMDD_HHMMSS/aggregate_report.txt
# View individual relay results
ls reports/run_YYYYMMDD_HHMMSS/
| Service | Port | Description |
|---|---|---|
| next-orly-badger | 8001 | This repository's Badger relay |
| next-orly-neo4j | 8008 | This repository's Neo4j relay |
| neo4j | 7474/7687 | Neo4j graph database |
| khatru-sqlite | 8002 | Khatru with SQLite backend |
| khatru-badger | 8003 | Khatru with Badger backend |
| relayer-basic | 8004 | Basic relayer example |
| strfry | 8005 | Strfry C++ LMDB relay |
| nostr-rs-relay | 8006 | Rust SQLite relay |
| benchmark-runner | - | Orchestrates tests and aggregates results |
cmd/benchmark/
├── main.go # Benchmark tool implementation
├── docker-compose.yml # Service orchestration
├── setup-external-relays.sh # Repository setup script
├── benchmark-runner.sh # Test orchestration script
├── Dockerfile.next-orly # This repo's relay container
├── Dockerfile.benchmark # Benchmark runner container
├── Dockerfile.khatru-sqlite # Khatru SQLite variant
├── Dockerfile.khatru-badger # Khatru Badger variant
├── Dockerfile.relayer-basic # Relayer basic example
├── Dockerfile.strfry # Strfry relay
├── Dockerfile.nostr-rs-relay # Rust relay
├── configs/
│ ├── strfry.conf # Strfry configuration
│ └── config.toml # nostr-rs-relay configuration
├── external/ # External relay repositories
├── data/ # Persistent data for each relay
└── reports/ # Benchmark results
The benchmark can be configured via environment variables in docker-compose.yml:
environment:
- BENCHMARK_EVENTS=10000 # Number of events per test
- BENCHMARK_WORKERS=8 # Concurrent workers
- BENCHMARK_DURATION=60s # Test duration
- BENCHMARK_TARGETS=... # Relay endpoints to test
docker-compose.yml - Add service to docker-compose.yml
- Create appropriate Dockerfile
- Update BENCHMARK_TARGETS environment variable
configs/ directory# Build and run a specific relay
docker-compose up next-orly
# Run benchmark against specific endpoint
./benchmark -datadir=/tmp/test -events=1000 -workers=4
# Build the benchmark tool
go build -o benchmark main.go
# Run with custom parameters
./benchmark \
-datadir=/tmp/benchmark_db \
-events=5000 \
-workers=4 \
-duration=30s
The benchmark suite includes next.orly.dev with two different database backends to compare architectural approaches:
- Lower latency for single-instance operations - No network round-trips - Simpler deployment - Limited to single-node scaling
- Optimized for relationship traversal (e.g., follow graphs, event references) - Native Cypher query language for graph patterns - ACID transactions with graph-native storage - Network overhead from Bolt protocol - Excellent for complex graph queries (finding common connections, recommendation systems) - Higher memory usage for graph indexes - Ideal for analytics and social graph exploration
The benchmark results will show:
This comparison helps determine which backend is appropriate for different deployment scenarios and workload patterns.
Benchmark struct in main.gomain() function to call new testbenchmark-runner.shEach relay's Dockerfile and configuration can be customized:
configs/# View logs for specific relay
docker-compose logs next-orly
# Run benchmark with debug output
docker-compose up --build benchmark-runner
# Check individual container health
docker-compose ps
docker-compose logs <service># Clean up everything
docker-compose down -v
docker system prune -f
rm -rf external/ data/ reports/
# Start fresh
./setup-external-relays.sh
docker-compose up --build
The benchmark suite includes comprehensive testing to ensure reliable performance measurements:
# Run benchmark tests
go test ./cmd/benchmark
# Run all tests including benchmark
go test ./...
# Run with verbose output
go test -v ./cmd/benchmark
The benchmark suite is tested as part of the project's integration test suite:
# Run the full test suite
./scripts/test.sh
# Run performance benchmarks
./scripts/runtests.sh
Test the complete benchmark environment:
# Test individual relay startup
docker-compose up next-orly
# Test full benchmark suite (requires external relays)
./scripts/setup-external-relays.sh
docker-compose up --build
# Clean up test environment
docker-compose down -v
# Test benchmark configuration parsing
go test -v ./cmd/benchmark -run TestConfig
# Test individual benchmark patterns
go test -v ./cmd/benchmark -run TestPeakThroughput
# Test result aggregation
go test -v ./cmd/benchmark -run TestResults
# Build the benchmark binary
go build -o benchmark ./cmd/benchmark
# Build with optimizations
go build -ldflags="-s -w" -o benchmark ./cmd/benchmark
# Cross-compile for different platforms
GOOS=linux GOARCH=amd64 go build -o benchmark-linux-amd64 ./cmd/benchmark
main.gobenchmark-runner.shEach relay's configuration can be customized:
docker-compose.ymlconfigs/# View logs for specific relay
docker-compose logs next-orly
# Run benchmark with debug output
docker-compose up --build benchmark-runner
# Check individual container health
docker-compose ps
To add support for new relay implementations:
docker-compose.ymlBENCHMARK_TARGETS environment variableThis benchmark suite is part of the next.orly.dev project and follows the same licensing terms.