Busy Nginx servers can spend surprising time coordinating which worker accepts the next connection. The reuseport parameter on the Nginx listen directive uses the operating system’s SO_REUSEPORT support so each worker can keep its own listening socket for the same address and port.
Enable Nginx reuseport when you run multiple workers and want better accept-side distribution under high connection rates. The practical path is to set the HTTP, HTTPS, stream, or QUIC listener once, validate the syntax, avoid duplicate listen options, and confirm that the expected listener sockets exist after reload.
Understand Nginx reuseport and SO_REUSEPORT
SO_REUSEPORT allows multiple sockets to bind to the same local address and port when the operating system supports it. Nginx exposes that behavior through the reuseport parameter on listen, not through a separate top-level directive.
nginx-reuseport is not a separate package or standalone directive. In Nginx configuration, the feature is the reuseport parameter on listen.
Use these details before editing a live site:
| Item | Context | Default or version | Practical note |
|---|---|---|---|
HTTP listen ... reuseport | HTTP server block | No default; parameter added in Nginx 1.9.1 | Creates separate listening sockets for worker processes on the same address:port pair. |
Stream listen ... reuseport | Stream server block | No default; reuseport 1.9.1, udp 1.9.13; stream module required | Applies to TCP and UDP stream services. For UDP, Nginx documents udp reuseport together for session handling. |
HTTP/3 listen ... quic reuseport | HTTP server block | Requires an Nginx build with HTTP/3 support | Creates UDP QUIC listeners. Keep the normal TCP TLS listener for HTTP/1.1 and HTTP/2 clients. |
accept_mutex | events block | Default is off; older Nginx releases defaulted to on before 1.11.3 | Nginx documentation says accept_mutex is not needed when using reuseport. |
SO_REUSEPORT | Operating system socket option | Linux 3.9 and later; Nginx also documents compatible BSD support | The operating system owns the socket behavior. nginx -t only proves Nginx syntax. |
If you also tune backlog, keep it on the same single listen line that owns the address:port options. backlog controls the pending connection queue, while reuseport controls whether workers get separate listening sockets. Nginx documents a backlog default of 511 on Linux and most non-BSD platforms.
Configure Nginx stream listen reuseport
The stream module has its own listen directive under a stream server block. Do not copy stream-only parameters such as udp into HTTP virtual hosts.
stream {
upstream dns_backend {
server 192.0.2.53:53;
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_pass dns_backend;
}
}
The stream listen syntax can place reuseport, backlog, and so_keepalive on the same line, but they are independent listener options, not a required bundle. Use udp reuseport for UDP stream session handling; use backlog and so_keepalive on TCP stream listeners only when those socket-level settings match your workload.
stream {
upstream app_backend {
server 127.0.0.1:12345;
}
server {
listen 127.0.0.1:9000 reuseport backlog=1024 so_keepalive=30m::10;
proxy_pass app_backend;
}
}
For nearby Nginx performance topics, compare this setting with enabling TCP Fast Open, configuring open file cache, enabling gzip compression, and enabling the Nginx sendfile directive. Those features solve different bottlenecks, so measure them separately instead of treating them as substitutes.
Check Nginx reuseport Requirements
Before configuring reuseport, verify these requirements:
- Nginx 1.9.1 or later: The HTTP
listenparameter was added in Nginx 1.9.1. - Operating system support: Linux needs kernel 3.9 or later. Nginx documentation also lists compatible DragonFly BSD support and FreeBSD 12.0 or later through
SO_REUSEPORT_LB. - Multiple worker processes: The setting has little value with one worker because there is only one process accepting connections.
- Raw Nginx config access: Hosted panels, CDN edge rules, or Nginx Proxy Manager style tools need the equivalent listener setting in their own UI or generated config.
If a control plane generates Nginx configuration, change the control plane setting instead of editing generated files. For example, the Kubernetes ingress-nginx reuse-port ConfigMap option controls this behavior for ingress-nginx, and its documented default is true.
Check the Nginx version first:
nginx -v
Example output:
nginx version: nginx/1.x.x
On Linux, confirm the kernel branch as well:
uname -r
Example output:
6.x.x-generic
Any Linux kernel version 3.9 or newer supports the socket option. Most current Linux server releases already meet that requirement, but older appliances and frozen vendor images are still worth checking.
Enable Nginx reuseport in the listen Directive
Add reuseport to the listen directive inside the relevant server block. On typical Linux package installs, create a backup before editing /etc/nginx/nginx.conf or the included virtual-host file that owns the listener.
sudo cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
The basic HTTP syntax is:
listen 80 reuseport;
This line belongs in an HTTP server block. Do not place it in the http, events, or location context.
Use one Nginx reuseport listener per address and port
Set
reuseportonly once for each unique address:port combination. Multiple server blocks can share that listener, but only onelistenline for the same address and port should carry the socket options.
This configuration is invalid because both server blocks set reuseport on the same IPv4 port:
# Invalid: reuseport appears twice for the same address:port
server {
listen 80 reuseport;
server_name domain1.com;
root /var/www/domain1;
}
server {
listen 80 reuseport;
server_name domain2.com;
root /var/www/domain2;
}
Nginx reports an error like this when the duplicate option is present:
nginx: [emerg] duplicate listen options for 0.0.0.0:80
The duplicated address may be IPv4, IPv6, HTTP, or HTTPS, so the same problem can also appear as [::]:443 or another listener in the error text.
Configure Nginx reuseport for HTTP and HTTPS
For a site that already has valid TLS certificate files, add reuseport once to each unique HTTP and HTTPS address:port listener. Keep the HTTP-only configuration first if certificates have not been issued yet.
# HTTP listener
server {
listen 80 reuseport;
listen [::]:80 reuseport;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS listener
server {
listen 443 ssl reuseport;
listen [::]:443 ssl reuseport;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/example.com;
index index.html;
}
This example uses four unique listener addresses: IPv4 port 80, IPv6 port 80, IPv4 port 443, and IPv6 port 443. That is valid because no address:port pair repeats the reuseport option.
Use Nginx reuseport with HTTP/3 and QUIC
HTTP/3 uses QUIC over UDP, so it needs a separate quic listener in addition to the normal TCP TLS listener. Add this only when your Nginx build includes HTTP/3 support and your firewall or load balancer allows UDP on the HTTPS port.
nginx -V 2>&1 | grep -o -- '--with-http_v3_module'
Relevant output for a build with the HTTP/3 module includes:
--with-http_v3_module
server {
listen 443 ssl reuseport;
listen [::]:443 ssl reuseport;
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/example.com;
index index.html;
}
The TCP listeners handle normal HTTPS clients, while the QUIC listeners handle UDP traffic for HTTP/3. Verify TCP and UDP sockets separately because a working TCP 443 listener does not prove that UDP 443 is active or reachable through the network path.
Configure Nginx reuseport for Multiple Domains
When multiple domains share the same IP address and port, choose one server block to own the socket options for that address:port pair. The default server block is usually the clearest place to keep them.
# First domain owns the listener options for port 80
server {
listen 80 reuseport;
listen [::]:80 reuseport;
server_name domain1.com www.domain1.com;
root /var/www/domain1;
index index.html;
}
# Additional domains share the same listeners
server {
listen 80;
listen [::]:80;
server_name domain2.com www.domain2.com;
root /var/www/domain2;
index index.html;
}
server {
listen 80;
listen [::]:80;
server_name domain3.com www.domain3.com;
root /var/www/domain3;
index index.html;
}
All three virtual hosts still use the same listener set for their shared address and port. The later server blocks omit reuseport because the socket options already belong to that listener.
Combine Nginx reuseport with default_server
If you use a catch-all server for unmatched hostnames, keep default_server and reuseport together on the listener that should own both behaviors.
server {
listen 80 default_server reuseport;
listen [::]:80 default_server reuseport;
server_name _;
return 444;
}
Other server blocks on the same address and port should omit both default_server and reuseport unless they intentionally bind a different address or port.
Test and Apply Nginx reuseport Changes
After editing the configuration, run the Nginx syntax test before reloading the service:
sudo nginx -t
Expected output for a valid configuration:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
If the test passes, reload Nginx so existing connections can drain while new workers pick up the listener changes:
sudo systemctl reload nginx
On non-systemd systems, use Nginx’s reload signal instead:
sudo nginx -s reload
Verify Nginx reuseport is Active
On Linux, count the active listener sockets for the port you changed. With one IPv4 port 80 listener and four worker processes, the count should be four.
sudo ss -H -ltn 'sport = :80' | wc -l
Expected output for that four-worker example:
4
Dual-stack listeners or HTTPS listeners add more sockets, so compare the count to the address families and ports you configured. If the count remains one on a multi-worker Linux host, the change may not have loaded, the edited file may not be included, or the service may need a full restart.
For UDP stream listeners or HTTP/3 QUIC listeners, use the UDP listener view instead:
sudo ss -H -lun 'sport = :443' | wc -l
Expected output depends on your worker count and address families. A two-worker, IPv4-only QUIC listener should show:
2
When to Use Nginx reuseport
reuseport is most useful when connection acceptance is a real bottleneck. It is not a general speed switch for every site.
- Good fit: High connection rates, many short-lived requests, multiple Nginx workers, and multi-core systems where accept-side contention shows up during load testing.
- Weak fit: Low-traffic sites, one-worker configurations, and workloads dominated by long-lived WebSocket or streaming connections after the initial accept phase.
- Operational caution: Test during a maintenance window or on a staging host first. Listener option mistakes can prevent Nginx from reloading.
For most production sites, the right decision is to test reuseport, compare connection handling under real traffic or a controlled load test, and keep the setting only when it improves the workload you actually run.
Troubleshoot Nginx reuseport Errors
Duplicate listen options error
Nginx reports this error when more than one listen directive sets socket options for the same address and port:
nginx: [emerg] duplicate listen options for 0.0.0.0:80
Search the included configuration tree for every reuseport entry. The recursive grep command guide covers more filtering options if the output is noisy.
sudo grep -R "reuseport" /etc/nginx/
Leave reuseport on only one listen line per address:port pair, then verify the fix:
sudo nginx -t
Invalid parameter reuseport error
An older Nginx build usually reports this error when it does not understand the reuseport parameter:
nginx: [emerg] invalid parameter "reuseport"
Check the running Nginx version. If it is older than 1.9.1, upgrade Nginx or remove reuseport from the configuration.
nginx -v
Only one socket per port after reload
If the listener count stays at one after reload, confirm that Nginx has more than one worker process configured:
sudo grep "worker_processes" /etc/nginx/nginx.conf
Relevant output should show auto or a number greater than 1:
worker_processes auto;
A single-worker configuration cannot create multiple per-worker listener sockets. If the worker count is already greater than one and the syntax test passes, restart Nginx during a safe window so the old listener state is fully replaced.
sudo nginx -t
sudo systemctl restart nginx
QUIC or UDP reuseport listener missing
If TCP verification succeeds but HTTP/3 or UDP stream traffic still fails, check the UDP listener separately. TCP socket checks do not show QUIC or stream UDP sockets.
sudo ss -H -lun 'sport = :443' | wc -l
If the count is zero, confirm that the configuration contains the correct UDP listener, the Nginx build supports any required module, and the firewall or load balancer exposes UDP as well as TCP.
sudo nginx -t
nginx -V 2>&1 | grep -o -- '--with-http_v3_module'
Conclusion
Nginx reuseport is configured when each changed listener passes nginx -t, reloads cleanly, and shows the expected per-worker socket count. Keep the option on one listen line per address:port pair, measure it under real traffic, and pair it with related Nginx tuning only when each change solves a separate bottleneck.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>