Enabling a protected stub_status endpoint in Nginx exposes live connection and request counters that help confirm whether the web tier is backed up under traffic, stalled behind slow clients, or simply idling normally. The page is small, immediate, and useful during incidents, load tests, or initial monitoring setup.
The stub_status directive from ngx_http_stub_status_module publishes a plain-text snapshot that includes Active connections plus cumulative accepts, handled, and requests counters, followed by the current Reading, Writing, and Waiting states. It is usually placed in a dedicated exact-match location inside a server block and queried with curl or a monitoring collector.
Examples below use packaged Nginx on Debian or Ubuntu, where site files commonly live under /etc/nginx/sites-available and reloads use nginx.service. Source builds need the module compiled with --with-http_stub_status_module, and any allowlist must match the client address that Nginx actually sees, so reverse-proxy or load-balancer deployments may need real-IP handling before off-box access rules behave as intended.
Related: How to improve Nginx performance
Related: How to restrict access by IP in Nginx
Steps to enable the Nginx stub_status page:
- Confirm that the installed Nginx build includes the stub_status module.
$ nginx -V 2>&1 | grep -- --with-http_stub_status_module configure arguments: ##### snipped ##### --with-http_stub_status_module ##### snipped #####
Packaged builds on Debian and Ubuntu normally include the module, while source builds need the --with-http_stub_status_module configure option.
- Open the server block file that should expose the status endpoint.
$ sudo vi /etc/nginx/sites-available/example.com.conf
On layouts without sites-available, edit the loaded server block file under /etc/nginx/conf.d/ or another path included from /etc/nginx/nginx.conf.
- Add an exact-match status location inside that server block.
location = /nginx_status { stub_status; access_log off; allow 127.0.0.1; allow ::1; deny all; }Rules are checked in order until the first match, so keep every allow line before deny all and use location = /nginx_status to avoid matching subpaths such as /nginx_status/foo.
- Test the Nginx configuration for syntax errors.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Related: How to test Nginx configuration
- Reload Nginx to apply the updated configuration.
$ sudo systemctl reload nginx
Use sudo nginx -s reload when systemd is not managing the service.
Related: How to manage the Nginx service
- Query the local status endpoint and confirm that the counters are returned.
$ curl -s http://127.0.0.1/nginx_status Active connections: 1 server accepts handled requests 3 3 3 Reading: 0 Writing: 1 Waiting: 0
The accepts, handled, and requests values are cumulative counters, while Active connections, Reading, Writing, and Waiting show the current connection state.
- Query the same path from an address or network that is not on the allowlist.
$ curl -i --interface 127.0.0.2 http://127.0.0.1/nginx_status HTTP/1.1 403 Forbidden Server: nginx/1.24.0 (Ubuntu) Date: Thu, 09 Apr 2026 12:50:22 GMT Content-Type: text/html Content-Length: 162 Connection: keep-alive <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.24.0 (Ubuntu)</center> </body> </html>
A 200 response from an untrusted address means the endpoint is exposed and the allow or deny rules need correction immediately.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
