3 minutes
Netbench
Benchmarking network systems is usually a static affair. You spin up ApacheBench or wrk, tell it to run at a fixed fifty concurrent connections for two minutes, and look at the resulting average latency.
But real-world traffic is never static. In the wild, servers face dynamic traffic surges, sudden micro-bursts, and predictable diurnal waves (like the slow ramp-up of users starting their workday followed by a quiet night-time dip).
To test how my network infrastructure and auto-scalers handle these fluid concurrency transitions, I built Netbench (written in Go, ofc). It is an high-concurrency network and HTTP traffic generator that dynamically scales its worker thread concurrency using real-time mathematical wave functions.
graph TD
Start[Run Netbench] --> Init[Initialize Scaler Engine]
Init --> Check{Scaler Function Selected}
Check -->|Sine Wave| Sine[math.Sin Waveform Scaling]
Check -->|Exponential| Exp[math.Exp Escalation]
Check -->|Linear/Log| Lin[Linear & Log Ramp-Up]
Check -->|Static| Stat[Static Concurrency]
Sine --> Scale[Dynamic Spawn / Despawn Workers]
Exp --> Scale
Lin --> Scale
Stat --> Scale
Scale --> Work[Run HTTP / TCP / UDP Load Workers]
Mathematical wave-scaling engine
The core innovation of Netbench is its dynamic scaling loop. Instead of keeping a static pool of workers, Netbench uses a scaler tick engine that recalculates the target worker count at every interval based on your selected mathematical curve.
func (scaler *scaler) getScalerFunc() func() float64 {
switch scaler.scaler {
case interfaces.CurveScaler:
return func() float64 {
return math.Pow(scaler.increment, scaler.factor)
}
case interfaces.ExponentialScaler:
return func() float64 {
return math.Exp(scaler.increment) * scaler.factor
}
case interfaces.LinearScaler:
return func() float64 {
return scaler.increment * scaler.factor
}
case interfaces.LogarithmicScaler:
return func() float64 {
return math.Log(scaler.increment) * scaler.factor
}
case interfaces.SineScaler:
return func() float64 {
return math.Sin(scaler.increment/scaler.factor) * scaler.max
}
}
return nil
}
This math engine yields massive testing flexibility. You can use the Exponential curve to simulate a brutal flash-mob traffic spike, or you can utilize the Sine scaler to generate a beautiful, repeating sine-wave traffic flow that matches the natural rise and fall of production traffic.
At every tick, the scaler calculates the target concurrency, spawns new worker Goroutines to make up the difference, or cancels the context of active workers to cleanly spin them down.
Dual-mode network workers
To ensure Netbench can stress more than just simple web servers, the worker engine supports dual-mode workloads:
- HTTP Load Mode: Generates structured HTTP/HTTPS traffic. You can specify methods, custom headers, and pass base64-encoded request bodies.
- Raw Network Mode: Drops down to direct sockets to stream raw TCP or UDP byte packets, making it perfect for benchmarking firewalls, routing filters, and core network gateways.
switch *t {
case HTTPWorker:
worker_opts.HTTPOpts.URL = worker_opts.Target
_worker = NewHTTPWorker(ctx, &worker_opts.HTTPOpts, payload)
case NetWorker:
target := strings.SplitN(worker_opts.Target, "://", 2)
worker_opts.NetOpts.Type = target[0]
worker_opts.NetOpts.Addr = target[1]
_worker = NewNetWorker(ctx, &worker_opts.NetOpts, payload)
}
Percentile-perfect latency reports
Blasting packets into a void is useless if you cant see how the target responded. When the benchmarking run completes, Netbench aggregates all response statistics and prints out clean, human-readable text or structured JSON profiles.
Instead of just returning a raw average latency, Netbench provides full latency distribution percentiles (minimum, 25%, 50%, 75%, 90%, 99%, and maximum latencies).
This makes it incredibly easy to spot “tail latency” issues (where the average connection looks fast, but 1% of your users suffer from massive multi-second timeouts due to queue congestion).
If you want to benchmark your network setups using real-world traffic flows, give it a build.
- Codebase & Contributing: f0o/netbench on Github
Related Content: