## TL;DR
worker_connections caps the connections each nginx worker handles; the right value is derived from expected concurrent connections divided by worker processes, with headroom. But worker_connections alone is not the story: worker_rlimit_nofile must allow the file descriptors, and worker_processes should match CPU cores. Tune all three together or the limit you raised is not the limit that binds.

## The query
```text
nginx worker_connections tuning for high traffic
```

## Use this when
- Nginx logs warn about too many open files or connection limits
- Preparing for known traffic spikes
- Capacity planning for the edge tier
- Connections get refused under load

## Not for when
- Upstream application performance
- TLS handshake optimization (related but separate)
- Choosing a load balancer

## Steps

### Step 1: Measure current connection patterns
Check active connections per worker during peak: the status module or logs give you the numbers. You need the peak concurrent connections, not the average; tuning for the average fails at the first spike.
Expected output: peak connections per worker, measured, not guessed.

### Step 2: Do the math
worker_connections should exceed peak connections per worker with headroom (2x is a sane start). worker_processes typically equals CPU cores. Total capacity is workers times connections; make sure that product covers peak plus growth.
Expected output: concrete numbers for worker_processes and worker_connections with the reasoning written down.

### Step 3: Raise the file descriptor limit to match
worker_rlimit_nofile must cover worker_connections times workers plus overhead, and the OS ulimit must allow it. This is the step everyone forgets: nginx configured for 10k connections but allowed 1024 file descriptors still caps at 1024.
Expected output: file descriptor limits at every layer above the connection target.

### Step 4: Tune keepalive to shape connection churn
Keepalive settings determine how long connections linger. For high traffic, keepalives reduce handshake overhead but hold connections; tune keepalive_timeout and upstream keepalive pools so idle connections do not eat the budget you just raised.
Expected output: connection reuse high, idle connection waste low.

### Step 5: Load test and watch the real limits
Test with realistic traffic and watch for the actual binding constraint: connection refused, file descriptor errors, or CPU saturation. The math gets you close; the load test tells you the truth.
Expected output: a tested configuration with measured headroom, not a theoretical one.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_vy_vIQZF6YLIUNHxnatyLA
