Skip to main content

Gateway API Architecture, Feature Comparison, and Test Report

43 min read

Choosing a Gateway API implementation requires comparing the actual traffic path, policy extensions, and operational responsibilities as well as API support. This report compares representative architectures, reanalyzes published conformance evidence, and defines a feature and performance test procedure for EKS.

Evidence boundary

We analyzed 10 upstream reports covering 27 profiles. Locally executed tests exercise the measurement kit and response validation, not an installed Gateway controller. No EKS performance measurements of these implementations have been collected. There is no RPS, P99, or cost ranking. Raw evidence and execution records are in the benchmark kit.

1. Benchmark Objective​

The comparison should answer specific engineering questions:

  • Can the required routes, filters, and policies be expressed through standard APIs?
  • Which traffic path meets the required arrival rate and SLO for the same request contract?
  • How do configuration changes, failures, and certificate rotation affect existing connections and new requests?
  • Which components, resources, and costs remain the operator's responsibility?

Representative architectures​

Table 1. Request path and distinctions to test for each representative Gateway API implementation

ImplementationControl plane and actual request pathDistinctions to test
AWS Load Balancer ControllerA controller configures managed ALB L7 or NLB L4 routingAWS integration, ACM certificates, managed scaling. ALB and NLB are separate paths; controller CPU is not load balancer CPU
Envoy GatewayA control plane deploys and configures Envoy proxiesIsolation and resource use of per-Gateway versus shared proxy fleets; policy extensions
NGINX Gateway FabricSeparate control-plane and NGINX data-plane pods communicate over secure gRPCNGINX build/edition, configuration updates, forwarding to Pod endpoints
kgatewayGateway API resources and policies become Envoy configurationSeparate OSS from vendor extensions. The reviewed OSS repository is Apache-2.0; an enterprise license is not a blanket requirement
Kong KIC + Kong GatewayKIC supplies configuration; Kong Gateway handles requestsKIC/proxy versions, router flavor, plugins, edition, and their operational costs
Traefik ProxyThe Kubernetes Gateway provider supplies proxy configurationEntrypoints, provider options, and Experimental-channel scope
Cilium Gateway APIeBPF/TPROXY interception reaches per-node Envoy for L7CNI, security policy, and observability integration; eBPF alone neither processes all L7 traffic nor proves superior performance
IstioEnvoy ingress Gateway; ambient adds ztunnel/HBONE and optional waypoint pathsSeparate ingress from mesh, recording waypoint placement, traffic enrollment, and added hops

The table follows project architecture references. Features from different versions and deployment modes must not be combined under a single product name. VPC Lattice uses a separate aws-application-networking-k8s controller and managed service network. It is a separate comparison track, not an ALB/NLB mode.1

Evidence levels​

Table 2. Status in this report and what each evidence type establishes

EvidenceStatus in this reportWhat it establishes
Upstream conformancePinned YAML reanalysis completeAPI behavior reported for that version and profile
Local fixtureExecution records providedRequest generation, response assertions, failure detection
Installed implementation feature testsnot_runRequires testing the actual controller and proxy
Installed implementation performancenot_run; measurements nullThroughput, latency, efficiency, and cost conclusions pending

2. Test Environment Design​

Compare equivalent traffic paths​

Figure 1. Managed edge, in-cluster proxy, and CNI/mesh traffic path comparison

Expand the diagram to read labels and follow connections.
Diagram

Compare managed edge, in-cluster proxies, and CNI/mesh integration in separate groups. Do not combine direct proxy measurements with requests that traverse an NLB. An NLB L4 forwarding test and an Envoy L7 test behind an NLB are different experiments. Lattice needs a separate service-network, DNS, and authentication path.

Where a common entry layer is used, keep that layer, target mode, and AZ placement consistent. If switching CNI or enrolling workloads in a mesh affects other candidates, use separate clusters and record the environmental differences.

Record before execution​

Table 3. Required records to pin before execution, by area

AreaRequired records
EnvironmentAWS account/profile/region, dedicated cluster/namespace, Kubernetes/OS/kernel/CPU architecture, node types/count/AZs, CNI/MTU/kube-proxy mode
ImplementationController/proxy image digests, Gateway API version/channel, GatewayClass/controllerName, chart/flags/policies, configuration checksum
Request pathInternal/external generator placement, ingress hops, target type, cross-AZ traffic, client→gateway and gateway→backend protocols, TLS termination
WorkloadMethod, payload/response size, compression, connection reuse, timeout/retry, expected status/body/backend ID, route count and request distribution
ExperimentRun ID, source revision, tool versions, warm-up/measurement/drain windows, arrival rate/VUs/repetitions/order, SLO, stop conditions, cost limit

Select and pin measurement versions after checking compatibility at deployment time. The historical conformance cohort below is not a recommendation for new installations. Managed data-plane CPU and memory are not directly observable and must be marked not_observable.

3. Test Scenarios​

Pass feature checks first​

Verify the GatewayClass → Gateway → Route → Backend relationship and applicable observedGeneration, Accepted, Programmed, and ResolvedRefs conditions. Correlate requests and backend IDs to establish that responses actually traversed the Gateway under test. Calling an echo endpoint alone does not verify a Gateway.

Table 4. Requests, expected behavior, and distinctions for each feature test group

Test groupRequests and expected behaviorDistinctions to verify
Standard routingExact/prefix paths, hostname, header, weighted backends; boundary and mismatch cases/prefix-other must not match /prefix; unauthorized attachment and references must be rejected
Filters and backendsRewritten path/query, request/response header changes, timeout, mirroringDeclared Extended support versus observed behavior; separate mirrored traffic from primary requests
TLS and protocolsCertificate/SNI, termination/passthrough, HTTP/1.1, HTTP/2, gRPCBoth protocol legs, certificate lifecycle, backend TLS policy
Implementation policiesAuthentication, rate limit, plugins, observabilityStandard API versus custom CRDs, OSS/commercial scope, added hops
AI extensionsModel selection, inference endpoints, admission/rate limit, streamingExtension version and backend contract; separate token generation time from Gateway overhead

The last two groups are not assumed to be common capabilities. Preserve pass, fail, unsupported, skipped, and not_run with evidence. A field absent from an upstream report is not_reported.

1. Basic Throughput (Throughput Test)​

Use constant-arrival-rate to schedule a fixed number of operation starts per second. The basic HTTP test makes one GET per iteration with no redirects or retries. VUs provide execution capacity to maintain that schedule; concurrency is not a measurement of maximum RPS.2

The initial proposal is 10/50/100 requests/s for each eligible HTTP protocol, repeated three times. Each repetition has 60 seconds of warm-up, 180 seconds of measurement, and a separate drain window covering request timeouts. Two supported protocols produce 18 measurement windows. Adjust the plan to the dedicated environment's capacity and budget before running it, then expand only after low-rate validity checks pass.

Report the highest tested arrival rate that met the SLO. Do not call it maximum throughput without a valid failure bracket and evidence that the generator had spare capacity.

2. Latency Profile​

At the same arrival rate, retain successes, errors, and timeouts and report P50/P90/P95/P99 for each run. This plan withholds P99.9 below 100,000 observations; reaching that count alone does not guarantee statistical precision.

Define the measurement population by request start time and follow late completions through drain. Filtering only by completion timestamp can exclude slow boundary requests. Never average repeated P99 values. A combined distribution requires raw observations or histograms with identical bucket boundaries.

3. TLS Performance​

Test connection reuse and new connections separately. Record TLS version, certificate chain, client→gateway ALPN, and backend TLS. http_req_duration excludes initial DNS and connection establishment, so retain connection and handshake metrics separately.

The reviewed LBC version uses ACM configuration/discovery; do not apply another implementation's certificateRefs configuration unchanged.3 A request that negotiates HTTP/1.1 when HTTP/2 was expected is not an eligible HTTP/2 result.

The NLB L4 plan requires separate clients for TCP connection/echo, UDP sequence numbers/loss/jitter, and TLS passthrough SNI/backend certificates. Do not rank HTTP RPS against UDP packet throughput. The current HTTP kit does not execute these L4 cases.

4. L7 Routing Complexity​

Add simple paths, hostname/header matching, rewrites, and policies in controlled stages. At each stage verify status, body, backend ID, and transformed paths and headers. An 80:20 distribution needs sample counts and confidence intervals; insufficient samples remain inconclusive. Session affinity or correlated choices also invalidate an independent-selection assumption.

5. Scaling Test​

Route counts of 10/50/100/500 are proposed test sizes. Hold rule distribution and backend count constant, and measure steady-state requests separately from configuration convergence. Retain application time, condition updates, and time to the first correct response. Resource acceptance alone does not prove that the data plane is serving the new configuration.

6. Resource Efficiency​

Collect the control plane, proxy, backend, and generator separately. Include Cilium agent/CNI/Envoy placement and relevant mesh tunnels/waypoints. Divide successful requests by the measured CPU-seconds of the declared components over the same window.

ALB/NLB/Lattice cannot receive an equivalent proxy-container CPU allocation. Assess those paths separately using observable service metrics, costs with explicit usage/period/region, and operating responsibilities. This report contains no price estimates.

7. Failure Recovery​

Test controller restart, proxy replacement, backend termination, and certificate rotation separately. Existing connection survival and new Route reconciliation are distinct outcomes. Record error windows, recovery time, connection drain, and interruption of long-lived streams.

Run only after the dedicated target, timing, and stop limits are established. Retain previous configuration/images/certificates. Recovery stops load generation, restores the change, then rechecks resource status and the response contract.

8. gRPC Performance​

Separate unary, server-streaming, client-streaming, and bidirectional cases. Verify gRPC status, message content/count/order, time to first message, inter-message gaps, and completion in addition to HTTP status.

AI-service SSE needs its own client that verifies first event, progressive delivery, interruption, and completion. A completed ordinary HTTP GET is not a streaming test. This kit does not yet include gRPC/SSE load clients; both remain not_run.

4. Measured Metrics​

Table 5. Metric units and definitions with their boundaries

MetricUnitDefinition and boundary
Arrivals/completions/successesoperations/s or requests/sSeparate scheduled, started, completed, successful, failed, timed-out, interrupted, and dropped work; declare requests per iteration
Request durationmshttp_req_duration excludes initial DNS/TCP/TLS setup; define whole-operation time separately
Connection/TLSmshttp_req_connecting, http_req_tls_handshaking; distinguish reused connections with zero samples
Errors/dropscount, %Declare denominator; dropped_iterations counts work that never started
CPUcoressum(rate(container_cpu_usage_seconds_total[window])); percentages require an explicit core denominator
MemoryMiBcontainer_memory_working_set_bytes / 1024 / 1024; retain time series
NetworkMbpsApply rate() to each counter, then sum × 8 / 1,000,000; avoid duplicated interfaces
Reconciliation/recoveryms or sDefine start/end events and distinguish control plane from data plane

Pin collection settings with the cAdvisor metric definitions and Prometheus functions used for counter rates and quantiles.

Acceptance gates require correct response contracts, no drops or interruptions, verified protocol, generator/backend bottleneck checks, and retained raw data/configuration/exit codes. Keep failed load levels with their failure reason; do not rank their apparently fast responses. Interleave or randomize candidate order across repetitions and verify stabilization/cooldown. Final SLOs must come from workload requirements; this report does not invent a universal P99 pass threshold.

5. Validation Results and Measurement Status​

Reanalysis of published conformance​

We pinned kubernetes-sigs/gateway-api commit 112584e6624e32a9c9ec6a818a735506fc33eb49 and verified SHA-256 hashes of 10 reports. The source manifest and original files and derived analysis JSON retain API version, channel, mode, report time, reference release, and provenance differences. This is reanalysis of upstream-executed tests, not our EKS execution.

The following six members share Gateway API v1.4.0 / experimental / default. HTTP/gRPC/TLS numbers are passed Core test counts in the respective Gateway profiles; each has zero Core failures and skips.

Table 6. Passed Core counts and interpretation boundaries for the v1.4.0 experimental cohort

Implementation and reported versionHTTP / gRPC / TLS CoreInterpretation boundary
Envoy Gateway v1.6.033 / 13 / 11Report predates reference-release publication; not independent verification of the final image
Cilium 1.19.0-pre.233 / 13 / 11Prerelease evidence, not a stable 1.19 result
NGINX Gateway Fabric v2.3.033 / 13 / 11Recorded version/profile only
kgateway v2.1.033 / 13 / 11OSS report; separate vendor extensions
Istio 1.2833 / 13 / 11YAML omits patch; report predates reference 1.28.0 publication
Traefik v3.633 / 13 / 11YAML omits patch; report predates reference v3.6.0 publication

The pinned Cilium source starts with <Right>apiVersion rather than apiVersion. Frozen bytes and hashes remain unchanged, and source_metadata_issues records the defect. The profile statistics remain upstream-reported values; they do not establish valid source metadata.

Common Core success does not imply identical Extended support. NGF declares HTTPRouteBackendProtocolH2C unsupported in this cohort despite gRPC Core success. Envoy/Istio declare HTTPRouteCORS supported; Cilium/NGF/kgateway/Traefik declare it unsupported. NGF's BackendTLSPolicy declaration does not turn its absence in another report into evidence of non-support.

Keep the following supplemental records separate because their path, API version, or mode differs.

Table 7. Core results and comparison boundaries for supplemental evidence with differing paths or versions

Separate evidenceReported Core resultComparison boundary
VPC Lattice controller v2.0.1, API v1.4.0HTTP 10 passed / 23 skipped, partialManaged service-network path
AWS LBC v3.2.0, API v1.5.0 standardHTTP 23 passed / 10 skipped, partialReproduction uses ALB, not NLB
Kong KIC v3.4.0, API v1.2.1, expressionsHTTP 33 passed; gRPC 11 passed / 1 skippedFixed router flavor
Same KIC, traditional_compatibleHTTP 32 passed / 1 skipped; gRPC 10 passed / 2 skippedDo not merge with expressions

Missing v1.4.0 LBC/KIC reports in the selected tree mean not_verified. A partial result with zero failures is not full success. Adding Core and Extended counts does not produce a feature-support percentage or a performance score.4

Locally executed validation​

The prior execution report records the run at 2026-09-19 00:08 UTC. Pinned Python 3.13.15 and k6 2.2.0 images ran on an arm64 Docker VM with 10 CPUs and 8,217,317,376 bytes RAM, shared with three existing containers. The backend was limited to 1 CPU/256 MiB and the generator to 1 CPU/512 MiB, using an internal network only. These are declared limits, not utilization measurements. The published artifacts omit the original Docker info/inspect and before/after inventories, so actual limit enforcement, isolation and cleanup were not independently reverified.

Table 8. Observed result and outcome for each local fixture check

CheckObserved resultOutcome
Echo, controlled status, controlled delayThree feature probes passedFixture contract met
HTTP/1.1, 5 arrivals/s × 5 seconds, three repetitions26 / 26 / 25 requests; zero drops and response-contract failuresFirst two boundary-tolerated; third exact
Incorrect expected body26 failed body checksk6 exit 99; validator rejected
Delayed fixture with insufficient generator capacityFour requests; 37 dropped arrivalsk6 exit 99; validator rejected
Redirect override / skipped setupZero requests in both casesGuards rejected execution; exits 107 / 108
Resource cleanupThe derived report records test-resource removal and retention of three existing containersOriginal before/after inventories unavailable

The first two nominal runs observed 26 requests against 25 planned, or 104%. The validator classifies ±1 and 95–105% delivery as an explicit boundary-tolerance policy only when at least 20 arrivals were planned. This is not proof that timer races caused every discrepancy. Dropped arrivals remain unacceptable.

Raw execution records, exit codes, and the hash manifest retain per-run timing statistics. The historical Python probe incorrectly retains the k6 digest in generator_image. New configuration generation sets both the Python version and image digest; the evidence README records the erratum without changing old raw files or hashes. The k6 artifacts are summaries rather than request-level latency data, so their percentiles cannot be independently recomputed. Five-second fixture timings are not product performance plots or rankings. These runs did not test a Gateway, TLS, gRPC/SSE, Kubernetes state, or resource utilization.

Installed implementation measurements pending​

Table 9. Feature and performance measurement status and prerequisites by target

TargetFeature measurementsPerformance/efficiencyPrerequisites
ALB / NLBnot_runnullDedicated AWS/EKS target, service configuration, cost limit
Envoy / NGF / kgateway / Kong / Traefiknot_runnullPinned deployment, independent proxy/generator/backend capacity
Cilium / Istionot_runnullCNI/mesh path and isolated environment
VPC Latticenot_runnullService network, associations, authentication path

At this stage, API evidence and the measurement procedure are prepared. There is no evidence yet for implementation speed or cost superiority.

6. Benchmark Execution Plan​

Reproduction​

From the repository root, run source analysis and kit regression checks:

npm run test:gateway-benchmark

For a local arm64 Docker fixture check, choose a new output directory. Two pinned images are required. The runner creates and removes only its bounded containers and internal network, with no published host ports.

python3 scripts/benchmarks/gateway-api-benchmark/run-local.py \
--output /tmp/gateway-fixture-new-run

The kit README describes pinned images, output formats, limits, and individual commands. cases.routes.example.json is an unmeasured feature-contract example and deploys no Gateway. Review its expectations against the actual configuration and add resource-status evidence before use.

EKS execution stages​

Table 10. Deliverable and completion criterion for each EKS execution stage

StageDeliverableCompletion criterion
1. Confirm environmentAccount/profile/region/cluster/namespace, versions, capacity, budget, change/recovery scopeDedicated target and operational limits established
2. Verify featuresResource conditions, path evidence, standard/Extended/custom-policy resultsResponse contracts pass with explicit support and skip reasons
3. Establish HTTP baselineProtocol/rate repetitions, raw metrics, exit codes, resource time seriesGenerator validity, response correctness, and SLO can be assessed
4. Extend scenariosTLS, route scale, failures, gRPC/SSEScenario-specific clients, telemetry, and recovery validated
5. Update reportGroup-specific plots/tables, failure points, operating trade-offsEvery number traceable to raw execution evidence

The architecture report and bounded test kit requested in Issue #80 are available. Its follow-up live campaign remains pending; the owner must reconcile the closing scope before issue closure. Live EKS implementation measurements remain not_run/null and require a confirmed account/profile, region, dedicated cluster and capacity, and budget. Local fixture results do not complete the installed-Gateway stages.

Architecture references​

Footnotes​

  1. VPC Lattice controller v2.0.1 concepts. ↩

  2. k6 constant-arrival-rate, HTTP metric definitions. ↩

  3. LBC Gateway resources, certificates, and L4/L7 boundaries. ↩

  4. Conformance reporting rules at the pinned snapshot. ↩