nginx/nginx
Lore
The history of how nginx grew from one engineer's side project into a load balancer that fronts a substantial fraction of the public web.
Eras
The Sysoev era (Aug 2002 – Oct 2004)
Igor Sysoev started writing nginx in 2002 while at Rambler, a Russian search engine. The first commits in this repo are dated 2002-08-06, labeled nginx-0.0.1. The early goal was specifically to handle the C10K problem — serving tens of thousands of concurrent connections without spawning a thread per connection. Apache could not.
For two years there were no public releases. The codebase grew quietly: pool allocator, event loop, the cycle pattern, the module system, an HTTP request engine. By Oct 2004 Sysoev was confident enough to publish release-0.1.0. The license was a permissive BSD-style — a pragmatic choice that let nginx spread without legal friction.
Public 0.x (Oct 2004 – Apr 2009)
Most of the architectural decisions visible in today's code crystallized in this period: the 11-phase HTTP engine, the pluggable event modules (epoll, kqueue, select, poll, /dev/poll, eventport), the upstream subsystem with FastCGI, proxy, and memcached, and the HTTPS/SSL integration via OpenSSL. The mail proxy modules (pop3, imap, smtp) landed in Mar–Sep 2007, broadening the scope from "fast HTTP server" to "general L7 proxy."
The codebase ballooned from a few thousand lines to most of the modules that exist today. Releases came in small, frequent chunks — 0.1.x through 0.8.x — and the version-numbering scheme remained two-digit.
Nginx, Inc. and the 1.x line (Apr 2009 – 2017)
Igor Sysoev co-founded Nginx, Inc. in 2011 to commercialize nginx. The company sold a closed-source commercial fork called NGINX Plus layered on the same mainline. The repo's commit volume swelled: 2009 was the busiest year ever (~850 commits) as the team pushed toward release-1.0.0, which shipped on 2011-04-12.
Through the 1.x line the team stabilized the API for third-party module authors and added performance and protocol features:
- Apr 2015 — the Stream module (generic L4 proxy) was ported in from NGINX+. First commit: 2015-04-20. This unlocked using nginx as a TCP/UDP load balancer.
- Sep 2015 — HTTP/2 (RFC 7240/7241). First commit: 2015-09-11. Replaced the earlier (and never-merged-to-mainline) SPDY work.
- 2017 — Igor Sysoev retired from active development. Maxim Dounin became the de-facto lead committer.
F5 acquisition and the Dounin years (2019 – Jan 2024)
F5 acquired Nginx, Inc. in Mar 2019. From the outside very little visibly changed: the mainline kept moving, the website stayed put, the open-source license stayed BSD-2-Clause. Internally, the project became a small group inside a much larger company.
The dominant technical narrative of this era was HTTP/3 + QUIC:
- Mar 2020 — first HTTP/3 commits, in a long-running feature branch
- Dec 2020 — QUIC code reorganized under
src/event/quic/. First commit: 2020-12-25 (a Christmas Day refactor) - Jun 2022 — HTTP/3 lands in the mainline 1.25.x line as no-longer-experimental
The QUIC implementation is hand-rolled — nginx does not use ngtcp2 or quiche. It calls into OpenSSL for TLS 1.3 keying material via the KEYLOG callback (or via a custom OpenSSL compat shim, ngx_event_quic_openssl_compat.c, when linked against an OpenSSL that lacks native QUIC).
freenginx and the F5 stewardship era (Jan 2024 – present)
In Feb 2024 Maxim Dounin announced he was forking nginx as freenginx, citing disagreements with F5's management of security disclosures. Dounin's commit volume in this repo dropped to near zero after early 2024; his last commit here is from early 2024.
F5 reorganized the open-source side: the canonical repository moved to github.com/nginx/nginx (this repo) and development now happens via GitHub PRs rather than the older mailing-list-and-mercurial workflow. Sergey Kandaurov, Roman Arutyunyan, Andrew Clayton, and Aleksei Bavshin became the most active committers.
Recent focus areas:
- 2024–2025 — OpenSSL 4.0 compatibility (renamed error codes, deprecated APIs)
- 2024–2025 — HTTP/3 and QUIC refinements (memory usage, bug fixes, frame handling)
- Apr 2025 —
release-1.28.0(stable) and the1.27.xmainline preceding it - Apr 2026 —
release-1.30.0, the latest tag in this snapshot. The current mainlinemasterreports1.31.0insrc/core/nginx.h.
GitHub workflow infrastructure was added in this period:
.github/workflows/check-pr.yml,check-commit-message.yaml,check-version-bump.yaml,check-whitespace.yaml,f5_cla.yml,mark-issues-prs-stale.yaml,new-issue-welcome.yaml.github/ISSUE_TEMPLATE/,.github/DISCUSSION_TEMPLATE/,pull_request_template.md
These reflect the move from "nginx-devel mailing list" to "GitHub Issues + PRs."
Longest-standing features
- The pool allocator (
ngx_palloc.c) — first commit Aug 2002. Has been refactored several times but the API (ngx_create_pool,ngx_palloc,ngx_pool_cleanup_add,ngx_destroy_pool) is unchanged. Every other subsystem depends on it. - The cycle pattern (
ngx_cycle.c) — also from Aug 2002. The way nginx handlesSIGHUPreloads — by building a fresh cycle from the old one — has been the default reload strategy since the project began. - The 11-phase HTTP engine (
ngx_http_core_module.c) — same shape since at least 2007. The phase names occasionally got renamed (PRECONTENTwas onceTRY_FILES), but the order and the phase-handler hook signature are stable. - The sample
nginx.conf(conf/nginx.conf) — its skeleton (aneventsblock, anhttpblock with oneserverlistening on 80, a default index page) has shipped since 0.1.0.
Major rewrites
| What | When | Why |
|---|---|---|
QUIC moved to src/event/quic/ |
Dec 2020 | Originally lived alongside HTTP/3 code; split out so the transport could be reused |
| HTTP/2 implementation | Sep 2015 | Replaced never-merged SPDY work; written from spec |
| Stream module port | Apr 2015 | Brought NGINX+'s commercial L4 proxy back into mainline |
| The slab allocator | 2010-ish | Replaced ad-hoc shared-memory allocators with a class-based slab |
| OpenSSL stapling | 2014 | Added inline OCSP response caching to avoid client-side OCSP lookups |
Deprecated and removed features
- SPDY — implemented experimentally but never merged to mainline. Replaced by HTTP/2 in 2015. References to SPDY in old commit messages and old branches; no SPDY code remains in
src/. - The
aio sendfiledirective — quietly deprecated; modern Linux usessendfile()plus AIO without a special directive. ssldirective onlisten(deprecated form) — thesslkeyword on alistenline replaced the earlierssl on;directive years ago.- The
master_process off;mode — still present, but only for debugging. Production should always run with the master. - Various OS modules:
ngx_devpoll_module(Solaris/dev/poll) andngx_select_module/ngx_poll_moduleare still compiled but rarely used outside of legacy or fallback environments.
Growth trajectory
graph LR
A[2002:<br/>1 dev<br/>~10K LOC] --> B[2004:<br/>0.1.0<br/>~30K LOC]
B --> C[2007:<br/>mail proxy<br/>~70K LOC]
C --> D[2011:<br/>1.0 / Nginx Inc.<br/>~120K LOC]
D --> E[2015:<br/>HTTP/2 + Stream<br/>~170K LOC]
E --> F[2020:<br/>HTTP/3 + QUIC<br/>~220K LOC]
F --> G[2026:<br/>F5 stewardship<br/>~247K LOC]The dominant pattern: the codebase grows by adding new modules and protocol implementations, not by rewriting the core. The pool allocator from 2002 still allocates memory for QUIC buffers in 2026.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.