Vegeta HTTP Load Test

Vegeta cheatsheet — constant-rate HTTP load testing. echo 'GET http://localhost:8080' | vegeta attack -rate=50 -duration=30s | vegeta report. Latency histograms and percentiles.

6 min read

What it is

Vegeta is a command-line HTTP load testing tool that generates load against a target HTTP service and displays the results in a format that can be easily consumed by other tools or visualized.

Installation

Linux

go install github.com/tsenik/vegeta@latest

or

sudo apt update && sudo apt install vegeta

or

sudo yum install vegeta

Mac

brew install vegeta

or

go install github.com/tsenik/vegeta@latest

Windows

Download the pre-compiled binary from the Vegeta releases page.

Core Concepts

Vegeta operates by sending a specified number of HTTP requests to a target URL at a defined rate. It then collects metrics on the response times, success rates, and other performance indicators.

Commands / Usage

Generating Load

Basic Request

Send requests to a single URL with a default rate of 50 requests per second.

vegeta attack -targets ./targets.txt

Explanation: Sends requests to URLs defined in targets.txt at the default rate.

Specifying Rate and Duration

Send 100 requests per second for 30 seconds.

vegeta attack -targets ./targets.txt -rate 100 -duration 30s

Explanation: Configures the attack to run at 100 requests/second for 30 seconds.

Specifying Total Number of Requests

Send a total of 10,000 requests.

vegeta attack -targets ./targets.txt -max-workers 1000 -max-qps 10000 -duration 1m

Explanation: While -duration is often used, you can also indirectly control the total by setting rate and duration. For a fixed number of requests, vegeta attack -targets ./targets.txt -duration 1m -rate 1000000 will attempt to send that many if the system can handle it.

Sending Requests from a File

Use a targets.txt file to define multiple URLs and HTTP methods.

GET http://localhost:8080/users
POST http://localhost:8080/users
  Body: '{"name": "test"}'
  Header: Content-Type: application/json
GET http://localhost:8080/posts?id=123

Explanation: targets.txt allows defining various requests, including POST bodies and custom headers.

Specifying Workers

Use 50 concurrent workers for the attack.

vegeta attack -targets ./targets.txt -rate 100 -duration 30s -workers 50

Explanation: Controls the number of concurrent workers sending requests.

Body from File

Send a POST request with a body read from payload.json.

cat payload.json | vegeta attack -targets ./targets.txt -rate 100 -duration 30s

Explanation: Pipes the content of payload.json to Vegeta’s stdin, which is then used as the request body for requests targeting POST methods in targets.txt.

Custom Headers

Add a custom X-API-Key header to all requests.

vegeta attack -targets ./targets.txt -header "X-API-Key: your_super_secret_key"

Explanation: Adds a static header to every request.

Dynamic Headers (using header flag multiple times)

Add multiple custom headers.

vegeta attack -targets ./targets.txt -header "X-API-Key: your_super_secret_key" -header "User-Agent: Vegeta-Test"

Explanation: Allows specifying multiple static headers.

From Standard Input

Pipe a list of URLs to vegeta attack.

echo "GET http://localhost:8080/items" | vegeta attack -rate 100 -duration 30s

Explanation: Reads targets from stdin if no file is specified.

Attack with HTTP/2

Enable HTTP/2 for the attack.

vegeta attack -targets ./targets.txt -http2

Explanation: Forces Vegeta to use HTTP/2 for requests.

Reporting and Visualization

Basic Text Report

Generate a text-based summary of the attack results.

vegeta attack -targets ./targets.txt -duration 1m | vegeta report

Explanation: Pipes the binary output of vegeta attack to vegeta report for a human-readable summary.

Plotting Results

Generate an HTML report with latency plots.

vegeta attack -targets ./targets.txt -duration 1m > results.bin
cat results.bin | vegeta plot > plot.html

Explanation: vegeta attack outputs binary results, vegeta plot reads these results and generates an HTML file with visualizations.

JSON Report

Output results in JSON format for programmatic processing.

vegeta attack -targets ./targets.txt -duration 1m > results.bin
cat results.bin | vegeta report -output-json > report.json

Explanation: Generates a JSON output of the attack metrics.

Metrics Report

Display detailed metrics like latency percentiles and throughput.

vegeta attack -targets ./targets.txt -duration 1m | vegeta report -type metrics

Explanation: Provides a detailed breakdown of performance metrics.

Other Commands

Help

Display help information for Vegeta commands.

vegeta --help
vegeta attack --help
vegeta report --help
vegeta plot --help

Explanation: Standard help command for any CLI tool.

Common Patterns

Load Testing an API Endpoint with JSON Body and Authentication

echo '{"username": "testuser", "password": "password123"}' | vegeta attack \
  -targets ./login_targets.txt \
  -rate 50 \
  -duration 1m \
  -header "Content-Type: application/json" \
  -header "Authorization: Bearer your_token" | vegeta report

Explanation: Simulates login requests with a JSON payload and an authorization header, then reports the results. login_targets.txt would contain POST http://localhost:8080/login.

Stress Testing a Service to Find Breaking Point

Gradually increase the rate until errors occur.

for rps in $(seq 100 100 1000); do
  echo "Testing at ${rps} RPS..."
  vegeta attack -targets ./targets.txt -rate ${rps} -duration 30s -output-rate 1000000 | vegeta report -type metrics
done

Explanation: Iteratively increases the request rate and reports metrics for each level, helping to identify the saturation point.

Saving Results for Later Analysis

Store binary results for detailed reporting or plotting.

vegeta attack -targets ./targets.txt -duration 5m -output-rate 1000000 > results.bin
# Later, generate reports
cat results.bin | vegeta report
cat results.bin | vegeta plot > report.html

Explanation: Captures raw attack results for flexible post-processing.

Testing Different HTTP Methods and Paths

Define a targets.txt file with various requests.

GET http://localhost:8080/users
GET http://localhost:8080/users/1
POST http://localhost:8080/users
  Body: '{"name": "new user"}'
PUT http://localhost:8080/users/1
  Body: '{"name": "updated user"}'
DELETE http://localhost:8080/users/1
vegeta attack -targets ./targets.txt -rate 200 -duration 2m | vegeta report

Explanation: Loads test various HTTP methods and paths defined in the targets file.

Gotchas

  • Rate vs. QPS: Vegeta’s -rate flag specifies the target number of requests per second. The actual achieved QPS might be lower if the target service is too slow or if the machine running Vegeta is overloaded. The report will show the actual QPS.
  • Binary Output: By default, vegeta attack outputs binary data. This is efficient for piping but needs to be explicitly processed by vegeta report or vegeta plot.
  • Max Workers: The -workers flag limits the number of goroutines that will be spawned to send requests. If the target is very fast and your machine has many cores, you might need to increase this to achieve your target rate.
  • Target Service Overload: If the target service is overwhelmed, Vegeta might report a high number of errors (e.g., connection refused, timeouts). This is expected behavior for load testing, but it’s important to monitor these error rates.
  • targets.txt Syntax: Be careful with indentation for Body and Header lines. They must be indented with at least one space.
  • duration and rate Interaction: If the duration is too short to achieve the target rate with the specified workers, the total number of requests will be less than rate * duration. Vegeta will try to reach the rate.
  • max-qps vs. rate: -rate is the desired QPS. -max-qps is a hard limit on QPS per worker. If your target is very fast, you might hit -max-qps before -rate is reached. Generally, you’ll use -rate and let Vegeta manage the rest.
  • Firewall/Rate Limiting: Network firewalls or rate limiting on the target server can artificially cap your load test results. Ensure your test environment is configured appropriately.