The origin of the C10K problem
In the late 1990s, as web traffic grew, an architectural problem known as C10K emerged: how to handle ten thousand concurrent connections on a single server. Traditional web servers like Apache HTTP Server use a process-per-connection or thread-per-connection model: each client connection requires a dedicated process or thread. As connections grow, memory consumption and the cost of context switching become the bottleneck.
Nginx (pronounced “engine-x”) was created in 2004 by Igor Sysoev, a Russian system administrator managing Rambler, one of Russia’s most heavily trafficked websites. The motivation was practical: serving a volume of traffic that Apache’s prefork model could not handle efficiently.
Event-driven architecture
Nginx adopts a radically different architecture. A master process manages configuration and coordinates a small number of worker processes — typically one per CPU core. Each worker uses an asynchronous event loop based on system calls such as epoll (Linux) or kqueue (FreeBSD) to handle thousands of connections within a single thread.
The model is non-blocking: when a worker initiates an I/O operation — reading a file from disk, sending data to a client, waiting for a response from a backend — it does not stop and wait. It registers the event and immediately moves on to serve another connection. When the I/O operation completes, the operating system notifies the worker through the event loop.
The result is predictable and contained memory usage: an Nginx worker process occupies just a few megabytes of RAM regardless of the number of active connections. Where Apache with prefork might require hundreds of megabytes to handle thousands of connections, Nginx uses a fraction of that.
Reverse proxy and load balancing
Beyond serving static content with exceptional efficiency, Nginx is designed to function as a reverse proxy: it receives requests from clients and forwards them to backend servers — FastCGI applications, upstream HTTP servers, memcached processes. This architecture allows the separation of static content serving from application logic.
Load balancing features distribute requests across multiple backend servers using configurable algorithms: round-robin, least connections, IP hash for session persistence. Nginx also handles buffering of responses from backends, freeing application processes as soon as the response is generated.
An architectural alternative
Nginx does not seek to replace Apache in all its use cases. It does not support .htaccess files for distributed configuration and has no direct equivalent of Apache’s modular system. Its strength lies in a specific scenario: high-traffic sites where efficient management of concurrent connections and fast static content serving are priorities. In this scenario, the event-driven architecture offers measurable advantages in terms of performance, resource consumption and scalability.
Link: nginx.org
