goben: a single-binary Go tool for measuring TCP, UDP, and TLS throughput
goben is a golang tool to measure TCP/UDP transport layer throughput between hosts.
At a glance
- What is it?
- goben measures transport layer throughput between two hosts over TCP, UDP, or TLS, with one binary and no runtime dependencies, optional bandwidth limiting, and results exportable as ASCII, CSV, YAML, or a PNG chart. The README frames it as a fix for the shortcomings of iperf2 and nepim rather than as a new idea.
- Who is it for?
- goben fits a network engineer who wants a throughput number between two hosts quickly, on any platform, without installing a runtime or a package set, and who wants the result in a form they can paste into a ticket or keep as a PNG.
- 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 131 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 October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is that existing throughput tools were frustrating to use
goben is a Go tool to measure TCP and UDP transport layer throughput between hosts, and the History section explains the motivation better than the feature list does. Years ago, out of frustration with iperf2 limitations, the author wrote the nepim tool, and one can find known iperf problems in a linked article on iperf caveats. Nepim was more customizable, easier to use, reported simpler to understand results, and was lighter on CPU. Later the author found nuttcp, and goben is intended to fix the shortcomings of nepim in three specific ways. Take advantage of multiple CPUs while not wasting processing power, since nepim was single-threaded. Be easily portable to multiple platforms, since nepim was heavily tied to the UNIX-like world. And use a simpler synchronous code flow, since nepim used a hard-to-follow asynchronous architecture. The audience is a network engineer who has been burned by one of those tools and wants something predictable.
One binary, no runtime, and a server plus a client model
The tool is written in Go as a single executable file with no runtime dependency, which is the practical reason to reach for it over a tool that needs a language runtime on the measuring host. The usage model is deliberately simple: start the server, then launch the client pointing at the server's address. The README's example is exactly that, with the server running `goben` and the client running `goben -H 1.1.1.1` where 1.1.1.1 is the server's address. Underneath, it spawns multiple concurrent lightweight goroutines to handle multiple parallel traffic streams, which is the direct answer to the single-threaded complaint about nepim. The Go Report Card, Go Reference, and GolangCI badges in the README signal the usual toolchain hygiene, and the module targets go 1.26.4.
Building it is three commands, and the Makefile has the matrix
Installation with Go Modules, since Go 1.11, is documented as a short sequence. The README asks you to clone the repository outside GOPATH, run the tests, and then install:
git clone https://github.com/udhos/goben ;# clone outside GOPATH
cd goben
go test -v ./...
CGO_ENABLED=0 go install ./cmd/gobenThe `CGO_ENABLED=0` matters because it produces a static binary that will run anywhere, which is the whole point of the no-runtime-dependency claim. You can also run directly from source with `go run ./cmd/goben`. The Makefile covers the rest. The `bin/goben` and `bin/amd64/goben` targets build the executable and a Linux amd64 build, `test` depends on `certs`, which runs `make -C test/certs` to generate the test certificates, and there are `client` and `server` targets that run the tool locally against those certificates. The `lint` target is worth a look, since it installs and runs `revive`, `govulncheck`, and `deadcode`.
TLS is on by default, and mutual authentication is on by default too
The command line options are where the tool's design shows. TCP and TLS both default to true, and the README notes that TLS can be enforced by disabling TCP and UDP. The TLS options take a CA certificate file, a certificate, and a private key, all in PEM format, with defaults of ca.pem, cert.pem, and key.pem. Both `--tlsAuthClient` and `--tlsAuthServer` default to true, meaning mutual TLS is what you get unless you turn it off, which is unusual and sensible for a measurement tool. Buffer sizes are explicit. TCP read and write buffers default to 1000000 bytes each, and UDP read and write buffers default to 64000. Those numbers shape the results, because they determine how much data is in flight, and they are the first thing to check if a result looks unlike what you expected.
Bandwidth limiting, one-way modes, and duration controls
Several options exist for shaping the test rather than just running it flat out. The `--maxSpeed` flag sets a bandwidth limit in Mbps, where zero means unlimited. The `--passiveClient` and `--passiveServer` flags suppress traffic in one direction, so each side only receives, which is how you isolate upload from download on a single path. The `--connections` flag sets the number of parallel connections to each host, and the `--hosts` flag takes a comma-separated list in the format host[:port], where the port defaults to `--defaultPort`, which is `:8080`. Time is controlled by `--totalDuration`, with the default of 10s, and `--reportInterval` sets the periodic throughput report, with the default of 2s and an unspecified time unit defaulting to a second. The `--localAddr` flag binds a specific local address and port, for example `127.0.0.1:2000`.
Results export as ASCII, CSV, YAML, or a PNG chart
The export mode is a comma-separated or repeated flag, with values of ascii, csv, yaml, png, or filenames, and the help text gives the pattern `--export ascii,csv,result-%d-%s.yaml` or `-e my.yaml -e my.png`. The feature list names the same set, adding that test results can be saved as a PNG chart and exported as YAML or CSV. The dependencies explain the implementation, with `github.com/guptarohit/asciigraph` for the terminal chart, `github.com/wcharczuk/go-chart` for the PNG, `gopkg.in/yaml.v3` for YAML, and `github.com/spf13/pflag` for the command line parsing. The ASCII output is the one to try first, because it means the result can be read straight from the terminal on a host with nothing installed, which is the situation the tool was designed for.
A different tool from iperf, with a different set of trade-offs
The comparison with iperf2 and nuttcp is worth making explicitly, because both are named in the README. The difference in approach is that goben is a self-contained Go binary with a small, readable option set, a synchronous code flow, and results it can draw in the terminal, while iperf2 is the older, more universally deployed tool and nuttcp is the one the author found after nepim. The trade-off runs both ways. goben is easy to drop onto a server with no runtime and easy to script, and its output is easy to read. What it does not have is the maturity and the breadth of the established tools, and the README is not shy about that, since it points readers to a list of known iperf problems as the reason its own tool exists. If you already have iperf installed and working, goben earns its place by being easier to run and read, not by measuring differently.
Editorial conclusion
goben fits a network engineer who wants a throughput number between two hosts quickly, on any platform, without installing a runtime or a package set, and who wants the result in a form they can paste into a ticket or keep as a PNG. It is the wrong tool if you need to measure anything above the transport layer, since it reports TCP, UDP, and TLS throughput rather than application performance, and it is the wrong tool if you need the mature ecosystem of iperf, because the README itself points at iperf caveats as the reason this exists. Before you adopt it, run it against the hosts you actually care about, and read the default buffer sizes, because the TCP read and write buffers default to 1000000 bytes and the UDP ones to 64000, and those defaults shape the numbers you get.
Frequently asked questions
How do I install and run goben?
Clone the repository outside GOPATH, run `go test -v ./...`, then `CGO_ENABLED=0 go install ./cmd/goben` to get a static binary with no runtime dependency. You can also run it directly from source with `go run ./cmd/goben`, or download a binary release from the repository's releases page.
How do I run a goben throughput test?
Start the server with `goben` on one host, then start the client on the other with `goben -H <server address>`. The client takes a comma-separated list of hosts in the format host[:port], where the port defaults to the `--defaultPort` value of `:8080`.
Can goben measure TLS throughput?
Yes. TLS is enabled by default, with TCP and UDP both defaulting to true, and TLS can be enforced by disabling TCP and UDP. The `--cert`, `--key`, and `--ca` options take PEM files, and mutual TLS is enabled by default on both the client and server side through `--tlsAuthClient` and `--tlsAuthServer`.
What output formats does goben support?
The `--export` flag takes a comma-separated or repeated list of ascii, csv, yaml, png, or filenames, for example `--export ascii,csv,result-%d-%s.yaml` or `-e my.yaml -e my.png`. The ASCII chart is rendered with asciigraph and the PNG chart with go-chart.
How does goben limit bandwidth during a test?
The `--maxSpeed` flag sets a bandwidth limit in Mbps, where zero means unlimited. The `--passiveClient` and `--passiveServer` flags suppress traffic in one direction so each side only receives, and `--connections` sets the number of parallel connections to each host.
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/udhos-goben)Was this useful?