Categorica open-sources nginx-stats-prometheus, an NGINX module for Prometheus metrics
Categorica has open-sourced nginx-stats-prometheus, its own module that makes NGINX serve Prometheus statistics itself. The company uses NGINX as a reverse proxy and for serving web content, Prometheus to collect metrics and Grafana to display them.
The authors say there is only really one choice for NGINX metrics collection: NGINX Prometheus Exporter, which they call a fully featured Prometheus exporter. Their objection was a simple one: why does the metrics endpoint run its own web server? The exporter can run as a systemd service, which is just a regular binary, but it is more typical to deploy it as a Docker sidecar container. The authors call that an additional complexity that doesn't feel necessary. It also means metrics collection itself escapes metrics collection, "who watches the watchmen". They built the module in their evenings and weekends, and it quickly became their preferred mechanism for statistics collection.
Setup takes some command-line work. Building NGINX from source is recommended so the required features are compiled in, though not required. If you use an existing NGINX build, it must have been compiled with --with-compat and --with-http_stub_status_module. You need the NGINX sources to compile the module (the supplied Makefile can fetch them, based on the output of nginx -v, or you can point the NGINX_SRC variable at your own sources), a C99 compiler such as Clang, and the PCRE, OpenSSL and zlib libraries and headers. The steps assume a Unix-like environment. The plugin is built with make module and sudo make install.
Configuration loads ngx_http_stats_prom_module.so, then defines a server block, in the example listening on port 9100, with a location /metrics that contains the directive prometheus_metrics. The metrics are then served at http://hostname:9100/metrics. The sample response includes nginx_up, nginx_process_pid, nginx_http_requests_total (434488 in the sample) and nginx_http_responses_total split by status class (1xx to 5xx). These process-level metrics are available as soon as the process starts and are measured from process start. There are also basic metrics for each server or upstream directive in nginx.conf, which appear after the first request on that prefix.
There are hard limits. At most 512 server or upstream directives are supported, and prefix lengths over 255 characters are ignored. Only 1 megabyte of memory is allocated for statistics by default; if it runs out, collection is silently skipped. The size can be changed with prometheus_metrics_shm_size.
The authors list the limitations plainly. The module is not a drop-in replacement for nginx-prometheus-exporter. Significantly fewer statistics are collected. It is tied to the NGINX version it is built against, so updating NGINX typically means rebuilding the plugin. And it is significantly less battle tested, since their own stats collection is far less mature and used.
The module is MIT licensed. Pull requests are welcome, provided a human has at least reviewed the patch-set first. Categorica offers no support and cannot guarantee help with any issues. The post suggests it for people who want to run NGINX without containers, simplify deployment configuration, or simply prefer collecting statistics from a plugin.
Key facts
- Categorica released nginx-stats-prometheus, an NGINX module that serves Prometheus metrics from inside NGINX, under the MIT licence.
- It removes the separate exporter process or Docker sidecar that NGINX Prometheus Exporter typically needs.
- Hard limits: at most 512 server or upstream directives, prefixes over 255 characters ignored, and 1 MB of statistics memory by default (set with prometheus_metrics_shm_size).
- The authors say it is not a drop-in replacement: significantly fewer statistics, tied to the NGINX version it is built against, and significantly less battle tested.
- NGINX must be built with --with-compat and --with-http_stub_status_module; the project offers no support.
Why it matters
NGINX metrics have had essentially one route: the separate NGINX Prometheus Exporter. This module moves collection inside NGINX, so there is no extra web server or sidecar container to deploy and monitor. The authors frame this as removing a complexity that doesn't feel necessary, and as closing the gap where the metrics collector itself escapes metrics collection. It is a small, niche project, and the authors themselves present it as a trade-off rather than a better exporter.
Who it affects
Teams that run NGINX, collect metrics with Prometheus and are comfortable compiling software. The post names three groups: people who want to run NGINX without containerisation, people who want a simpler deployment configuration, and people who just prefer collecting statistics from a plugin. Anyone who relies on the full set of statistics from the existing exporter is not the target.
How to use it
Build or check your NGINX: it needs --with-compat and --with-http_stub_status_module. Have the NGINX sources, a C99 compiler and the PCRE, OpenSSL and zlib headers ready. Run make module and sudo make install. Then add load_module modules/ngx_http_stats_prom_module.so, a server block (the example listens on 9100) and a location /metrics with prometheus_metrics. Check it with curl http://localhost:9100/metrics. If 1 MB of statistics memory is not enough, raise prometheus_metrics_shm_size. The module is MIT licensed.
How solid is it
This is a first-party release from the company that wrote it, and it has been their preferred mechanism for statistics collection. The post gives no benchmarks or overhead measurements, and no supported NGINX version range. It does not claim adoption outside Categorica. The authors say it is significantly less battle tested than the existing exporter and far less mature.
Risks and caveats
Significantly fewer statistics are collected than with NGINX Prometheus Exporter, so it is not a drop-in replacement and existing dashboards may not carry over. The module is tied to the NGINX version it is built against, so NGINX updates typically mean rebuilding it. Hard limits apply: 512 server or upstream directives, 255-character prefixes. If the 1 MB statistics memory fills up, collection is silently skipped. Categorica offers no support and does not guarantee help with issues. Contributions must at least be reviewed by a human before submission.
“Why does the metrics endpoint itself run its own web-server?”
— Categorica, in the post announcing nginx-stats-prometheus