Skip to content

Performance Benchmarks

Nantian Gateway runs nightly conformance and load tests against the latest build. Results are published automatically to the platform-release repository. This page summarizes the current baseline and explains how to interpret and reproduce the results.

The following results are from a 10-minute vegeta HTTP load test running against a data plane instance inside a Kind cluster. The test sends HTTP/1.1 GET requests at unlimited rate through the gateway to a simple echo backend.

MetricValue
Throughput9,000–11,000 RPS
P50 latency3–4 ms
P90 latency6–9 ms
P99 latency11–15 ms
Max latency70–100 ms
Success rate100%
Data plane CPU~1,100 millicores
Data plane memory~105 MiB
  1. A Kind cluster is created with a single control-plane node.
  2. Nantian Gateway is deployed via Helm using the latest main branch images.
  3. A simple echo backend service is deployed (an HTTP server that returns a minimal response).
  4. A Gateway and HTTPRoute are created to route all traffic to the echo backend.
  5. Vegeta runs inside the cluster as a pod, sending requests to the gateway’s ClusterIP service.
1. Warmup: 60 seconds of unlimited-rate attack (results discarded)
2. Measurement: 10 minutes of unlimited-rate attack (results captured)
3. Resource sampling: CPU and memory samples taken every 60 seconds via kubelet summary API
  • Target: GET / through Gateway → dataplane → echo backend
  • Workers: 50 vegeta workers
  • Rate: Unlimited (workers send requests as fast as possible)
  • Data plane: 2 CPU cores (2000m limit), jemalloc allocator, LTO fat build
  • Backend: Minimal HTTP echo server
Terminal window
# Clone the gateway repository
git clone https://github.com/nantian-gw/gateway.git
cd gateway
# Run the conformance + performance suite
make conformance

This creates a Kind cluster, deploys Nantian Gateway, runs conformance tests, and executes the load test. Results are saved to dist/performance.json.

Terminal window
# Deploy the echo backend
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-bench
spec:
replicas: 4
selector:
matchLabels:
app: echo-bench
template:
metadata:
labels:
app: echo-bench
spec:
containers:
- name: echo
image: ghcr.io/nantian-gw/echo-bench:v2026.07.0
ports:
- containerPort: 8080
resources:
requests: {cpu: 500m, memory: 32Mi}
limits: {cpu: 2000m, memory: 64Mi}
---
apiVersion: v1
kind: Service
metadata:
name: echo-bench
spec:
selector:
app: echo-bench
ports:
- port: 80
targetPort: 8080
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: bench-route
spec:
parentRefs:
- name: your-gateway
rules:
- backendRefs:
- name: echo-bench
port: 80
EOF
# Run vegeta from inside the cluster
kubectl run vegeta-bench --restart=Never --rm -i \
--image=peterevans/vegeta:latest -- \
sh -c "printf 'GET http://your-gateway.namespace.svc:80/\n' > /tmp/t && \
echo 'Warmup 60s...' && \
vegeta attack -duration=60s -rate=0 -max-workers=100 -targets=/tmp/t > /dev/null && \
echo 'Measurement 120s...' && \
vegeta attack -duration=120s -rate=0 -max-workers=100 -targets=/tmp/t | vegeta report -type=json"

The number of successful requests per second. Higher is better, but throughput alone doesn’t tell the full story — a gateway that adds 100ms of latency to each request might still achieve high RPS if it has enough concurrent connections.

  • P50 (median): Half of all requests complete faster than this value. Represents typical user experience.
  • P90/P95: The slowest 10% and 5% of requests. Shows how well the system handles occasional congestion.
  • P99: The slowest 1% of requests. Important for SLA compliance — this is the latency most of your users will never see.
  • Max: The single slowest request in the entire test. Often driven by GC pauses, connection establishment, or scheduler delays.
  • Data plane CPU: Should scale with throughput. If CPU is maxed out but throughput isn’t growing with more workers, the bottleneck is CPU-bound.
  • Data plane memory: Should be stable. Growth over time suggests a memory leak. Nantian Gateway’s Rust data plane typically stays under 150 MiB in load tests.

If your throughput doesn’t match the baseline:

  1. Check your backend — the echo backend must handle at least the same throughput as the gateway. Use multiple replicas and ensure each replica has enough CPU.
  2. Check your vegeta configuration — running vegeta from a resource-constrained pod limits how many requests it can generate. Use multiple vegeta pods in parallel for high-scale testing.
  3. Check Gateway API resource configuration — complex route matching (many rules, filters, or backend weights) adds processing overhead.
  4. Check CPU allocation — the data plane needs at least 2 CPU cores to achieve the baseline numbers. Use resources.limits.cpu to ensure the pod gets enough compute.

For a deeper performance optimization guide, see the Configuration Tuning page.

Full nightly results with raw vegeta and CPU/memory data are archived in the platform-release repository.