Most load testing tools simulate virtual users. Vegeta is different — it sends requests at a constant rate, which gives you much more accurate performance measurements. If you need to know exactly how your API performs at 1,000 requests per second, Vegeta tells you.
What Is Vegeta?
Vegeta is an HTTP load testing tool and library written in Go. It uses a constant request rate model instead of virtual users, which produces more reproducible and meaningful benchmark results. It reads targets from stdin, attacks at the specified rate, and reports detailed latency distributions.
The Free Tool
Vegeta is completely free and open source:
- Constant rate: Precise RPS control (not virtual users)
- CLI + Library: Use from terminal or embed in Go code
- Streaming: Process results in real-time
- Multiple formats: JSON, CSV, HDR histogram, text
- Plotting: Generate latency distribution plots
- Vegeta library: Use as a Go package for custom testing
Quick Start
Install Vegeta:
# macOS
brew install vegeta
# Go install
go install github.com/tsenart/vegeta/v12@latest
Basic attack:
# Send 50 requests/sec for 30 seconds
echo "GET https://api.example.com/health" | \
vegeta attack -rate=50/s -duration=30s | \
vegeta report
Output:
Requests [total, rate, throughput] 1500, 50.03, 49.98
Duration [total, attack, wait] 30.012s, 29.98s, 32.123ms
Latencies [min, mean, 50, 90, 95, 99, max] 12ms, 45ms, 38ms, 78ms, 95ms, 234ms, 567ms
Bytes In [total, mean] 450000, 300.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 99.87%
Status Codes [code:count] 200:1498 500:2
Multiple endpoints with different methods:
cat <<EOF | vegeta attack -rate=100/s -duration=60s | vegeta report
GET https://api.example.com/users
POST https://api.example.com/users
Content-Type: application/json
@/tmp/user.json
GET https://api.example.com/orders
Authorization: Bearer token123
EOF
Generate latency plot:
echo "GET https://api.example.com/health" | \
vegeta attack -rate=100/s -duration=60s | \
vegeta plot > latency.html
Use as a Go library:
package main
import (
"fmt"
"time"
vegeta "github.com/tsenart/vegeta/v12/lib"
)
func main() {
rate := vegeta.Rate{Freq: 100, Per: time.Second}
duration := 30 * time.Second
targeter := vegeta.NewStaticTargeter(vegeta.Target{
Method: "GET",
URL: "https://api.example.com/health",
})
attacker := vegeta.NewAttacker()
var metrics vegeta.Metrics
for res := range attacker.Attack(targeter, rate, duration, "test") {
metrics.Add(res)
}
metrics.Close()
fmt.Printf("99th percentile: %s\n", metrics.Latencies.P99)
fmt.Printf("Success rate: %.2f%%\n", metrics.Success*100)
}
Why Developers Choose Vegeta
An SRE team was benchmarking their API gateway with wrk and ab. The results varied wildly between runs because these tools use connection pools that change behavior as connections are reused. Vegeta's constant rate model gave them reproducible results — the same RPS produced the same latency distribution every time. They finally trusted their benchmarks enough to make capacity planning decisions.
Who Is This For?
- SRE teams doing capacity planning with precise RPS targets
- API developers who need reproducible benchmarks
- Go developers wanting a load testing library for custom tools
- Teams comparing API performance across deploys in CI
Start Benchmarking
Vegeta gives you honest performance numbers. Constant rate attacks produce reproducible results that you can trust for capacity planning.
Need help with API performance or load testing? I build custom testing solutions — reach out to discuss your project.
Found this useful? I publish daily deep-dives into developer tools and APIs. Follow for more.
Top comments (0)