NGINX Performance Tuning Prompt
Tune worker_processes, keepalive, buffers, sendfile, and connection limits to your actual hardware and traffic — producing a justified config diff, not cargo-culted values copied from a blog.
- Target user
- Engineers tuning NGINX throughput and latency under real load
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior performance engineer who tunes NGINX from evidence: CPU count, RAM, traffic profile, and observed bottlenecks. You never paste magic numbers; every value has a reason and a way to verify it. I will provide: - The hardware (CPU cores, RAM, NIC, container limits): [DESCRIBE HARDWARE] - The workload (static files, reverse proxy, TLS-heavy, large uploads, many small requests): [DESCRIBE WORKLOAD] - The symptom (high latency, CPU pegged, connection refused, slow uploads): [DESCRIBE SYMPTOM] - Current `nginx.conf` main/events/http context: [PASTE CONFIG] Tune it: 1. **Workers & connections** — `worker_processes auto` vs a pinned count, `worker_connections`, `worker_rlimit_nofile`, and how max clients = workers × connections relates to your traffic and file-descriptor limit. 2. **Keepalive** — `keepalive_timeout` and `keepalive_requests` for clients, and upstream `keepalive` for proxied connections (with `proxy_http_version 1.1` + `Connection ""`), explaining the latency win of connection reuse. 3. **File serving** — `sendfile`, `tcp_nopush`, `tcp_nodelay`, and when each helps (large static files vs small proxied responses). 4. **Buffers** — `client_body_buffer_size`, `client_max_body_size` (for uploads), `proxy_buffers`/`proxy_buffer_size`, and the disk-spill behavior when buffers overflow. 5. **Compression** — `gzip` (and `brotli` if the module exists) with sensible types and `gzip_comp_level`, noting the CPU/bandwidth tradeoff. 6. **OS-level note** — the somaxconn / `listen ... backlog` interaction and the file-descriptor ulimit, since NGINX config alone won't fix a kernel cap. Output: (a) the tuned `main`/`events`/`http` directives as a diff with a one-line reason per change, (b) the formula tying worker/connection values to my hardware, (c) what metric each change should move, (d) the verification: `nginx -t`, then a before/after load test. Apply changes incrementally and reload after `nginx -t`; do not hot-edit the live config.
Why this prompt works
NGINX tuning advice on the internet is mostly numbers without context — someone’s worker_connections 10240 for a beefy server gets pasted onto a 1-core container and does nothing. The prompt anchors every value to your stated hardware and workload and demands the formula (max clients = workers × connections, bounded by the FD limit), so the config fits your machine instead of someone else’s.
It also catches the silent ceiling that defeats most tuning attempts: cranking worker_connections without raising worker_rlimit_nofile and the OS ulimit just hits the file-descriptor cap. Surfacing the somaxconn/backlog and ulimit interaction means the answer addresses the whole stack, not just the part NGINX controls.
The one-reason-per-change diff and the before/after load test keep a human in control. You apply changes incrementally, watch the specific metric each is supposed to move, and gate every reload behind nginx -t, so you never bundle three tweaks and ship a regression you can’t attribute.