Solution 1: EPOLLEXCLUSIVE flag

If EPOLLEXCLUSIVE (Linux 4.5, glibc 2.24) is defined when compiling NGINX, NGINX could make use of it to reduce resource usage when volume of new connection is low.

NGINX discards EPOLLRDHUP if EPOLLEXCLUSIVE is enabled, keeping EPOLLIN and EPOLLOUT compatible with the CentOS 7 backport.

#if (NGX_HAVE_EPOLLEXCLUSIVE && NGX_HAVE_EPOLLRDHUP)
    if (flags & NGX_EXCLUSIVE_EVENT) {
        events &= ~EPOLLRDHUP;
    }
#endif

For every 16 requests handled, NGINX would re-add the socket in ngx_reorder_accept_events() to balance request across workers.

    if (c->requests++ % 16 != 0
        && ngx_accept_disabled <= 0)
    {
        return;
    }
 
    if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT)
        == NGX_ERROR)
    {
        return;
    }
 
    if (ngx_add_event(c->read, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT)
        == NGX_ERROR)
    {
        return;
    }

Solution 2: listen reuseport

SO_REUSEPORT could significantly increase the max latency in a degraded state. See https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/.

As a side effect, total length of pending connection queue (backlog) is multiplied by the number of workers because each worker has its own socket and therefore gets its own accept queue.

If you intend to set reuseport on listen, you should consider enabling the net.ipv4.tcp_migrate_req kernel parameter (Linux v5.14+ only) to reduce impact on in-flight request sockets during the handshake and established sockets in the accept queue during configuration reload.