Envoy vs NGINX, Java, and Go for API Gateways
API7.ai
February 28, 2025
Envoy, NGINX/OpenResty, Java frameworks, and Go programs are different foundations for building an API gateway. They cannot be ranked reliably by programming language alone. A product's filters, configuration model, deployment topology, default limits, and operating practices often matter more than its implementation language.
This guide compares the four choices as gateway runtime families. It avoids universal latency or throughput claims because meaningful results require the same hardware, protocols, TLS settings, policies, payloads, upstream behavior, and test method.
Key Takeaways
- NGINX and OpenResty use an event-driven worker model; OpenResty adds Lua-based request processing and a broader library ecosystem.
- Envoy can run from static configuration or receive dynamic configuration through xDS. A separate control plane is useful for many deployments but is not mandatory.
- “Java gateway” can mean a framework such as Spring Cloud Gateway, a commercial product, or a custom application. Current Spring Cloud Gateway has WebFlux and Web MVC variants.
- “Go gateway” is also a family, not one architecture. Concurrency, configuration, extensions, and protocol support depend on the product.
- Choose using a representative benchmark and an operational proof of concept—not claims that one language is always faster, lighter, or easier.
What Are You Actually Choosing?
An API gateway combines a request-processing runtime with a control and operating model. A useful evaluation separates at least five layers:
- Data plane: accepts connections, parses protocols, applies policies, and proxies traffic.
- Configuration plane: distributes routes, upstreams, certificates, and policy settings.
- Extension model: runs built-in or custom filters and plugins.
- Operations: exposes metrics, logs, traces, readiness, debugging, and rollout controls.
- Product layer: adds governance, developer workflows, tenancy, support, and integrations.
Envoy and NGINX are proxy foundations. Java and Go are languages and runtime ecosystems in which several gateways are built. Comparing them as if they were four interchangeable binaries hides those layers.
NGINX and OpenResty-Based Gateways
NGINX's architecture uses a master process and event-driven worker processes. Workers handle many connections without assigning one operating-system thread to every connection. NGINX modules provide features in phases of request processing.
OpenResty packages NGINX with LuaJIT and Lua libraries. Gateways built on OpenResty can implement dynamic policy and plugins in Lua while retaining NGINX's networking model. Product architecture still varies: configuration storage, synchronization, plugin isolation, and hot-update behavior are not properties of NGINX alone.
Strengths to Evaluate
- Mature HTTP proxying, TLS, upstream selection, and connection management.
- Event-driven workers suited to large numbers of network connections.
- NGINX modules and, with OpenResty, Lua phases and libraries for request policy.
- Familiar operational concepts for teams already running NGINX.
- A clear separation can be built between a lightweight data plane and an external control plane.
Tradeoffs to Evaluate
- Blocking work in an event loop can stall a worker; extensions must use appropriate nonblocking APIs or offload work.
- Native NGINX modules have a different build and safety model from Lua plugins.
- Advanced NGINX configuration and request phases require specialized knowledge.
- A product may offer external runners or WebAssembly, but support and constraints are product-specific.
Apache APISIX is built on NGINX and OpenResty. It adds dynamic routing, a plugin system, and its own control and configuration mechanisms. Evaluate APISIX using its current documentation and a workload test rather than attributing every APISIX capability to generic NGINX.
Envoy-Based Gateways
Envoy is a network proxy with listeners, filter chains, clusters, and a worker-thread architecture. It supports HTTP/1.1, HTTP/2, HTTP/3, gRPC, TCP proxying, observability integrations, and extensible traffic filters.
Envoy is strongly associated with service meshes because it is used as a data plane in systems such as Istio. It can also run as an edge or API gateway. These are deployment choices, not separate Envoy editions.
Static and Dynamic Configuration
Envoy can start with a static bootstrap configuration. For changing environments, its xDS APIs can deliver listeners, routes, clusters, endpoints, secrets, and other resources dynamically. A control plane helps coordinate xDS state, but saying Envoy “requires a control plane” is inaccurate.
Strengths to Evaluate
- Broad Layer 4 and Layer 7 protocol handling.
- xDS APIs for dynamic discovery and configuration.
- Strong alignment with proxy-based service mesh architectures.
- Detailed metrics, access logging, tracing hooks, and health behavior.
- Several extension paths, including built-in filters, native extensions, WebAssembly, and external processing, each with different constraints.
Tradeoffs to Evaluate
- xDS resource relationships and eventual updates need careful control-plane design.
- Filter ordering, timeouts, retries, circuit breakers, and outlier detection can interact in non-obvious ways.
- Writing an in-process native filter can require C++, but not every extension requires a custom C++ filter.
- An Envoy-based product may hide or add significant behavior; assess the product, not just Envoy's feature list.
Java-Based Gateways
A Java gateway is usually an application or product running on the JVM. Spring Cloud Gateway is a prominent framework, but it should not stand in for every Java implementation.
Current Spring Cloud Gateway documentation includes a WebFlux server variant and a Web MVC server variant. The execution and concurrency model therefore depends on the selected variant, libraries, filters, and any blocking calls. “Java gateway” does not automatically mean one thread per request, nor does it guarantee reactive execution.
Strengths to Evaluate
- Familiar language, build tools, testing frameworks, and observability for Java teams.
- Direct integration with Spring configuration, security, resilience, and service-discovery ecosystems.
- Application-level filters can reuse typed libraries and organization-specific Java components.
- A custom gateway can be developed and debugged with normal application tooling.
Tradeoffs to Evaluate
- Custom code increases the team's ownership of upgrades, vulnerability remediation, and policy correctness.
- Blocking libraries in a reactive request path can reduce concurrency and need explicit isolation.
- JVM startup, memory, garbage collection, and just-in-time compilation must be measured under the actual deployment model.
- Framework flexibility can encourage business orchestration in the gateway, increasing coupling and failure impact.
Choose a Java gateway when its framework and team fit are valuable, not because Java is universally slower or easier than another runtime.
Go-Based Gateways
Go is used for gateways, ingress controllers, service proxies, and control-plane components. Go's goroutines and standard networking libraries support concurrent services, but “Go-based gateway” does not identify a single proxy architecture.
A Go product might implement request processing in one binary, embed another proxy, generate proxy configuration, or divide control and data planes. Its plugin model may use compiled packages, side processes, RPC, WebAssembly, configuration-only middleware, or no third-party in-process plugins.
Strengths to Evaluate
- A statically compiled deployment can simplify packaging.
- Go tooling and concurrency primitives are familiar to cloud-native teams.
- Product-specific extensions may be straightforward for teams already using Go.
- The same ecosystem can support controllers and automation around Kubernetes APIs.
Tradeoffs to Evaluate
- Compiled in-process extensions can couple plugin releases to the gateway binary.
- Garbage collection, allocation, connection pools, and scheduler behavior still require measurement.
- Protocol depth and plugin ecosystems vary considerably across Go gateway products.
- A smaller binary or simpler example does not prove lower production resource use under policy-heavy traffic.
Architecture Comparison
| Area | NGINX/OpenResty family | Envoy family | Java framework family | Go product family |
|---|---|---|---|---|
| Core model | Event-driven workers; modules and optional Lua | Worker threads; listeners, filters, clusters | JVM framework; model depends on WebFlux, MVC, or product | Product-specific Go concurrency and proxy design |
| Dynamic configuration | Product-specific APIs and storage | xDS or product control plane; static also supported | Framework configuration, discovery, or product control plane | Product-specific controller, APIs, or files |
| Extension examples | NGINX modules, Lua, product-specific runners/Wasm | Built-in/native filters, Wasm, external processing | Java filters and framework integrations | Compiled middleware, RPC, Wasm, or configuration |
| Common fit | Edge/API gateway with NGINX operations or Lua policy | Mesh, edge, or gateway needing xDS and protocol depth | Java/Spring application platform integration | Go/cloud-native team and product-specific fit |
| Main evaluation risk | Blocking plugins and complex request phases | Control-plane/filter interaction complexity | Custom-code ownership and blocking behavior | Assuming all Go products share one architecture |
This table describes families. Product documentation and tests must confirm individual capabilities.
Protocol and Traffic Requirements
Start with protocols instead of language preference:
- Which HTTP versions, gRPC modes, WebSocket, TCP, UDP, or streaming behaviors are required?
- Must the gateway inspect messages or only proxy connections?
- How are request and upstream timeouts represented?
- Are retries safe for the workload, and are they limited by an overall deadline?
- Does the gateway preserve cancellation and trace context?
- How are certificate rotation and upstream identity handled?
A proxy can list a protocol while lacking the policy granularity or operational visibility the application needs. Test complete flows, including malformed requests, client cancellation, slow streams, partial upstream failure, and rolling configuration updates.
Extensibility and Safety
“Easy to extend” is incomplete without an isolation model. For every runtime, ask:
- Does extension code run inside the data-plane process, in a sandbox, or in a separate process?
- Can an extension block the request loop or exhaust shared memory?
- Which APIs are stable across upgrades?
- How are dependencies, signatures, and supply-chain provenance controlled?
- Can policy be tested without starting the whole production platform?
- What happens when an extension times out, crashes, or returns an invalid result?
An external extension may reduce process crash risk but add network latency and another failure mode. An in-process extension may be fast but expands the trusted computing base. There is no universal winner.
How to Benchmark the Options
Do not use a vendor headline benchmark as a capacity plan. Build a reproducible test that includes:
- the same instance type, CPU limits, network path, and TLS mode;
- the protocols, request sizes, response sizes, and connection reuse seen in production;
- the same authentication, authorization, rate limit, logging, and tracing policy;
- a realistic mix of fast, slow, successful, and failing upstreams;
- configuration updates during traffic; and
- latency percentiles, errors, saturation, CPU, memory, and recovery—not requests per second alone.
Warm up the system, publish test scripts and settings, repeat runs, and identify the bottleneck. If the upstream is the constraint, a gateway comparison may only measure how each product handles waiting.
Decision Framework
Use these questions to narrow the choice:
- Existing platform: Which runtime can the on-call team operate and upgrade safely?
- Control model: Do you need static files, an admin API, GitOps, Kubernetes resources, or xDS?
- Extension boundary: Which policies are built in, and which require custom code?
- Topology: Is this an edge gateway, internal gateway, ingress data plane, service-mesh gateway, or several of them?
- Failure model: Can the data plane keep serving its last accepted configuration if the control plane is unavailable?
- Governance: How are configuration changes reviewed, staged, rolled back, and audited?
- Lifecycle: What is the supported upgrade and vulnerability-response path?
The answer may also be a combination—for example, an API gateway at the edge and Envoy sidecars internally. Avoid duplicating authentication, retry, and rate-limit policy at every layer without a clear owner.
FAQ
Is Envoy faster than NGINX?
There is no workload-independent answer. Both are production proxies with different architectures and features. Compare them with identical protocols, policies, hardware, telemetry, upstreams, and test methods.
Does Envoy require a control plane?
No. Envoy supports static configuration. A control plane becomes useful when xDS resources must change dynamically across a fleet.
Must Envoy extensions be written in C++?
No. Native in-process extensions can use C++, but Envoy also supports other extension mechanisms such as WebAssembly and external processing. Availability and constraints depend on the product and filter.
Is Spring Cloud Gateway only reactive?
No. Current Spring Cloud Gateway includes WebFlux and Web MVC server variants. Select and test the variant that matches the application's libraries and concurrency model.
Are Go gateways always lighter than Java gateways?
No. Resource use depends on implementation, configuration, traffic, telemetry, and deployment limits. Measure the exact products under the intended workload.
Which foundation is best for Kubernetes?
Kubernetes support is a product and controller capability, not a property of one language. Check Gateway API or Ingress support, rollout behavior, status reporting, multi-tenancy, and the data-plane lifecycle.
Next Steps
- Review API gateway fundamentals.
- Compare API gateway, reverse proxy, and load balancer roles.
- Explore Apache APISIX as an NGINX/OpenResty-based API gateway.
- Build a representative proof of concept before standardizing on a runtime family.