ngxtop: a terminal metrics view built by tailing your nginx access log
Real-time metrics for nginx server
At a glance
- What is it?
- A Python script that parses an nginx access log and prints top-like request counts, status breakdowns and byte averages, with a docopt CLI over the top.
- Who is it for?
- ngxtop is built for one specific moment: somebody is asking what the server is doing right now and does not want to wait for a dashboard. That constraint explains the whole design, including the default of following only newly written lines, the two second refresh interval and the absence of any data export.
- 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 October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Zero configuration when the log format is the default one
The pitch in the README is that you run the command and it works. `ngxtop` tries to work out where the access log lives and what shape it has by parsing your nginx configuration, which is why the release notes for 0.0.2 mention PyParsing being brought in specifically to detect the log file location and format. When that works, no flags are needed at all and you get the default view: request counts per path, average bytes sent, and a breakdown by 2xx, 3xx, 4xx and 5xx.
$ ngxtop
running for 411 seconds, 64332 records processed: 156.60 req/secThe sample output in the README makes the shape of the data obvious. The summary row is one line per status class, and the detailed table is grouped by request path by default, with the busiest paths at the top. The rate figure is computed over the whole run, not a moving window, which matters when you read those numbers: it tells you the average since you started watching, not what is happening in the last two seconds.
This is a log parser, not an nginx client. Nothing is queried over HTTP, no stub status module is required, and the only cost is reading lines off disk. That is the structural difference from something like `stub_status` or a Prometheus exporter, and it is why ngxtop works against Apache logs too.
A docopt CLI where the query language is part of the command
The interface has three shapes rather than one, which is unusual and worth learning. A bare `ngxtop [options]` runs the live view. Adding a mode word and a variable turns it into a query: `(print|top|avg|sum)` followed by the field name. And `ngxtop info` is a separate self describing mode.
Usage:
ngxtop [options]
ngxtop [options] (print|top|avg|sum) <var>
ngxtop infoGrouping, ordering and filtering are all flags rather than a separate configuration file. The default group key is `request_path`, the default output order is `count`, and `-w` takes a having expression that defaults to `1`, meaning everything passes. To see which clients are sending the most traffic you switch to the `top` mode with a different field:
$ ngxtop top remote_addr
running for 20 seconds, 3215 records processed: 159.62 req/secThe interesting capability is combining a filter with an arbitrary field list. The README's example of surfacing errors together with their referer uses `-i` for a filter expression and then two bare fields after `print`:
$ ngxtop -i 'status >= 400' print request status http_referer
running for 2 seconds, 28 records processed: 13.95 req/secThat combination is the reason to reach for this rather than `awk`. Writing `awk` to bucket status codes and print two columns is a ten minute job that you will write again next month; here it is one flag. The cost is a learning curve, since the expressions are parsed by pyparsing and the error messages when you get them wrong are not documented anywhere in the README.
Following only new lines, and the flag that changes that
The default behaviour surprises people enough that the README spells it out in the option list. Run `ngxtop` against a log that already has a million lines in it and it will not process them. It positions itself at the end and watches for lines as they are written.
--no-follow ngxtop default behavior is to ignore current lines in log
and only watch for new lines as they are written to the access log.
Use this flag to tell ngxtop to process the current content of the access log instead.
-t <seconds>, --interval <seconds> report interval when running in follow mode [default: 2.0]There is a good reason for it. The tool is a troubleshooting instrument, and its own description says it is designed to run in a short period like `top` does. Streaming a large historical log through it would produce totals that describe last week while you are trying to diagnose right now, which is actively misleading. When you do want the historical view, `-t` sets the reporting interval and `--no-follow` turns off the tail behaviour, so the combination gives you a snapshot over accumulated data.
The two second default interval is also deliberate. Slower and the display feels broken; faster and you are redrawing a table faster than anyone can read it.
Piping a remote Apache log into it
Because the parser is decoupled from nginx, the log format flag is the main thing that varies. The supported formats are `combined` as the default, `common` for the Apache shared log format, and `caddy` for Caddy's JSON access logs. The Caddy support is the newest-looking item in that list and the least likely to be one you need.
$ ssh user@remote_server tail -f /var/log/apache2/access.log | ngxtop -f common
running for 20 seconds, 1068 records processed: 53.01 req/secThat line is worth reading twice, because it is the whole design in one command. No agent, no configuration change on the remote host, no port to open beyond SSH. Whatever writes lines that look like a common access log can be the input, including a container's stdout. If your custom `log_format` directive deviates from combined, you can pass the format string with `-f` in the same syntax nginx uses, or let `-c` point at a config file so the detection runs against that instead of the default paths.
Three dependencies, and a Python story the README and the metadata disagree about
The dependency list in setup.py is three names long: docopt for the command line grammar, tabulate for the ASCII tables you see in every sample, and pyparsing for both the nginx config parsing and the filter expressions. That is a small enough surface that you can read the whole thing in an afternoon, and the package is a single `ngxtop` directory with a `tests/` folder beside it.
The Python version story is where the documentation and the metadata disagree, and it is worth stating plainly rather than picking one and hoping. The README says the tool is primarily developed and tested with Python 2 but also supports Python 3. The release notes for v0.0.3, published 2020-12-21, are titled "Finally Python3 compatible". The classifiers in setup.py list Python 2.6, 2.7, 3.2 and 3.3, and classify the project at development status 4, Beta.
Read together, the most defensible summary is that Python 3 support arrived late and was never tested broadly. A classifier listing 3.2 and 3.3 tells you what was declared when the package was last versioned, not what works on a current interpreter, and Python 3.2 has been unsupported by the language itself for a very long time. If you are on a recent Python, the sensible move is to install it, run it against a log you know the answer to, and confirm the numbers before putting it in a runbook. The MIT license and the `Intended Audience :: System Administrators` classifier are the parts of that metadata still clearly accurate.
Editorial conclusion
ngxtop is built for one specific moment: somebody is asking what the server is doing right now and does not want to wait for a dashboard. That constraint explains the whole design, including the default of following only newly written lines, the two second refresh interval and the absence of any data export. Because it reads the access log rather than talking to nginx, it works the same on a remote Apache server piped over ssh, and it degrades gracefully when your `log_format` is nonstandard. The honest limits are equally clear. There is no history, so an outage that ended an hour ago leaves no trace, and the README points you at Luameter when you want long running collection instead. Python support is documented in three slightly different ways across the README, the release notes and the package classifiers, so install and smoke test on your own interpreter before trusting it in a script. Start with a bare `ngxtop` against a default log format, then add `-g` to change what the table groups by and `-i` to narrow it to errors.
Frequently asked questions
What does ngxtop actually measure?
It parses lines from an access log, not from nginx itself, so it reports request counts, average bytes sent and a breakdown by status class grouped by whatever field you name. Nothing is stored between runs.
Why is ngxtop not showing me anything that already happened?
Because by default it ignores existing lines and watches only for new ones, so the numbers describe traffic since you started it. Pass --no-follow to process the current contents of the log instead.
Can ngxtop parse Caddy or Apache logs?
Yes, through the -f log format flag, which supports combined (the default), common for Apache, and caddy for Caddy JSON access logs. The README shows piping a remote Apache log over ssh with -f common.
How do I group by something other than the request path?
Use -g with any log field, for example ngxtop top remote_addr for the busiest client addresses. Combine it with -i for a filter expression such as 'status >= 400' to narrow the records before they are aggregated.
Is ngxtop a replacement for a proper monitoring system?
No, and the README says so: it is meant for short, top-like troubleshooting sessions. For long running collection or graphing the project points you at Luameter instead.
Does ngxtop work on Python 3?
Yes, though the project's own records conflict on the details. The README says it was mainly developed on Python 2, release v0.0.3 is titled "Finally Python3 compatible", and the package classifiers stop at Python 3.3.
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/lebinh-ngxtop)