Introduction to Vegeta
Vegeta is a versatile command-line HTTP load testing tool and library, originally developed by the team at Tsenior. Written in Go, it is designed to be fast, lightweight, and easy to integrate into CI/CD pipelines. Unlike many GUI-based load testing tools, Vegeta focuses on simplicity and automation, making it a favorite among developers who need reliable performance benchmarks.
What Makes Vegeta Different
Vegeta uses a constant request rate approach, meaning it sends requests at a steady pace rather than spawning concurrent threads. This design gives you more predictable and reproducible results, which is critical when comparing performance across code changes or infrastructure updates.
Why Load Testing Matters
Performance issues often surface only under real-world traffic conditions. Without proper load testing, you risk deploying code that performs well in development but crumbles when actual users hit your endpoints. Vegeta helps you:
- Identify bottlenecks before they affect production users
- Establish performance baselines for regression testing
- Validate that infrastructure scaling decisions work as expected
- Measure the impact of code changes on response times
- Set realistic SLAs and SLOs based on empirical data
Installing Vegeta
Since Vegeta is written in Go, installation is straightforward. You can download a precompiled binary or build it from source.
Binary Installation
# macOS
brew install vegeta
# Linux (download binary)
wget https://github.com/tsenart/vegeta/releases/download/v12.11.1/vegeta_12.11.1_linux_amd64.tar.gz
tar -xzf vegeta_12.11.1_linux_amd64.tar.gz
sudo mv vegeta /usr/local/bin/
# Verify installation
vegeta -version
Building from Source
go install github.com/tsenart/vegeta@latest
Basic Usage
The simplest way to use Vegeta is by piping an HTTP request definition into the tool. Vegeta reads requests in a custom format where each line represents a request.
Your First Load Test
echo "GET http://localhost:8080/api/health" | vegeta attack -duration=10s -rate=50 | vegeta report
This command sends 50 requests per second for 10 seconds to your health endpoint and prints a summary report. The output includes latency percentiles, throughput, and success rates.
Understanding the Report
Requests [total, rate, throughput] 500, 50.00, 49.95
Duration [total, attack, wait] 10.009s, 10.000s, 9.149ms
Latencies [min, mean, 50, 95, 99, max] 1.234ms, 4.567ms, 3.890ms, 8.123ms, 12.456ms, 45.678ms
Bytes In [total, mean] 15000, 30.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:500
Error Set:
Key metrics to focus on include the 95th and 99th percentile latencies, which reveal tail latency behavior that averages can hide. The success ratio tells you immediately if your service is handling the load.
Advanced Request Definitions
Real-world testing requires more than simple GET requests. Vegeta supports a flexible request format that allows custom headers, bodies, and HTTP methods.
Request Format
# Single request with headers
echo "GET http://localhost:8080/api/users
Authorization: Bearer my-token-123
Accept: application/json" | vegeta attack -duration=5s -rate=10
POST Requests with Body
echo "POST http://localhost:8080/api/users
Content-Type: application/json
{\"name\":\"John\",\"email\":\"john@example.com\"}" | vegeta attack -duration=10s -rate=20 | vegeta report
Using Request Files
For complex test scenarios, store your requests in a file. Each request is separated by a blank line.
# requests.txt
GET http://localhost:8080/api/users/1
Authorization: Bearer token1
GET http://localhost:8080/api/users/2
Authorization: Bearer token2
POST http://localhost:8080/api/orders
Content-Type: application/json
{"product_id": 42, "quantity": 3}
# Run the test
vegeta attack -duration=30s -rate=50 -targets=requests.txt | vegeta report
Testing with Different Rate Patterns
Vegeta supports both constant and variable request rates. Variable rates help simulate realistic traffic spikes.
Constant Rate
vegeta attack -duration=60s -rate=100 -targets=requests.txt | vegeta report
Variable Rate
You can specify a rate schedule that changes over time using the -rate flag with a schedule format.
# Ramp up from 0 to 100 over 10 seconds, hold for 30s, ramp down
vegeta attack -duration=40s -rate="0..100:10s,100:30s,100..0:10s" -targets=requests.txt | vegeta report
Generating Visual Reports
Text reports are useful, but visualizations make it easier to spot trends and anomalies. Vegeta can generate plots in HTML format.
HTML Plot
vegeta attack -duration=60s -rate=100 -targets=requests.txt | vegeta plot > plot.html
Open the resulting HTML file in a browser to see an interactive plot showing latency over time. This is invaluable for identifying when performance degrades during a test.
JSON Output for Custom Analysis
vegeta attack -duration=30s -rate=50 -targets=requests.txt | vegeta report -type=json > results.json
You can then process this JSON with tools like jq or import it into dashboards for long-term tracking.
Best Practices for Effective Load Testing
Test from a Realistic Environment
Running load tests from your local machine against a remote server introduces network noise. Ideally, run Vegeta from an environment similar to where real traffic originates, such as a cloud VM in the same region as your production infrastructure.
Warm Up Before Measuring
Cold caches and JIT compilation can skew initial results. Run a short warm-up test before capturing your actual measurements.
# Warm up
vegeta attack -duration=10s -rate=20 -targets=requests.txt > /dev/null
# Actual test
vegeta attack -duration=60s -rate=100 -targets=requests.txt | vegeta report
Test Realistic Scenarios
Don't just hammer a single endpoint. Create request files that mimic actual user journeys, mixing reads, writes, and different endpoints in proportions that reflect real usage patterns.
Monitor the System Under Test
Load testing without monitoring the target system tells only half the story. Watch CPU, memory, database connections, and application metrics during tests to understand why performance behaves the way it does.
Automate in CI/CD
Integrate Vegeta into your deployment pipeline to catch performance regressions automatically. Store baseline results and compare new runs against them.
#!/bin/bash
# perf-test.sh
BASELINE_FILE="baseline.json"
THRESHOLD_P95_MS=100
vegeta attack -duration=30s -rate=50 -targets=requests.txt | vegeta report -type=json > current.json
P95=$(jq '.latencies."95"' current.json)
echo "Current P95 latency: ${P95}ns"
if [ "$P95" -gt "$((THRESHOLD_P95_MS * 1000000))" ]; then
echo "FAIL: P95 latency exceeds threshold"
exit 1
fi
echo "PASS: Performance within acceptable limits"
Be Mindful of Rate Limits and Test Environments
Always test against staging or dedicated performance environments. Running aggressive load tests against production can cause real outages. If you must test production, use low rates and short durations, and coordinate with your team.
Conclusion
Vegeta is a powerful, no-nonsense load testing tool that fits naturally into developer workflows. Its command-line interface, predictable request rate model, and flexible output formats make it ideal for both ad-hoc testing and automated performance validation. By incorporating Vegeta into your development process, you gain visibility into how your applications behave under stress, allowing you to catch performance issues early and ship more reliable software. Start with simple tests against your most critical endpoints, build up realistic scenarios over time, and automate the process to ensure performance remains a first-class concern throughout your development lifecycle.