tsenart/vegeta: HTTP load testing at a fixed request rate
HTTP load testing tool and library. It's over 9000!
At a glance
- What is it?
- Vegeta is a Go CLI and library that fires HTTP requests at a constant rate, records the results in a binary format, and reports latency distributions. It is MIT licensed and the last push was on 2026-09-24.
- Who is it for?
- Adopt Vegeta if you want a constant-rate generator you can script and pipe, and if you are willing to read its report output rather than a dashboard. Do not adopt it if you need scripted user journeys with think times; it replays targets, not sessions.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The constant-rate gap Vegeta fills
Most quick load tests are loops. You write a script that fires N requests as fast as the client can manage, then you look at the average. That number tells you how fast your laptop and the network can push, not how the service behaves at a rate you chose. Vegeta is built around the opposite assumption: you pick a request rate, and the tool tries to hold it. The README describes the project as "built out of a need to drill HTTP services with a constant request rate", and the default is 50 requests per second.
The audience is narrow and specific. If you are a backend engineer who wants a repeatable number to compare before and after a deploy, or a Go developer who wants to call the same machinery from a test, Vegeta fits. If you want a browser-driven scenario with login, cart and checkout steps, it does not. Targets are HTTP requests, not user journeys.
How the attack loop and the binary result file fit together
The pipeline has four commands and one intermediate format. The attack command reads targets, sends requests, and writes a binary stream of results. The report command reads that stream and produces text, JSON, histograms or an HDR plot. The encode command converts the stream to csv, gob or json. The plot command turns it into an HTML page.
The rate flag is the core control. It takes a value like 50/1s, and the documentation notes that 0 means infinity. Workers start at 10 and can grow to -max-workers. The tool avoids what the README calls coordinated omission, which is the distortion you get when a generator stalls and then reports only the fast responses it managed to collect. The README links to a pull request comment and an article on the subject rather than explaining the fix in detail, so the mechanism is a claim you should verify against your own results.
Because results are a file, you can attack once and report many ways. The same results.bin feeds a text summary, a JSON metrics file and a histogram without re-running the test. That is the design decision that makes the tool composable, and it is also why the binary format exists instead of plain text.
Installing Vegeta and running a first attack
The README lists pre-compiled executables on the GitHub releases page, Homebrew and MacPorts on macOS, pacman on Arch Linux, and pkg on FreeBSD. On macOS, Homebrew is the shortest path:
$ brew update && brew install vegetaAfter that, vegeta -version should print a version and exit. On Arch Linux the equivalent is pacman -S vegeta, and on FreeBSD it is pkg install vegeta. If you prefer to build from source, the README gives this sequence, which requires a Go toolchain because the Makefile runs go build:
git clone https://github.com/tsenart/vegeta
cd vegeta
make vegeta
mv vegeta ~/bin # Or elsewhere, up to you.The Makefile builds with CGO_ENABLED=0 and -tags=netgo, so the resulting binary is static. The repository also contains a Dockerfile, which builds the binary in a golang:1.20-alpine3.18 stage and copies it into alpine:3.18.0 with vegeta as the entrypoint.
A first real use is a five second attack against a local service, with the targets coming from stdin in the plain HTTP format. This is the README's own example:
echo "GET http://localhost/" | vegeta attack -duration=5s | tee results.bin | vegeta reportThe report command defaults to text output. You should see a summary with latency percentiles and a success ratio. To keep the numbers instead of the prose, the README shows this form:
vegeta report -type=json results.bin > metrics.jsonFor a latency distribution rather than percentiles, the report command accepts a histogram type with explicit buckets:
cat results.bin | vegeta report -type="hist[0,100ms,200ms,300ms]"One flag worth knowing before you point this at anything shared: -rate defaults to 50/1s, so a five second run sends roughly 250 requests. Raise -duration or -rate deliberately, and use -max-body if you do not want response bodies captured in the result file.
Where the constant-rate model breaks down
Vegeta does not maintain sessions in the browser sense. Each target is an HTTP request, and the -body flag sets one body file for every request unless a target overrides it. If your service behaves differently for a logged-in user with a cookie jar and a sequence of dependent calls, you are testing a shape of traffic that Vegeta does not generate. You can add headers per request and you can vary targets, but ordering and state are your problem.
The DNS behaviour is another boundary. The -dns-ttl flag caches lookups, with -1 disabling the cache and 0 meaning forever, and -resolvers replaces the system resolver entirely. That is useful for testing a specific address, but it also means a misconfigured resolver silently changes what you are measuring. The -connect-to flag goes further and maps a host and port to a different host and port, which is convenient for pointing a production hostname at staging. Both flags make it easy to attack something other than what you think you are attacking, so read the target file before you run.
The result file is binary and the format is not documented in the README. The encode command exists to convert it, and the report command reads it, but if you want to process results in another language you are going through csv or json. That is a real constraint on tooling, not a detail.
Vegeta as a Go library versus hey or k6
The README states that Vegeta is usable both as a command line tool and as a Go library, with the library documented at pkg.go.dev under the v12 module path. That dual identity is the clearest difference from the alternatives.
hey is a Go load generator with a similar command line shape, but it is aimed at a quick request-count run rather than a rate-controlled attack with a persisted result format. If you want one command and a summary, hey is less ceremony. If you want to keep the raw results and report on them later, Vegeta's file-based pipeline is the point.
k6 takes a different approach again: test scenarios are written in JavaScript, which makes staged ramps and per-user logic expressible, at the cost of a scripting runtime and its own execution model. Vegeta's targets are declarative lines, and the tool has no scripting layer. That is a smaller surface to learn and a smaller surface to express yourself in.
The versioning scheme is worth noting for library users. Since v8.0.0 the CLI and library are versioned separately, with CLI releases tagged cli/vMAJOR.MINOR.PATCH and library releases tagged both lib/vMAJOR.MINOR.PATCH and vMAJOR.MINOR.PATCH, the latter for go mod compatibility. The current module path in go.mod is github.com/tsenart/vegeta/v12 and it declares go 1.22.
Maintenance, releases and the MIT licence
The repository is not archived, and the last push was on 2026-09-24. The most recent release listed is v12.13.0 on 2025-10-31, after v12.12.0 on 2024-07-29 and v12.11.3 on 2024-07-27. The gap between v12.12.0 and v12.13.0 is roughly fifteen months, so releases are not frequent. The README states that both the library and the CLI follow SemVer v2.0.0, and the separate tagging scheme for cli/ and lib/ means an upgrade can move one component without the other. Upgrading the library means changing the module path only when the major version changes; the current path pins v12.
The licence is MIT. That permits use, modification and redistribution with the licence text preserved, and it comes with no warranty. This is a summary of the identifier, not legal advice; read the LICENSE file in the repository before you rely on it for a commercial deployment. The README also lists a Gitter channel and a Bitcoin donation badge, which are the project's stated support channels.
Editorial conclusion
Adopt Vegeta if you want a constant-rate generator you can script and pipe, and if you are willing to read its report output rather than a dashboard. Do not adopt it if you need scripted user journeys with think times; it replays targets, not sessions. Before committing, confirm the target file format and the -rate value you intend to use against a staging host, and check whether -prometheus-addr fits your monitoring setup.
Frequently asked questions
How do I install Vegeta?
The README lists pre-compiled executables on the GitHub releases page, Homebrew and MacPorts on macOS, pacman on Arch Linux, and pkg on FreeBSD. Building from source uses git clone, make vegeta, and then moving the binary somewhere on your PATH.
What alternatives to Vegeta should I consider?
hey is a similar Go load generator aimed at a quick request-count run, and k6 lets you write scenarios in JavaScript instead of declarative target lines. The main practical difference is that Vegeta keeps results in a binary file you can report on repeatedly with the report, encode and plot commands.
Does Vegeta send requests at a fixed rate?
Yes. The attack command has a -rate flag that defaults to 50/1s, and the README says a value of 0 means infinity. The project describes itself as built out of a need to drill HTTP services with a constant request rate.
Can I use Vegeta as a Go library instead of the CLI?
The README states that Vegeta is usable as both a command line tool and a Go library, and links to the library documentation at pkg.go.dev. The go.mod module path is github.com/tsenart/vegeta/v12 and it declares go 1.22.
What is the result file format produced by vegeta attack?
The attack command writes a binary stream, which the README's examples pipe into vegeta report or vegeta plot. The encode command can convert that stream to csv, gob or json if you need to process it elsewhere.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tsenart-vegeta)