What is NGINX?
NGINX is an HTTP web server, reverse proxy, content cache, load balancer and TCP/UDP proxy, originally written by Igor Sysoev and released under the 2-clause BSD license. The open-source project lives at nginx.org, which hosts the source, releases and the module reference documentation; that is the canonical URL for this page. nginx.com now redirects to F5’s product pages, because the commercial side belongs to F5, Inc. F5 NGINX Plus is the paid edition: it extends open-source NGINX with active health checks, an API for changing upstream configuration without a reload, a much larger set of real-time metrics, and commercial support. NGINX is not an API management platform. It has no developer portal or key provisioning, and most teams use it as the reverse proxy in front of their application or as the data plane under something that does provide those features.
Why use it in the API Lifecycle?
- Reverse proxy and load balancing:
proxy_passto upstream groups with round-robin, least-connections or hash-based balancing, plus passive health checks in the open-source build. - Rate and connection limiting:
limit_reqenforces a leaky-bucket request rate per key, andlimit_conncaps concurrent connections. - TLS termination: HTTP/2 and HTTP/3 at the edge, so upstream services can speak plain HTTP on a private network.
- Caching:
proxy_cachestores upstream responses and honors their caching headers, which takes load off read-heavy endpoints. - OpenTelemetry tracing: The
ngx_otel_moduledynamic module (packaged asnginx-module-otel) exports spans over OTLP/gRPC and handles W3C trace context propagation. - Commercial edition: NGINX Plus adds active health checks, dynamic reconfiguration through an API and deeper monitoring for teams that need them and want vendor support.
Best Practices
- Set
limit_req_status 429;wherever you uselimit_req. The default is503, which tells a client the server is broken rather than that it is sending too fast, and well-behaved clients treat503 Service Unavailableand429 Too Many Requestsdifferently. Add aRetry-Afterheader on the rejection, and giveadd_headerthealwaysparameter: without it,add_headeronly applies to 2xx and 3xx responses and the header never reaches the429. - Use
burstwithlimit_req. With the default burst of zero, two requests arriving in the same instant from a legitimate client are enough to trip the limit; addnodelayif you want the burst served immediately rather than queued. - Key rate limits on
$binary_remote_addror an authenticated identifier, not a raw header value. Requests with an empty key are not counted at all, so a key built from a header the client can omit is a bypass. - Append to forwarding headers rather than overwriting them:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;along withHostandX-Forwarded-Proto. If you consumeX-Forwarded-Forfrom an upstream load balancer, restrict trust withset_real_ip_fromso clients cannot spoof their address. NGINX adds no forwarding headers unless configured to, and that includes the standardizedForwarded. - Enable
ngx_otel_modulewithotel_trace_context propagate;at the edge so an incomingtraceparentis continued rather than replaced, and export to an OpenTelemetry Collector. The default,ignore, neither reads nor writes the trace context headers, so NGINX’s spans start a trace of their own instead of joining the caller’s. - Do not confuse the NGINX Ingress Controller (maintained by F5’s NGINX team) with ingress-nginx (a separate Kubernetes community project). Their annotations and configuration are not interchangeable.