nginx runs on almost every server that serves a web application, and most administrators already have a familiar config with location and proxy_pass blocks. The question "can the same nginx cover the role of an API gateway" comes up for exactly that reason — nobody wants to add a new service just to route a handful of paths. This article covers what nginx handles on its own, where its limits are, and how to tell whether those limits are enough for a given project.
How an API gateway differs from a plain proxy
A reverse proxy accepts a request and forwards it further by one rule: usually by domain or by path. An API gateway adds a layer of logic on top of that, specific to APIs — token validation, rate limiting per client, aggregating several backends into one response, route versioning.
The line between the two roles is blurry: part of the gateway functionality nginx covers with built-in directives, part needs a third-party module or a separate process. So the answer to "does nginx fit" always depends on which exact functions a given project needs.
What nginx does out of the box
Basic routing by path and host, proxying to several upstream servers with load balancing, limiting the number of connections and requests with the limit_req and limit_conn directives, terminating TLS, serving static files without touching the backend — all of that is built in, with no extra modules. Basic setup is covered in the article on configuring nginx.
That also includes rewriting headers, returning custom response codes based on conditions, basic login-password authentication, and restricting access by IP through allow and deny. For an internal API or a gateway with a small set of rules, that is often enough without third-party software.
What is missing without third-party modules
Validating a JWT or integrating with an OAuth2 provider is not done with built-in means — it needs a module such as njs (embedded JavaScript) or moving the check to a separate service that nginx calls through auth_request.
- validating and decoding JWT without writing code in njs or lua;
- automatic service discovery — the upstream list has to be updated by hand or through an external config generator;
- protocol transformation, for example turning a REST request into a gRPC call;
- a single metrics panel across routes — it needs an export to a monitoring system through a third-party module.
The table below sums up the difference between plain nginx and a specialized gateway by key functions:
| Function | nginx | Specialized API gateway |
|---|---|---|
| Routing by path and host | yes | yes |
| Rate limiting per client | limited, by hand | yes, by default |
| JWT and OAuth2 validation | via a module or an external service | yes |
| Service discovery | no | yes |
| Protocol transformation | no | yes |
When plain nginx is enough
If one or two backends sit behind the gateway, routes do not change every week, and token checking is simple — matching one secret or a static key list — plain nginx is enough without third-party add-ons. The same logic applies to internal APIs that never leave a single network.
On a loaded server, it is worth first checking whether performance is actually limited by worker and buffer settings — that is covered in the article on optimizing nginx on a VPS, before adding another layer of infrastructure.
When a specialized gateway or Traefik makes sense
If there are dozens of backends that appear and disappear dynamically — in containers or an orchestrator — manually updating the upstream list in nginx config becomes a bottleneck. In that case it makes more sense to look at a solution with automatic service discovery, such as Traefik as a reverse proxy, which rereads the backend list without stopping the process.
The same applies to APIs with different protocols on the outside and inside — REST outside, gRPC inside — and to setups where a single authentication policy is needed across many independent development teams: a specialized gateway offers ready-made policies for that, while nginx would require custom code.
How to prepare nginx for the gateway role
Once the decision in favor of nginx is made, the order of steps is this:
- move shared directives — limits, headers, TLS — into a separate config file and bring it in through include;
- describe an upstream block with the list of backends and the balancing method;
- add limit_req_zone and limit_conn_zone to limit request rate by IP or by API key;
- set up token validation through auth_request if authentication is needed at the gateway level;
- enable logging in a format that an external monitoring system can parse, and check the config with nginx -t before reloading.
upstream api_backend {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
}
location /api/ {
limit_req zone=api_zone burst=20 nodelay;
proxy_pass http://api_backend;
}
limit_req_zone $binary_remote_addr zone=api_zone:10m rate=10r/s;
location = /auth-check {
internal;
proxy_pass http://auth_service/verify;
}
Frequently asked questions
How does nginx as an API gateway differ from Kong or Traefik?
Kong and similar products are designed as a gateway from the start: they ship plugins for JWT, OAuth2, rate limiting, and service discovery without writing code. nginx lets you solve the same tasks by hand or through the njs module, which is more flexible but needs more setup and upkeep.
Is a separate API gateway needed for small traffic?
With one or two backends and a simple token check, the built-in nginx directives are usually enough. A separate gateway is justified once backends become numerous and change dynamically, or when a single authorization policy is needed across different teams.
Can rate limiting be added to nginx without third-party modules?
Yes, the limit_req and limit_conn directives ship in the standard nginx build and limit request rate by a key — most often by the client IP address. For finer logic, such as a limit by an API key from a header, the njs module or a separate service is needed.
Does nginx fit a microservice architecture with gRPC?
nginx supports proxying gRPC through the grpc_pass directive, but it does not convert REST to gRPC and back on its own. If that kind of transformation is needed at the edge of the system, a separate component is usually placed in front of nginx, or a specialized gateway is used.