Brand logo
HomeCloud ComputingSecuritySoftware DevelopmentAI ApplicationsStartupsGeneral
  1. Home
  2. /
  3. softwaredevelopment
  4. /
  5. categorica-nginx-plugin-prometheus-metrics

From Side-car Collector to Compiled Module: An Engineering Runbook for NGINX Metrics

Why teams that build reverse-proxy paths care about this plugin

For delivery teams that manage gateway code, build scripts, and telemetry in the same workflow, Today provides a concrete reference: Categorica released nginx-stats-prometheus as an open-source NGINX plugin that exposes Prometheus-compatible counters and gauges directly from the proxy process. The practical audience is engineering groups already running NGINX, Prometheus, and Grafana, and the design question is not whether metrics matter, but whether a separate collector process should remain part of the build and deployment topology.

From a side-car habit to a compiled module

The starting point was a narrow complaint, not a major outage. When gathering gateway telemetry, only really one fully featured path existed: NGINX Prometheus Exporter. Yet its endpoint still needed its own web-server. Categorica acknowledged that this is not a major problem: the exporter can be deployed as a systemd service, and therefore as a regular binary, although Docker side-car containers are the more common pattern in many environments. The objection was architectural: an extra side-car increases deployment complexity, and the metrics path can evade metrics collection, in the manner of "who watches the watchmen". The plugin approach was born from free evenings and weekends; As of today, it is being shared.

A practical build-and-configure tutorial

Before you compile: prerequisites and assumptions

The work is command-line oriented. A basic understanding of the GNU "configure, make, make install" dance helps, though it is not strictly necessary. Building NGINX from source is recommended because the required features must be compiled in, and a package manager’s build of NGINX may differ; even then, it is not mandatory.

  • Even when you are not building NGINX from source, the NGINX sources are still needed to compile the module; the supplied Makefile can perform this step.
  • If NGINX is not being built from source, it must have been compiled with --with-compat and --with-http_stub_status_module.
  • A C99 compiler, such as Clang, is required.
  • The PCRE, OpenSSL, and zlib libraries and headers must be present.
  • These steps assume a Unix-like environment.

Step 1: build NGINX when it is not already suitable

Skip this step if an appropriate NGINX version is already installed. In a terminal, use:

cd path-to-nginx-source;
# we'll use the path to the NGINX source whilst building the plugin.
export NGINX_SRC=`pwd`;
./configure --with-compat --with-http_stub_status_module;
make -j;
sudo make install;

This builds and installs NGINX, typically with the /usr/local prefix. For more details about building NGINX, consult their documentation.

Step 2: build and install the plugin

If an appropriate NGINX version is already installed, the supplied Makefile determines its version by invoking nginx -v, then downloads the NGINX sources needed to build the plugin.

If that behavior is not wanted, set the path to the NGINX sources with the environment variable NGINX_SRC; this skips the version check and source download.

Afterward, build the plugin with:

make module
sudo make install

This builds the plugin and installs it to the correct plugin location. More information can be found on Categorica’s Github repository’s README.md.

Step 3: load the module and expose a metrics route

After building the plugin, configuration must describe the route where statistics should be exposed.

load_module modules/ngx_http_stats_prom_module.so;
http {
  # Optional: set shared memory size (default 1m)
  # prometheus_metrics_shm_size 2m;
  server {
    # standard NGINX server directives apply here
    listen 9100;
    location /metrics {
      prometheus_metrics;
    }
  }
}

This configuration exports statistics suitable for Prometheus ingestion at http://hostname:9100/metrics. Assuming the NGINX instance runs locally, the endpoint can be queried with curl:

curl http://localhost:9100/metrics

Sample response:

# HELP nginx_up Whether the nginx process is up
# TYPE nginx_up gauge
nginx_up 1
# HELP nginx_process_pid PID of the worker process (serving metrics)
# TYPE nginx_process_pid gauge
nginx_process_pid 2985885
# HELP nginx_http_requests_total Total number of HTTP requests
# TYPE nginx_http_requests_total counter
nginx_http_requests_total 434488
# HELP nginx_http_responses_total HTTP responses by status class
# TYPE nginx_http_responses_total counter
nginx_http_responses_total{status="1xx"} 0
nginx_http_responses_total{status="2xx"} 42598
nginx_http_responses_total{status="3xx"} 771
nginx_http_responses_total{status="4xx"} 77
nginx_http_responses_total{status="5xx"} 1
# etc.

What the metrics endpoint returns

Once the process is running, NGINX metrics should be visible on the route specified in the configuration. The following metrics are available immediately and are measured from process start.

MetricTypeLabels
nginx_upgauge
nginx_process_pidgauge
nginx_http_requests_totalcounter
nginx_http_responses_totalcounterstatus (1xx – 5xx)
nginx_http_requests_by_method_totalcountermethod (GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH, other)
nginx_http_request_bytes_totalcounter
nginx_http_response_bytes_totalcounter
nginx_http_version_totalcounterversion (1.0, 1.1, 2.0, 3.0)
nginx_http_request_duration_secondshistogram(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10)
nginx_connections_activegauge
nginx_connections_readinggauge
nginx_connections_writinggauge
nginx_connections_waitinggauge
nginx_connections_accepted_totalcounter
nginx_connections_handled_totalcounter

In addition, basic metrics exist for each server or upstream directive defined in nginx.conf. These appear after the first received request on that prefix.

MetricTypeLabels
<prefix>_requests_totalcounterserver / upstream
<prefix>_response_totalcounterserver / upstream, status (1xx – 5xx)
<prefix>_request_bytes_totalcounterserver / upstream
<prefix>_response_bytes_totalcounterserver / upstream

At most, 512 server or upstream directives are supported. Prefix lengths greater than 255 characters are ignored. Only 1 megabyte of memory is allocated for statistics. If this is exhausted, statistics collection is silently skipped. This can be configured in NGINX with prometheus_metrics_shm_size.

Comparison table: in-process plugin versus separate exporter

Engineering dimensionnginx-stats-prometheusnginx-prometheus-exporter
Process shapeStatistics are exposed through NGINX itself by a loaded module.A separate metrics endpoint runs its own web-server.
Typical deploymentPlugin build and install into the correct plugin location.Can be deployed as a systemd service, and therefore as a regular binary, but is more commonly run through Docker side-car containers.
Metrics coverageSignificantly fewer statistics are collected.Fully featured Prometheus exporter.
Upgrade couplingTied to the NGINX version it is built against; updating NGINX typically requires rebuilding the plugin.The comparison text does not describe a matching build coupling.
Maturity signalSignificantly less battle tested; the original description states the statistics collection is far less mature and less used.The comparison text does not apply that limitation to the exporter.
Drop-in statusNot a drop-in replacement for nginx-prometheus-exporter.Used as the baseline reference for the stated difference.

Common misconceptions for teams evaluating this pattern

  • A package-manager build of NGINX is always equivalent to the source build used for the module; the article warns it may differ.
  • Metrics collection requires a separate web-server; the plugin was built precisely to avoid the side-car topology while exposing metrics through NGINX itself.
  • Docker side-car deployment is mandatory; the exporter can also be deployed as a systemd service.
  • Shared-memory exhaustion is noisy; if the allocated 1 megabyte is exhausted, statistics collection is silently skipped.
  • Updating NGINX is a routine release task; the plugin is tied to the NGINX version it is built against, so rebuild is typically needed.
  • nginx-stats-prometheus is a drop-in replacement for nginx-prometheus-exporter; the limitation list says it is not.

FAQ: release, support, and operational boundaries

Is this a replacement for the existing exporter?

No. It is not a drop-in replacement for nginx-prometheus-exporter; it collects significantly fewer statistics, is tied to the NGINX version built against, and is significantly less battle tested.

Do I have to build NGINX from source?

No, but it is recommended so required features are compiled in. If NGINX is not built from source, it must have been compiled with --with-compat and --with-http_stub_status_module.

What if the installed NGINX version already exists?

The supplied Makefile can determine its version by invoking nginx -v and then download the needed NGINX sources. To avoid that behavior, set NGINX_SRC.

Where are metrics served?

On the configured route, such as http://hostname:9100/metrics, assuming the server directive listens on 9100.

What is the licence and contribution expectation?

The project is released under an MIT licence. Pull requests are welcome, with the ask that a human has at least reviewed the patch-set before submission. Details live in the Github repository’s README.md.

Is support available?

No support is currently offered, and help with issues arising from use cannot be guaranteed.

Action checklist before adopting the plugin in a release pipeline

  1. Confirm a Unix-like build environment and presence of PCRE, OpenSSL, and zlib headers.
  2. Verify a C99 compiler such as Clang is available.
  3. Decide whether to build NGINX from source or rely on an existing installation with --with-compat and --with-http_stub_status_module.
  4. Run the build sequence: ./configure --with-compat --with-http_stub_status_module; make -j; sudo make install; make module; sudo make install.
  5. Load modules/ngx_http_stats_prom_module.so and expose /metrics through an explicit server block.
  6. Choose shared memory size deliberately; default is 1m, and examples include setting 2m with prometheus_metrics_shm_size.
  7. Smoke-test with curl http://localhost:9100/metrics and review the gauge, counter, and histogram series before wiring Prometheus.
  8. Track the 512 prefix limit, 255 character prefix limit, and silent behavior if 1 megabyte is exhausted.
  9. Record in the release runbook that NGINX upgrades may require plugin rebuilds.

Delivery takeaway

The engineering value of this plugin is not that it adds more telemetry; it is that it moves the metrics endpoint into the same process boundary that applications already traverse. For teams trying to simplify deployment topology, reduce side-car complexity, and keep a Unix build path in the delivery chain, nginx-stats-prometheus offers a small, concrete experiment. Treat it as a versioned, rebuild-sensitive module rather than a universal replacement for nginx-prometheus-exporter, and validate the few limits before production rollout.

Brand logo

IT Insights

Cloud & Infrastructure Practice Media for Enterprise Technology Decision-Makers

Cloud ComputingSecuritySoftware DevelopmentAI ApplicationsStartupsGeneralAI Data News Global

© 2026 IT Insights.

Cookie Notice

We use cookies to improve your experience and analyze website traffic. Read our Privacy Policy to learn more.