Nginx Architecture and Worker Processes
When Nginx starts, a single master process is created first. The master process reads and validates nginx.conf, binds to the configured listening sockets, and then forks a configurable number of worker processes. The master itself never handles client connections directly; instead it manages privileged operations such as opening log files, binding to ports below 1024, and responding to control signals, while each worker independently accepts and processes actual client connections.
Cricket analogy: The master process is like captain Rohit Sharma, who sets the field and hands the ball to bowlers, while each worker process is a bowler executing deliveries independently without the captain touching every ball.
The Master Process and Signal Handling
The master process listens for Unix signals to manage the running server without downtime. Sending SIGHUP tells the master to re-read nginx.conf and gracefully spawn new workers with the new configuration while allowing old workers to finish processing their existing connections before exiting. This is why running 'nginx -s reload' does not drop active requests, and why it is safe to push configuration changes to a live production server.
Cricket analogy: Reloading config via SIGHUP is like a captain changing the batting order between overs without stopping the match, so existing deliveries finish under the old order while new play continues under the new one.
Worker Processes and the Event Loop
Each Nginx worker is single-threaded and uses an OS-level notification mechanism, epoll on Linux or kqueue on BSD, to monitor thousands of file descriptors at once without polling each one individually. The worker only does work when the operating system tells it a socket is readable or writable, allowing one worker to juggle the worker_connections limit's worth of simultaneous clients efficiently.
Cricket analogy: A single worker using epoll to watch thousands of connections is like one sharp umpire, Simon Taufel, simultaneously watching for no-balls, run-outs, and boundaries across the field instead of needing a separate umpire per event type.
# nginx.conf (main context)
worker_processes auto; # one worker per CPU core
worker_rlimit_nofile 65535;
events {
worker_connections 4096; # max simultaneous connections per worker
use epoll; # Linux event notification mechanism
multi_accept on;
}
http {
aio threads; # offload blocking disk reads to a thread pool
sendfile on;
}Worker Processes vs Worker Threads
The worker_processes directive is typically set to 'auto' so Nginx spawns one worker per CPU core, matching parallelism to actual hardware. Because each worker is single-threaded for network I/O, a genuinely blocking operation like a slow disk read could stall an entire worker; Nginx addresses this with an optional thread pool, configured via 'aio threads', that offloads blocking file I/O so the worker's event loop keeps servicing other connections while the read completes in the background.
Cricket analogy: Setting worker_processes to match CPU cores is like fielding exactly eleven players to match the pitch's demands; adding a twelfth does nothing since the rules cap it, just as extra workers beyond core count add overhead without benefit.
Raising worker_connections without also raising the operating system's file descriptor limit (ulimit -n) and worker_rlimit_nofile has no effect: workers will still be capped by the OS limit and will silently refuse new connections once it is hit, so always adjust both together.
- The master process reads config, binds sockets, and forks workers; it does not handle client traffic itself.
- Sending SIGHUP (nginx -s reload) reloads configuration gracefully without dropping existing connections.
- Each worker is single-threaded and uses epoll (Linux) or kqueue (BSD) to multiplex thousands of connections.
- worker_processes is typically set to 'auto' to match the number of CPU cores.
- worker_connections sets the per-worker limit on simultaneous connections.
- The optional thread pool (aio threads) offloads blocking disk I/O so it doesn't stall a worker's event loop.
- worker_connections must be raised alongside OS file descriptor limits, or the extra headroom is meaningless.
Practice what you learned
1. What is the primary responsibility of the Nginx master process?
2. What happens when you send SIGHUP to the Nginx master process (e.g. via nginx -s reload)?
3. Which OS mechanism do Nginx workers typically use on Linux to monitor many connections efficiently?
4. What is the recommended setting for worker_processes in most production deployments?
5. Why does Nginx offer an optional thread pool via 'aio threads'?
Was this page helpful?
You May Also Like
What Is Nginx?
An introduction to Nginx as a high-performance web server, reverse proxy, and load balancer, and why it dominates modern web infrastructure.
Installing and Running Nginx
How to install Nginx via package managers or Docker, and how to manage the running service safely.
The Nginx Configuration File Structure
How Nginx's nested context hierarchy, directive inheritance, and include files organize a production configuration.
Related Reading
Related Study Notes in DevOps
Browse all study notesAnsible Study Notes
DevOps · 30 topics
DevOpsAdvanced Kubernetes Study Notes
Kubernetes · 30 topics
DevOpsAdvanced Bash Scripting Study Notes
Bash · 30 topics
DevOpsApache Kafka Study Notes
Kafka · 30 topics
DevOpsDocker & Kubernetes Study Notes
YAML · 40 topics
DevOpsCI/CD Tools & Pipelines Study Notes
YAML · 37 topics