How to Enable reuseport in Nginx

The reuseport option in Nginx enables the SO_REUSEPORT socket option, which allows multiple worker processes to each maintain their own listening socket for the same port. By the end of this guide, you will have reuseport configured in your Nginx server blocks, verified with syntax tests, and understand when this optimization provides the greatest benefit.

Without reuseport, a single listening socket accepts all incoming connections and distributes them to workers. This design can create contention under heavy load. With reuseport enabled, the kernel distributes connections across multiple sockets at the network level, which reduces lock contention and improves throughput. High-traffic servers handling thousands of concurrent connections see the greatest improvement, particularly when running multiple Nginx worker processes.

What is SO_REUSEPORT?

SO_REUSEPORT is a Linux kernel socket option that allows multiple sockets to bind to the same IP address and port combination. When enabled, the kernel load-balances incoming connections across all sockets bound to that address, which distributes the accept workload across multiple processes.

In Nginx, each worker process typically competes for connections from a single shared socket. This design creates a bottleneck because only one worker can call accept() at a time on that socket. When you enable reuseport, each worker process opens its own socket, and the kernel handles distribution directly. As a result, workers spend less time waiting for connection handoff and more time processing requests.

For additional Nginx performance optimizations, see our guides on enabling TCP Fast Open, configuring open file cache, and enabling gzip compression.

Prerequisites

Before configuring reuseport, verify that your system meets these requirements:

  • Nginx 1.9.1 or later: The reuseport parameter was introduced in version 1.9.1. Earlier versions do not support this option.
  • Linux kernel 3.9 or later: The SO_REUSEPORT socket option requires kernel 3.9+. FreeBSD 12.0+ uses the equivalent SO_REUSEPORT_LB option.
  • Multiple worker processes: The benefit of reuseport comes from distributing load across workers. If you run only one worker process, reuseport provides no advantage.

To confirm your Nginx version, run:

nginx -v

Example output:

nginx version: nginx/1.x.x

Then verify your kernel version supports SO_REUSEPORT:

uname -r

Any kernel version 3.9 or higher supports reuseport. Modern distributions ship with kernel 5.x or 6.x, so virtually all current Linux systems meet this requirement.

Enable reuseport in the listen Directive

Add the reuseport option to the listen directive within a server block. Before making changes, create a backup of your configuration:

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup

The basic syntax for enabling reuseport is:

listen 80 reuseport;

This directive tells Nginx to listen on port 80 with the SO_REUSEPORT socket option enabled. Each worker process creates its own socket for this address and port, which allows the kernel to balance incoming connections across all workers.

Critical Rule: One reuseport Per Address and Port

The reuseport option can only appear once per unique address:port combination across your entire Nginx configuration. If you specify reuseport on multiple server blocks that share the same listen address and port, Nginx will fail with a “duplicate listen options” error.

For example, this configuration is invalid and will cause an error:

# INVALID: reuseport appears twice for the same port
server {
    listen 80 reuseport;        # First instance - OK
    server_name domain1.com;
    root /var/www/domain1;
}

server {
    listen 80 reuseport;        # ERROR: duplicate listen options
    server_name domain2.com;
    root /var/www/domain2;
}

Testing this configuration produces:

nginx: [emerg] duplicate listen options for 0.0.0.0:80

Configure reuseport for HTTP and HTTPS

For servers handling both HTTP and HTTPS traffic, add reuseport to each unique address:port combination, but only once per combination. The following example shows the correct configuration for dual-stack (IPv4 and IPv6) with both protocols:

# HTTP server block
server {
    listen 80 reuseport;              # IPv4 port 80
    listen [::]:80 reuseport;         # IPv6 port 80
    server_name example.com www.example.com;
    
    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

# HTTPS server block
server {
    listen 443 ssl reuseport;         # IPv4 port 443
    listen [::]:443 ssl reuseport;    # IPv6 port 443
    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;
}

In this configuration, reuseport appears four times, but each instance is for a unique address:port pair: IPv4 port 80, IPv6 port 80, IPv4 port 443, and IPv6 port 443. This is valid because no address:port combination is duplicated.

Configure reuseport for Multiple Domains

When hosting multiple domains on the same server and port, only the first server block for each address:port should include reuseport. Additional server blocks sharing that port must omit the option:

# First domain: includes reuseport
server {
    listen 80 reuseport;
    listen [::]:80 reuseport;
    server_name domain1.com www.domain1.com;
    root /var/www/domain1;
    index index.html;
}

# Second domain: shares the port, no reuseport
server {
    listen 80;
    listen [::]:80;
    server_name domain2.com www.domain2.com;
    root /var/www/domain2;
    index index.html;
}

# Third domain: shares the port, no reuseport
server {
    listen 80;
    listen [::]:80;
    server_name domain3.com www.domain3.com;
    root /var/www/domain3;
    index index.html;
}

All three domains benefit from reuseport because the option applies at the socket level, not the server block level. Once enabled on the first server block for an address:port, all subsequent server blocks sharing that combination inherit the kernel-level socket distribution.

Combine reuseport with default_server

For servers that need a catch-all block to handle requests that do not match any specific server_name, combine reuseport with default_server:

server {
    listen 80 default_server reuseport;
    listen [::]:80 default_server reuseport;
    server_name _;
    
    # Return 444 to close connection for unknown hosts
    return 444;
}

This configuration sets the server as both the default handler for unmatched requests and enables reuseport for port 80. Any other server blocks on port 80 should omit both default_server and reuseport.

Test and Apply the Configuration

After editing your configuration, always test the syntax before applying changes. This prevents service interruption from configuration errors:

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 to apply the changes without dropping existing connections:

sudo systemctl reload nginx

Alternatively, if you are not using systemd:

sudo nginx -s reload

Verify reuseport is Active

After reloading, verify that Nginx is listening with multiple sockets per port by checking the number of listening sockets:

ss -tlnp | grep nginx

With reuseport enabled and four worker processes, you should see multiple entries for the same port:

LISTEN    0    511    0.0.0.0:80    0.0.0.0:*    users:(("nginx",pid=1234,fd=6))
LISTEN    0    511    0.0.0.0:80    0.0.0.0:*    users:(("nginx",pid=1235,fd=6))
LISTEN    0    511    0.0.0.0:80    0.0.0.0:*    users:(("nginx",pid=1236,fd=6))
LISTEN    0    511    0.0.0.0:80    0.0.0.0:*    users:(("nginx",pid=1237,fd=6))

Without reuseport, you would see only one listening socket per port, shared by all workers. The multiple entries confirm that each worker has its own socket, which is the expected behavior when reuseport is active.

When to Use reuseport

The reuseport option provides the most benefit in specific scenarios. Consider enabling it when:

  • High connection rates: Servers handling thousands of new connections per second benefit from reduced accept lock contention.
  • Multiple worker processes: The optimization only helps when you have more than one worker. Check your worker_processes setting in nginx.conf.
  • Multi-core systems: Servers with many CPU cores running one worker per core see improved distribution of incoming connections.
  • Short-lived connections: Workloads with many brief requests (API endpoints, static assets) benefit more than workloads with long-held connections.

Conversely, reuseport may provide negligible benefit for:

  • Low-traffic servers: Sites with modest traffic (hundreds of requests per minute) are unlikely to hit accept contention.
  • Single-worker configurations: With only one worker, there is no socket contention to reduce.
  • Long-lived WebSocket connections: Persistent connections spend most time processing, not accepting.

Troubleshooting

Duplicate listen options Error

If Nginx fails to start with this error:

nginx: [emerg] duplicate listen options for 0.0.0.0:80

You have specified reuseport on multiple server blocks for the same address and port. Search your configuration files for duplicate instances:

grep -r "reuseport" /etc/nginx/

Remove reuseport from all but one server block per address:port combination, then test and reload.

Unknown Directive reuseport Error

If Nginx reports:

nginx: [emerg] invalid parameter "reuseport"

Your Nginx version is older than 1.9.1 and does not support reuseport. Upgrade to a newer Nginx version, or remove the reuseport parameter from your configuration.

Only One Socket Per Port After Reload

If ss -tlnp | grep nginx shows only one listening socket per port despite enabling reuseport, check:

  1. Worker process count: Verify worker_processes is greater than 1 in /etc/nginx/nginx.conf.
  2. Reload vs restart: A full restart may be required for reuseport changes to take effect in some cases:
sudo systemctl restart nginx

Conclusion

Your Nginx server now uses per-worker listening sockets that reduce connection accept contention under high load. Remember that reuseport can only appear once per address:port pair across all server blocks. For high-traffic sites with multiple worker processes, this optimization reduces latency and improves connection throughput with minimal configuration effort. Consider combining reuseport with TCP Fast Open and sendfile for additional performance gains.

Further Reading

Leave a Comment

Let us know you are human: