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