Why Is Nginx So Fast? A Deep Dive into Its Process and Event Model
This article explains Nginx's high performance by examining its multi‑process architecture, asynchronous event‑driven design, modular components, and I/O multiplexing mechanisms such as epoll, while also comparing it with Apache and detailing connection limits and request handling flow.
Nginx Overview
Nginx is renowned for high performance, stability, rich features, simple configuration, and low resource consumption. The article analyzes the underlying reasons for its speed.
Process Model
Nginx runs a single Master process that manages multiple Worker processes. The Master loads configuration, receives external signals, forwards commands to Workers, and monitors their health, automatically restarting any that crash. Workers are equal peers that handle network requests. The number of Workers is set in nginx.conf, typically matching the number of CPU cores to maximize CPU utilization while avoiding excessive context switches.
HTTP Connection Establishment and Request Handling
When Nginx starts, the Master loads the configuration file.
The Master initializes listening sockets.
The Master forks the configured number of Worker processes.
Workers compete for new connections; the winner completes the TCP three‑way handshake, establishes a socket, and processes the request.
Why Nginx Achieves High Performance and Concurrency
It uses a multi‑process + asynchronous non‑blocking model based on I/O multiplexing (epoll on Linux).
The request lifecycle is: establish connection → read request → parse request → process request → send response.
At the low level, this translates to read/write events on sockets.
Event Handling Model
The core HTTP handling consists of three phases:
Receive request: read request line, headers, and body (if present).
Process request: invoke appropriate handler modules.
Return response: generate status line, headers, and body.
Modular Architecture
Modules are grouped by functionality:
Event module: provides the OS‑independent event framework (e.g., ngx_events_module , ngx_event_core_module , ngx_epoll_module ).
Phase handler: processes client requests and generates content (e.g., ngx_http_static_module for static files).
Output filter: modifies the response before it is sent (e.g., adding footers or rewriting URLs).
Upstream: implements reverse‑proxy functionality, fetching content from backend servers.
Load‑balancer: selects a backend server according to a balancing algorithm.
Nginx vs Apache
Nginx: I/O multiplexing (epoll/kqueue), high performance, high concurrency, low resource usage.
Apache: blocking I/O with multi‑process/thread model, more stable modules, richer ecosystem.
Maximum Connections
Each Worker can handle up to worker_connections sockets, limited by the OS file‑descriptor limit ( ulimit -n). The overall maximum connections are: worker_processes × worker_connections for a generic server.
For a reverse‑proxy, the effective maximum is roughly half that number because each client connection also opens a backend connection.
HTTP Request and Response Structure
Request
Request line: method, URI, HTTP version.
Headers.
Optional body.
Response
Status line: HTTP version, status code.
Headers.
Body.
I/O Models
Two main approaches for handling many connections:
I/O multiplexing: a single thread monitors many sockets and performs read/write on the ready ones.
Blocking I/O + multithreading: each request gets its own thread, which is simpler but incurs higher context‑switch and memory overhead.
Select, Poll, and Epoll Comparison
// select system call
int select(int maxfdp, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
// poll system call
int poll(struct pollfd fds[], nfds_t nfds, int timeout);Select: scans an fd_set (max 1024 by default), limited by the size of the set and linear scanning overhead.
Poll: replaces the fixed‑size set with a dynamic array of pollfd, removing the descriptor count limit but still copying state between user and kernel space.
Epoll: registers interest events per descriptor, avoids linear scans, and supports a virtually unlimited number of descriptors limited only by OS resources.
Concurrency Capacity
After tuning, Nginx can sustain 10 000–30 000 concurrent connections on typical hardware, with the exact number depending on CPU cores and memory.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
