Skip to content

Apache Web Server/Ingress Configuration for High Scale

Apache Web Server/Ingress Configuration for High Scale

Section titled “Apache Web Server/Ingress Configuration for High Scale”

At high scale, web tier failures often come from connection pressure, bad timeout defaults, and weak overload controls. The fix is not one setting. It is a coordinated edge strategy across Apache, ingress, and backend services.

Typical deployment model:

  1. Global DNS and CDN.
  2. Apache edge or reverse proxy tier.
  3. Kubernetes ingress controller.
  4. Internal services behind ClusterIP.
Client -> CDN/WAF -> Apache (edge proxy) -> K8s Ingress -> Services
  1. Keep p95 latency stable during burst traffic.
  2. Prevent connection storms from collapsing upstream services.
  3. Enforce deterministic behavior for retries and timeouts.
  4. Preserve request traceability across all hops.

Apache responsibilities at scale:

  1. TLS termination or passthrough policy enforcement.
  2. Request normalization and header sanitation.
  3. Connection reuse to upstream ingress.
  4. Optional coarse rate limiting and bot controls.
  5. Structured access/error logging with request IDs.

Ingress responsibilities:

  1. Host/path routing to internal services.
  2. Service-aware load balancing.
  3. Per-route policies (timeouts, body size, auth integration).

Key controls for event MPM workloads:

  1. ServerLimit, ThreadsPerChild, MaxRequestWorkers sized to CPU/memory.
  2. KeepAlive On with conservative KeepAliveTimeout.
  3. MaxConnectionsPerChild to recycle workers and limit memory leak impact.
  4. Upstream keepalive pools in mod_proxy for backend reuse.
  5. Explicit timeout boundaries for request read, proxy connect, and backend response.

High-level rule:

  1. Bound every queue and timeout.
  2. Never allow unbounded waiting paths.

For NGINX ingress-like controllers:

  1. Set request timeout values intentionally by workload.
  2. Configure buffer/body limits to prevent memory pressure.
  3. Tune upstream keepalive and worker connection limits.
  4. Use separate ingress classes for internal and external traffic when needed.

Do not rely on defaults for high-traffic launch windows.

Timeout policy should be layered:

  1. Client edge timeout.
  2. Apache proxy timeout.
  3. Ingress upstream timeout.
  4. Application timeout.

Rules:

  1. Upstream timeout should be less than client timeout.
  2. Retries should be idempotency-aware.
  3. Avoid blind retries on non-idempotent POST operations.
  4. Reuse connections to reduce handshake and CPU overhead.
  1. Enforce modern TLS versions and cipher suites.
  2. Enable HSTS for public domains as appropriate.
  3. Forward security headers consistently (X-Forwarded-*, request ID).
  4. Sanitize/limit inbound headers and body sizes.
  5. Isolate admin endpoints from public routing paths.

Use tiered protection:

  1. Coarse global rate limit at CDN/WAF.
  2. Per-IP and per-path controls at Apache or ingress.
  3. Per-tenant or auth-aware limits in application layer.

This avoids overloading origin infrastructure with abusive traffic.

Track these at each tier:

  1. Request rate, error rate, and saturation.
  2. Upstream connect and response latency.
  3. 4xx/5xx by route and host.
  4. Connection pool utilization and resets.
  5. Retry counts and timeout distributions.

Alert on trend breaks, not only hard thresholds.

  1. Connection exhaustion at Apache:
    • Mitigation: tune worker/thread caps, keepalive timeout, and upstream reuse.
  2. Ingress 502/504 spikes:
    • Mitigation: verify backend readiness, upstream timeout mismatch, and service endpoint health.
  3. Retry storm under partial outage:
    • Mitigation: cap retries, add jitter, fail fast for non-critical paths.
  4. Slowloris-style request pressure:
    • Mitigation: request read timeouts and WAF protection.

Apache reverse proxy baseline:

ServerTokens Prod
ServerSignature Off
KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 2
Timeout 30
<IfModule mpm_event_module>
StartServers 4
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 50
MaxRequestWorkers 800
MaxConnectionsPerChild 10000
</IfModule>
ProxyRequests Off
ProxyPreserveHost On
<Proxy "balancer://ingress_pool">
BalancerMember "http://ingress-a.internal:80" retry=1 keepalive=On
BalancerMember "http://ingress-b.internal:80" retry=1 keepalive=On
ProxySet lbmethod=byrequests
</Proxy>
RequestHeader set X-Request-Id %{UNIQUE_ID}e
ProxyPass "/" "balancer://ingress_pool/"
ProxyPassReverse "/" "balancer://ingress_pool/"

Kubernetes ingress baseline:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: web
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
nginx.ingress.kubernetes.io/proxy-body-size: "8m"
spec:
ingressClassName: nginx
tls:
- hosts: ["www.example.com"]
secretName: web-tls
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-frontend
port:
number: 80
  1. Size Apache workers/threads based on load tests and memory budgets.
  2. Set strict timeout hierarchy across edge, ingress, and app.
  3. Enable connection reuse and avoid excessive handshake churn.
  4. Add layered rate limits and bot protection.
  5. Log request IDs end-to-end for incident triage.
  6. Run regular game days for 502/504 and retry-storm scenarios.

High-scale Apache and ingress reliability comes from explicit limits, clear timeout policy, and measurable behavior during failure. Treat edge and ingress as one delivery system, not isolated components.