Skip to content
>_devvkit
$devvkit learn --librarie vegeta-guide

Vegeta Guide

[load-testing][http][benchmark][go]
Performance & Profiling
Install
brew install vegeta
# or: go install github.com/tsenart/vegeta/v12@latest
# Windows: download from github.com/tsenart/vegeta/releases

Vegeta's superpower is constant request rate (`-rate` flag) — unlike wrk which pushes maximum throughput, Vegeta lets you specify exactly 500 req/s and measures how the system behaves. This makes it ideal for SLA validation.

Vegeta uses a three-stage pipeline: `attack` (generate load) → `encode` (format output) → `report` (analyze results). You pipe between stages, keeping intermediate binary data compact. The binary format supports distributed attacks — combine results from multiple machines.

Vegeta also ships a Go library so you can embed load testing in your application. Use `vegeta plot results.bin > plot.html` for visual latency distribution charts. GUI: Grafana with Prometheus for long-term trends.

Attack

Basic attackConstant rate load test.
echo "GET https://api.example.com/users" | vegeta attack -rate=100 -duration=30s > results.bin
cat targets.txt | vegeta attack -rate=500 -duration=1m > results.bin
Real-time metricsStream metrics to stdout.
echo "GET https://api.example.com" | \
  vegeta attack -rate=100 -duration=1m -format=json | \
  vegeta encode --to=json | \
  jq '. as $in | {$in.latency, $in.code, $in.bytes_out}'

Report

Generate reportText summary.
cat results.bin | vegeta report
# Outputs: latency p50/p95/p99, req/s, success rate, bytes in/out
Histogram reportLatency buckets.
cat results.bin | vegeta report --type=histogram --buckets "0,50ms,100ms,200ms,500ms,1s"
# JSON output:
cat results.bin | vegeta report --type=json | jq '.latencies
Plot HTMLVisual latency chart.
cat results.bin | vegeta plot > plot.html
# Open in browser — shows latency timeline and percentile distribution

Target Files

Target fileMultiple endpoints.
# targets.txt
GET https://api.example.com/users
GET https://api.example.com/products
POST https://api.example.com/orders
Header Authorization: Bearer token123
@body.json

vegeta attack -rate=200 -duration=30s -targets=targets.txt > results.bin
Dynamic bodyVary body per request.
# targets.txt with dynamic content
POST https://api.example.com/events
Content-Type: application/json
@/dev/stdin

# Pipe varied bodies:
echo '{"type":"click"}' | vegeta attack -rate=50 -duration=10s -targets=targets.txt

Distributed

Distributed loadMerge results from machines.
# Machine 1:
echo "GET https://api.example.com" | vegeta attack -rate=250 -duration=2m > m1.bin
# Machine 2:
echo "GET https://api.example.com" | vegeta attack -rate=250 -duration=2m > m2.bin
# Merge:
vegeta encode --to=json < m1.bin > m1.json
vegeta encode --to=json < m2.bin > m2.json
cat m1.json m2.json | vegeta report

Go Library

Go libraryEmbed in Go app.
package main

import (
  "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/users",
  })
  attacker := vegeta.NewAttacker()
  
  var metrics vegeta.Metrics
  for res := range attacker.Attack(targeter, rate, duration, "test") {
    metrics.Add(res)
  }
  metrics.Close()
  
  println("p95:", metrics.Latencies.P95)
}