What Linux TCP “Active, Passive, and Failed Opens” Reveal About Your Server’s Health

When a Linux server feels “slow under load,” the problem is often not CPU or memory—it’s what’s happening at the TCP connection layer. Every second, the kernel counts how many connections it initiates, how many it accepts, and how many fail. Those three numbers—active opens, passive opens, and failed connection attempts—are among the fastest ways to tell whether a box is a healthy client, a healthy server, or quietly dropping connections.

This article explains what each counter means, where to read it, how to turn the raw totals into a per-second rate, and how to interpret the patterns you’ll see in real production systems.


The three counters at a glance

The Linux kernel exposes TCP statistics through SNMP-style counters. The three that describe connection establishment are:

CounterSNMP nameMeaning
Active opensTcp: ActiveOpensConnections this host initiated (it sent the first SYN)
Passive opensTcp: PassiveOpensConnections this host accepted (it received a SYN and completed the handshake)
Failed opensTcp: AttemptFailsConnection attempts that failed to reach the ESTABLISHED state

A useful mental model:

  • Active open = “I am a client.” Your app called connect().
  • Passive open = “I am a server.” Your app called listen()/accept() and a client reached it.
  • Failed open = “something went wrong” before the connection was usable.

Most machines are predominantly one or the other. A web server shows mostly passive opens. A service that calls databases, caches, or upstream APIs shows mostly active opens. A machine doing both (like an API gateway) shows both.


Where to read the counters

Raw source: /proc/net/snmp

Everything ultimately comes from here:

cat /proc/net/snmp | grep ^Tcp

You’ll see two lines—a header and the values:

Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs ...
Tcp: 1 200 120000 -1 5829301 9481120 20733 15522 412 ...

These are cumulative counters since boot. A single reading tells you almost nothing—you need the rate of change.

The friendly tool: nstat

nstat is the right tool for humans. It reads the same counters and can show deltas over an interval:

# Snapshot of nonzero TCP counters
nstat -a | grep -i tcp

# Reset the baseline, wait, then show what changed
nstat -n; sleep 10; nstat

Key fields map directly:

See also: Mastering the Linux Command Line — Your Complete Free Training Guide

  • TcpActiveOpens
  • TcpPassiveOpens
  • TcpAttemptFails
  • TcpEstabResets
  • TcpCurrEstab

The classic: netstat -s / ss -s

netstat -s | grep -A3 -i 'connection'

Produces human-readable lines like “5829301 active connection openings” and “20733 failed connection attempts.” Same numbers, nicer labels.


Turning totals into a rate (the part that matters)

Because the counters only ever increase, the meaningful signal is opens per second. Compute it by sampling twice:

# Simple per-second rate over a 10s window
A1=$(awk '/^Tcp:/{print $6}' /proc/net/snmp | tail -1)   # ActiveOpens
sleep 10
A2=$(awk '/^Tcp:/{print $6}' /proc/net/snmp | tail -1)
echo "Active opens/sec: $(( (A2 - A1) / 10 ))"

Or just let nstat do the differencing:

nstat -n; sleep 10; nstat | awk '/TcpActiveOpens|TcpPassiveOpens|TcpAttemptFails/{print $1, $2/10 "/s"}'

In real monitoring (Prometheus node_exporter, Telegraf, etc.), these are already exposed as counters—graph the rate() and you get the same thing continuously.


Reading the patterns

Here’s how to interpret what you see.

Healthy server

TcpPassiveOpens   high and steady
TcpActiveOpens    low
TcpAttemptFails   near zero

The box mostly accepts connections. A low, flat AttemptFails is normal—some clients always disconnect early.

Healthy client / worker

TcpActiveOpens    high
TcpPassiveOpens   low
TcpAttemptFails   near zero

Typical of a service that fans out to backends. If ActiveOpens/sec is very high relative to your throughput, suspect missing connection pooling—you may be opening a fresh TCP connection per request instead of reusing them.

Rising failed opens — the red flag

TcpAttemptFails   climbing

AttemptFails increments when a connection attempt never reaches ESTABLISHED. Common causes:

  • Connection refused — nothing listening on the target port (client-side active-open failures).
  • SYN timeouts — the peer or network dropped the SYN; firewall blackholing.
  • Backlog overflow on the server — the listen queue is full, so incoming handshakes are dropped (often paired with ListenOverflows/ListenDrops).

Correlate with these companion counters:

nstat -az | grep -Ei 'ListenOverflows|ListenDrops|TCPSynRetrans|TcpAttemptFails'

If TcpExtListenOverflows is rising alongside AttemptFails, your server is accepting connections faster than the application can accept() them—tune the listen backlog and net.core.somaxconn, and check whether the app’s accept loop is blocked.

Connection churn

High TcpActiveOpens and high TcpEstabResets together means connections are being set up and torn down rapidly. That’s expensive—each open costs a handshake and each reset is an abrupt teardown. Look for:

  • Missing or too-small connection pools.
  • Aggressive client timeouts causing resets.
  • Keep-alive disabled where it should be on.

Common causes of failed connection openings

  1. Listen backlog too small. Bursty traffic overflows the accept queue. Raise net.core.somaxconn and pass a larger backlog to listen().
  2. Ephemeral port exhaustion. A client opening huge numbers of active connections can run out of source ports. Check net.ipv4.ip_local_port_range and reduce churn with pooling.
  3. Firewall / security group dropping SYNs. Manifests as SYN retransmits and eventual AttemptFails with no RST.
  4. Upstream service down or overloaded. connect() gets refused or times out.
  5. SYN flood or scanning. A spike in half-open attempts; SYN cookies (net.ipv4.tcp_syncookies) help absorb it.

A quick diagnostic recipe

When connection performance is suspect, run this and read the deltas:

# 1. Baseline, wait through a representative window, then diff
nstat -n; sleep 30; nstat | grep -Ei 'ActiveOpens|PassiveOpens|AttemptFails|EstabResets|CurrEstab'

# 2. Look for queue drops that explain failures
nstat -az | grep -Ei 'ListenOverflows|ListenDrops|SynRetrans'

# 3. Confirm listening sockets and their backlog usage
ss -ltn        # Recv-Q vs Send-Q on listeners shows backlog pressure

# 4. Check the relevant tunables
sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog \
       net.ipv4.ip_local_port_range net.ipv4.tcp_syncookies

Interpretation:

  • Failures with ListenOverflows → backlog/accept problem on this server.
  • Failures with SynRetrans, no overflow → network/firewall or dead upstream.
  • High active opens, modest work done → add connection pooling.

Key tunables worth knowing

SysctlWhy it matters
net.core.somaxconnCaps the effective listen backlog
net.ipv4.tcp_max_syn_backlogSize of the SYN (half-open) queue
net.ipv4.ip_local_port_rangeHow many ephemeral ports clients can use
net.ipv4.tcp_syncookiesSurvives SYN floods without dropping legit clients
net.ipv4.tcp_tw_reuseReuses TIME_WAIT sockets for new active opens

Change these only with a measured reason—defaults are fine for many workloads, and blindly raising backlogs can mask an application that simply isn’t accepting fast enough.


Bottom line

The active/passive/failed open counters are a compact health check for TCP connection performance:

  • Active opens tell you the host is acting as a client.
  • Passive opens tell you it’s acting as a server.
  • Failed opens (AttemptFails) are the alarm—track their rate, not the raw total, and correlate with ListenOverflows and SYN retransmits to find the cause.

Read them with nstat over a fixed interval, graph the per-second rate in your monitoring stack, and you’ll spot backlog overflows, missing connection pools, and network black holes long before they turn into a user-visible outage.

Avatar photo
David Cao

David is a Cloud & DevOps Enthusiast. He has years of experience as a Linux engineer. He had working experience in AMD, EMC. He likes Linux, Python, bash, and more. He is a technical blogger and a Software Engineer. He enjoys sharing his learning and contributing to open-source.

Articles: 275

Leave a Reply

Your email address will not be published. Required fields are marked *