The newest release is from 2020, the JSON schema is versioned, and the Makefile forgets one target
curl statistics made simple
At a glance
- What is it?
- httpstat is a single-file Python script that turns curl timing output into a readable breakdown, and it has grown a structured output mode, an SLO exit code and an agent skill since then. The last GitHub release is 1.3.0 from 2020, the environment variable list is explicitly a demo, and the readme points Windows users at somebody else's implementation.
- Who is it for?
- httpstat is a good fit if you want curl's timing phases made readable, or if you want a stable JSON shape and a non-zero exit code when a latency threshold breaks, and the single-file property means you can run it without installing anything. Decide how you install before you rely on those newer features.
- 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?
- Activity is slowing. The repository last received commits 7 months ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- reorx/httpstat6,221 ★ · +1
| Repository | 2026-09-23 | 2026-11-14 |
|---|---|---|
| reorx/httpstat | 6.2k | 6.2k |
1 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The newest release predates every structured feature the page describes
Three releases exist: 1.2.0 and 1.2.1 from September and October 2016, and 1.3.0 from 2020-10-15. The machine-readable output with a versioned schema, the SLO threshold check that exits with code 4, the flag that saves results to a file and the agent skill are all described as current features, and the release list does not say which of them shipped in 1.3.0. The README lists three install routes: downloading the script from the default branch with wget, pip install httpstat, and brew install httpstat (macOS only). The version number itself lives in the script rather than in the packaging metadata, since the project metadata declares its version as dynamic and reads it from an attribute of the module, which is consistent with a script that people also run straight from a checkout.
The page says Python 3 and the packaging metadata says 3.9
The compatibility claim on the page is loose: the script is described as compatible with Python 3, with no floor named. The packaging metadata is specific. It requires Python 3.9 or later and carries classifiers for 3.9 through 3.13, so a 3.8 interpreter is outside what the distribution claims to support even though the prose does not say so. The package is built with setuptools and wheel, and it ships one module rather than a package tree: the manifest lists a single module in its setuptools configuration and maps the console command to a main function inside it. That arrangement is what lets the same file be installed with pip, installed by a package manager, or run directly with the interpreter, all three of which the page offers. There is one development dependency group and it contains a single entry, a test runner, which matters more for the build than for the runtime, since the README describes the script as having no dependency.
The timings object mixes the tool's phases with curl's own counters
The sample JSON output is worth reading as a schema rather than as an example, because the field names tell you what was computed and what was passed through. The timings object holds ten keys. Six of them are the phases the tool presents to a human: DNS, connect, TLS, server and transfer, plus a total. The other four are curl's own cumulative numbers: name lookup, initial connect, pretransfer and start transfer. So a consumer has both a decomposition and the raw counters in one flat object with no indication of which is which. Above that sit a speed object with download and upload rates, a response object carrying the status line, status code, remote address and headers, and four top-level fields: a schema version, the url, an ok flag and the exit code. The schema version is the field that makes the rest safe to build on.
Threshold checks are a flag, an exit code and a field in the same output
The SLO feature is small and completely specified, which is rarer than it should be. The flag takes a comma separated list of thresholds:
httpstat httpbin.org/get --slo total=500,connect=100,ttfb=200Five keys are supported: total, connect, ttfb for time to first byte, dns and tls. A violation exits with code 4. In the pretty output the breaches are printed in red at the end, after the timings, so a human sees them without scrolling. In JSON mode the same information appears in a field that is otherwise null, holding a pass flag and a list of violations, and each violation names the key, the threshold in milliseconds and the actual measurement. The exit code and the field are redundant with each other on purpose: one is for a shell, the other is for a log pipeline. The SLO section does not specify how a partially failing run interacts with the ok flag at the top level.
The environment variable section says outright that it is a demo
The heading introduces the environment variables as a bunch of them, then hands you a list and adds that these are some usage demos and that the help output holds the full explanation. Treat the list accordingly. Two of the eight have a default that surprises people: showing the remote and local address is on by default, while showing download and upload speed is off, and the body is saved to a temporary file by default while showing it in the output is off and capped at 1023 bytes. One variable is on its way out: the metrics-only switch still forces JSON output but is described as kept for backward compatibility, with the format flag preferred instead. One points outside the shell: the curl binary variable exists to run a different curl than the one on your path, and the example uses it to get an HTTP/2 response, which the page then qualifies by saying curl has to be compiled with nghttp2, citing an old issue for the detail. Colour is disabled by the conventional environment variable, set to any value.
Five curl flags are reserved, and one of them is the silent flag
Because the tool is a wrapper, the page states which parts of curl are off limits: any supported option may be passed after the url except five that the tool has already claimed. They are the write-out format flag, the dump-headers flag, the output-file flag, and both the silent and show-error flags. That list has a practical consequence. The first instinct of anyone scripting curl is to silence output, and here that flag is the one most likely to be swallowed, along with the flag that chooses the output file, which is what the separate save flag is for instead. The passthrough is otherwise complete, and the example combines a method, a form-encoded data argument and the verbose flag in a single invocation:
httpstat httpbin.org/post -X POST --data-urlencode "a=b" -vSo the model is: url first, then curl, with five specific exceptions and a separate set of flags for output handling.
make test runs a shell script while the dev group declares a python runner
The Makefile has four targets and declares three of them phony. Test runs a shell script with bash, clean removes the build directory, the distribution directory and any egg metadata, build calls the uv build command, and publish depends on clean and build and then calls uv publish. The one target missing from the phony declaration is publish. The more interesting split is between the two test arrangements. A development dependency group declares a pytest release, and a tests directory exists at the root, while the make target runs httpstat_test.sh, a shell script, and never mentions the runner in the group. So there are two testing stories and the one wired into the Makefile is not the Python one. The tree also holds a lock file for the uv tool, a knowledge base directory, agent instructions in two files at the root, and a skills directory holding the packaged skill.
The page points Windows users at somebody else's implementation
The install section ends with a note for Windows users, suggesting a Go implementation maintained by somebody else, with a link to its releases. Then a related projects section lists four implementations in other languages, including that Go version, and the descriptions are personal rather than comparative: a Go version written in pure Go that relies on no external programs, which the page recommends for people who like solid binary execution and then admits the author uses it too, a Go library intended for debugging latency inside Go code with an article linked, a Bash version praised as the thing the author originally wanted to write, and a Node version credited to a third party's write-up. A tool that tells you its own Python script can be replaced by four others is telling you something real about where it sits.
Editorial conclusion
httpstat is a good fit if you want curl's timing phases made readable, or if you want a stable JSON shape and a non-zero exit code when a latency threshold breaks, and the single-file property means you can run it without installing anything. Decide how you install before you rely on those newer features. The newest release is 1.3.0 from October 2020, while the JSON format, the SLO check with its exit code and the agent skill are documented against the script on the default branch, so check which version a package install gives you before relying on them. Two smaller things to know: the environment variable section says outright that it is a set of demos, so run the help output before scripting around it, and the reserved curl options mean five familiar flags will not behave the way they do in curl, including the silent flag you might reach for first.
Frequently asked questions
Does pip install httpstat give me the features in the readme?
The README does not say which version pip installs; it lists pip install httpstat as one of three install routes. The newest release is 1.3.0 from 2020-10-15, while the JSON format, the SLO check that exits with code 4 and the agent skill are documented against the script on the default branch. Downloading the script directly gets the copy that carries those flags.
Which Python version does httpstat support?
The packaging metadata requires 3.9 or later and classifies 3.9 through 3.13, while the readme says only that the script is compatible with Python 3. The distribution ships one module and maps the console command to a main function inside it.
How do I fail a command when an httpstat latency threshold is broken?
Use the SLO flag with thresholds such as total=500,connect=100,ttfb=200. The supported keys are total, connect, ttfb, dns and tls, a violation exits with code 4, and in JSON mode the breaches appear in the slo field with the key, the threshold and the actual measurement.
Which curl options can I pass through httpstat?
Any curl option after the url except five the tool has claimed for itself: -w, -D, -o, -s and -S. A separate environment variable points httpstat at a different curl binary, which the readme uses to get an HTTP/2 response, noting that curl must be compiled with nghttp2 for that.
Is there an httpstat that does not need Python?
The readme points Windows users at a Go implementation that relies on no external programs, and its related projects section names a Go version, a Go library, a Bash version and a Node version, each with its own repository.
How do I run httpstat's tests?
The make target runs httpstat_test.sh with bash. The project's development dependency group separately declares pytest and a tests directory exists at the root, so the Python runner is available but is not what the Makefile invokes.
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/reorx-httpstat)Star history chart for your README
[](https://hysenlabs.com/projects/reorx-httpstat)Was this useful?