Backend Development 18 min read

Understanding Nginx Architecture, Process Model, and Module Design

The article explains Nginx’s high‑performance, event‑driven architecture, detailing its master‑worker process model, asynchronous non‑blocking I/O, CPU affinity, accept‑mutex load balancing, and the modular design built around ngx_module_t, covering core and HTTP modules, configuration parsing, data structures, and compilation guidelines for developers.

Baidu Geek Talk
Baidu Geek Talk
Baidu Geek Talk
Understanding Nginx Architecture, Process Model, and Module Design

Why learn Nginx? Nginx is the most popular web server, used by roughly one in three websites worldwide. Understanding its architecture and source code is essential for many backend development tasks.

Prerequisite knowledge includes C/C++ fundamentals, GDB debugging, basic Nginx usage (version 1.16), HTTP protocol, and network programming basics.

Learning guide outlines a roadmap covering Nginx source compilation, architecture, memory management, data structures (strings, arrays, linked lists, queues, hash tables, red‑black trees, trees), configuration parsing, process mechanisms (master and worker processes), HTTP module processing (11 phases), upstream mechanisms, various built‑in modules (time, event, load balancing, rate limiting, logging), cross‑platform compilation, and RTMP streaming module.

Basic architecture and design philosophy – Nginx is known for high performance, reliability, and extensibility, achieved through a modular design and event‑driven architecture.

Nginx Process Model

Nginx employs a master‑worker process model. The master process manages worker processes, handling signals and restarts. Workers handle client requests using asynchronous, non‑blocking I/O, often leveraging the epoll mechanism on Linux.

Key features:

Asynchronous non‑blocking – Workers never block on I/O; they process other requests while waiting for kernel operations.

CPU binding – Workers are typically bound to CPU cores via worker_cpu_affinity to reduce context switches and improve cache hits.

Load balancing – Nginx uses an accept_mutex lock to avoid the “thundering herd” problem and balances connections among workers.

Example code for calculating ngx_accept_disabled :

ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n

Worker accept logic snippet:

if (ngx_use_accept_mutex) {
    if (ngx_accept_disabled > 0) {
        ngx_accept_disabled--;
    } else {
        if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
            return;
        }
        // ...
    }
}

Modular Design

Nginx core provides a minimal set of core modules; most functionality is implemented in separate modules following a high‑cohesion, low‑coupling principle. All modules share a common interface defined by ngx_module_t :

struct ngx_module_s {
    ngx_uint_t            ctx_index;
    ngx_uint_t            index;
    char                 *name;
    ngx_uint_t            spare0;
    ngx_uint_t            spare1;
    ngx_uint_t            version;
    const char           *signature;
    void                 *ctx;
    ngx_command_t        *commands;
    ngx_uint_t            type;
    ngx_int_t           (*init_master)(ngx_log_t *log);
    ngx_int_t           (*init_module)(ngx_cycle_t *cycle);
    ngx_int_t           (*init_process)(ngx_cycle_t *cycle);
    ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);
    void                (*exit_thread)(ngx_cycle_t *cycle);
    void                (*exit_process)(ngx_cycle_t *cycle);
    void                (*exit_master)(ngx_cycle_t *cycle);
    uintptr_t             spare_hook0;
    uintptr_t             spare_hook1;
    uintptr_t             spare_hook2;
    uintptr_t             spare_hook3;
    uintptr_t             spare_hook4;
    uintptr_t             spare_hook5;
    uintptr_t             spare_hook6;
    uintptr_t             spare_hook7;
};

Core modules include ngx_core_module , ngx_http_module , ngx_events_module , ngx_mail_module , ngx_openssl_module , and ngx_errlog_module . HTTP modules are managed by ngx_http_module , which defines callbacks for configuration creation, merging, and request processing.

typedef struct {
    ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
    ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);
    void       *(*create_main_conf)(ngx_conf_t *cf);
    char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);
    void       *(*create_srv_conf)(ngx_conf_t *cf);
    char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
    void       *(*create_loc_conf)(ngx_conf_t *cf);
    char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;

The event‑driven framework consists of an event collector, dispatcher, and handler. Nginx supports multiple OS‑specific event models (epoll, poll, select, kqueue, eventport) and selects the most suitable one at runtime.

Overall, the article provides a comprehensive overview of Nginx’s internal design, making it valuable for backend developers and anyone interested in high‑performance web server architecture.

Backend DevelopmentnginxWeb Serverevent-drivenmodule architecture
Baidu Geek Talk
Written by

Baidu Geek Talk

Follow us to discover more Baidu tech insights.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.