Open-Source Wikis

/

nginx

/

NGINX

/

Architecture

nginx/nginx

Architecture

NGINX is a single C program built around three ideas: a module-based design where every feature is an ngx_module_t; a non-blocking, event-driven I/O loop where one OS thread per worker handles thousands of connections; and a master/worker process model that gives each worker its own pre-allocated pool of connections and shares state through mmap'd memory zones.

Process model

graph TD
    M[master process<br/>nginx -g] -->|fork + exec| W1[worker 0]
    M -->|fork + exec| W2[worker 1]
    M -->|fork + exec| WN[worker N]
    M -->|fork| CM[cache manager]
    M -->|fork| CL[cache loader]
    M -->|signals: SIGHUP/USR1/USR2/WINCH| M
    M -->|socketpair / channel| W1
    M -->|socketpair / channel| W2
    M -->|socketpair / channel| WN
    W1 -->|accept| Clients
    W2 -->|accept| Clients
    WN -->|accept| Clients

The master never serves traffic. Its job is to bind listening sockets, parse configuration, fork workers, watch for signals (SIGHUP to reconfigure, SIGUSR1 to reopen logs, SIGUSR2 for binary upgrade), and respawn dead workers. Workers inherit the listening sockets via fork() and run independent event loops.

The implementation lives in src/os/unix/ngx_process_cycle.c (and the Windows port in src/os/win32/ngx_process_cycle.c). See systems/process-model for the full state machine, signal flags (ngx_quit, ngx_terminate, ngx_reconfigure, ngx_reopen, ngx_change_binary), and the binary-upgrade dance that lets a running nginx replace its own executable without dropping connections.

Module model

Everything that nginx does — read a config directive, accept a connection, parse an HTTP request, call OpenSSL, gzip a response, talk to a FastCGI backend — is implemented as a module. A module is a static ngx_module_t struct (src/core/ngx_module.h) with hooks for init_module, init_process, exit_process, plus a commands table that maps directive names to setter functions, plus a typed ctx pointer that adds module-type-specific hooks (ngx_http_module_t, ngx_event_module_t, ngx_mail_module_t, ngx_stream_module_t).

Module types:

Type Examples Where the type's ctx lives
NGX_CORE_MODULE ngx_core_module, ngx_http_module, ngx_events_module src/core/ngx_module.h
NGX_EVENT_MODULE ngx_epoll_module, ngx_kqueue_module, ngx_poll_module src/event/ngx_event.h
NGX_HTTP_MODULE ngx_http_core_module, ngx_http_proxy_module, ngx_http_ssl_* src/http/ngx_http_config.h
NGX_MAIL_MODULE ngx_mail_smtp_module, ngx_mail_proxy_module src/mail/ngx_mail.h
NGX_STREAM_MODULE ngx_stream_proxy_module, ngx_stream_ssl_module src/stream/ngx_stream.h
NGX_CONF_MODULE ngx_conf_module (the include directive) src/core/ngx_conf_file.h

The list of modules baked into a given binary is generated by auto/modules at configure time and emitted as objs/ngx_modules.c. Dynamic modules (loaded via load_module at runtime) use the same struct but ship as .so files. See systems/configuration for how modules register directives and how ngx_init_cycle() walks them on startup and reload.

Event loop

Each worker runs a single thread that loops on ngx_process_events_and_timers() (src/event/ngx_event.c). The actual I/O readiness mechanism is pluggable — there is one event module per OS facility:

Module OS File
ngx_epoll_module Linux src/event/modules/ngx_epoll_module.c
ngx_kqueue_module FreeBSD, macOS src/event/modules/ngx_kqueue_module.c
ngx_eventport_module Solaris src/event/modules/ngx_eventport_module.c
ngx_devpoll_module Solaris (legacy) src/event/modules/ngx_devpoll_module.c
ngx_poll_module / ngx_select_* portable fallback src/event/modules/ngx_poll_module.c etc.
ngx_iocp_module Windows src/event/modules/ngx_iocp_module.c

Each connection (ngx_connection_t, src/core/ngx_connection.h) carries a read event, a write event, and a memory pool whose lifetime matches the connection. Timers ride on a per-worker red-black tree (src/event/ngx_event_timer.c); posted-event lists let modules defer work without re-entering the event loop. See systems/event-loop for the full picture.

HTTP request lifecycle

graph LR
    A[accept] --> P[ngx_http_init_connection]
    P --> H[read + parse request line + headers]
    H --> R[ngx_http_process_request]
    R --> Ph[11 phases:<br/>POST_READ → SERVER_REWRITE →<br/>FIND_CONFIG → REWRITE → POST_REWRITE →<br/>PREACCESS → ACCESS → POST_ACCESS →<br/>PRECONTENT → CONTENT → LOG]
    Ph --> Hndl[content handler<br/>static / proxy / fastcgi / ...]
    Hndl --> F[output filter chain<br/>ssi → range → gzip → chunked → header → write]
    F --> N[ngx_http_finalize_request]

The 11-phase request engine lives in src/http/ngx_http_core_module.c and src/http/ngx_http_request.c. Modules attach handlers to phases at config-time. Subrequests, internal redirects, try_files, and error_page all unwind through the same phase machinery. See systems/http/request-lifecycle.

Memory model

NGINX almost never calls malloc() in the hot path. Instead:

  • Pools (ngx_pool_t, src/core/ngx_palloc.c) — bump-allocator with cleanup callbacks. One per cycle, one per connection, one per HTTP request, one per subrequest. Freed all at once when the owner ends.
  • Slab allocators (ngx_slab_pool_t, src/core/ngx_slab.c) — fixed-size class allocator over a shared-memory zone. Used for SSL session caches, limit-req zones, upstream zones.
  • Shared memory zones (ngx_shm_zone_t, src/core/ngx_cycle.h) — mmap'd segments shared between workers. Created via ngx_shared_memory_add() during config parsing and re-attached on each reload.
  • Buffers and chains (ngx_buf_t + ngx_chain_t, src/core/ngx_buf.h) — every byte that flows through the output filter chain travels in a buffer link. Buffers can be in-memory, file-backed, or both.

See primitives/pool, primitives/buffer, and systems/core for details.

Build pipeline

graph LR
    A[auto/configure] -->|probe OS, libs| B[objs/ngx_auto_config.h]
    A -->|stitch modules| C[objs/ngx_modules.c]
    A -->|emit| D[objs/Makefile]
    D -->|gcc / clang| E[objs/*.o]
    E -->|link| F[objs/nginx]

The auto/ directory is hand-written shell, not autotools. auto/configure invokes auto/options, auto/cc, auto/lib, auto/os, and auto/modules to probe the system, decide which optional features are available, and generate the makefile. There is no ./configure --help autotools convention — flags are documented at nginx.org/en/docs/configure.html. See systems/configuration for the build system and how-to-contribute/tooling for everyday usage.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – nginx wiki | Factory