BeCuriouzBeCuriouz

Learn something new every day

🛠️ Tools & Services
🕸️

How nginx serves 10,000 connections without 10,000 threads

💡 nginx scales by handling thousands of connections per worker through an event loop, instead of dedicating a costly thread to each one.

When you load a busy website, there's a good chance nginx ("engine-x") is quietly answering. Created by Igor Sysoev in 2004, it's a web server and reverse proxy — a traffic cop that sits in front of your application, serving static files, balancing load across backend servers, and caching responses. But the reason it took over the internet is a design choice buried in its architecture.

The web server it dethroned, Apache, used a thread-per-connection model: every visitor got their own operating-system thread or process. That's simple, but each thread eats memory and CPU for context switching. Pile on ten thousand simultaneous users and the server collapses under its own bookkeeping — the infamous C10k problem.

nginx flipped the model. A small pool of worker processes (typically one per CPU core) each run an event loop: instead of blocking while waiting for a slow client, a worker registers interest in thousands of connections via the OS kernel (epoll on Linux, kqueue on BSD) and only wakes up when one has data ready. One worker juggles thousands of connections by never sitting idle. The payoff is dramatic: nginx holds roughly 10,000 idle keep-alive connections in about 2.5 MB of memory.

The tradeoff is discipline — a single blocking operation in a worker would freeze every connection it's handling, so nginx is engineered to keep almost everything non-blocking and asynchronous.

📚

Source: nginx

🕸️ How nginx serves 10,000 connections without 10,000 threads — BeCuriouz