Skip to main content

ADR-058: Pingora Integration — Embedded Connection Pool

  • Status: Accepted
  • Date: 2026-03-16
  • Decision Makers: Christophe Aboulicam
  • Related: ADR-024 (Gateway Modes), CAB-1847, CAB-1849

Context

Cloudflare's Pingora (Rust, Apache 2.0) replaced nginx and handles 1+ trillion requests/day. STOA Gateway is built on axum + reqwest + tokio. The question: how should STOA leverage Pingora?

Why Pingora

The Business Case (decisive factor)

Signalaxum-onlyWith Pingora
Enterprise pitch"Custom Rust gateway""Built on Pingora — Cloudflare's proxy framework"
Competitive positionSame tier as custom proxiesSame tier as Cloudflare Workers, Fastly Compute
CISO checkboxUnknown stackBattle-tested at 1T+ req/day
OSS credibilityGeneric frameworkInfrastructure-grade pedigree
Market uniquenessNoneOnly API gateway built on Pingora

No API gateway vendor — Kong, Gravitee, Envoy, agentgateway — uses Pingora. This is a first-mover advantage in positioning.

The Technical Case

Featurereqwest (current)Pingora Connector
Connection poolPer-client instanceShared across all workers (Cloudflare's key win)
H2 multiplexingPer-connectionGlobal stream multiplexing
Pool reuse at scaleDegrades >10K RPSDesigned for 1T+ req/day
Zero-copy proxyNo (userspace copy)Kernel splice/sendfile (future)

At under 1K RPS the difference is 0.5ms p95. At 50K+ RPS, shared pooling avoids connection exhaustion that per-client pools hit.

Options Evaluated

OptionDescriptionEffortVerdict
A: Full migrationReplace axum with Pingora server55+ ptsRejected — rewrites 400+ routes
B: SidecarPingora front-proxy → stoa-gateway21 ptsRejected — extra hop, thin value
C: EmbeddedPingora connector inside stoa-gateway13 ptsAccepted
D: Patterns onlyCopy Pingora patterns, don't use crate0 ptsSuperseded by C

Why Embedded (Option C) Won

  • One binary — no sidecar, no extra hop, no deployment complexity
  • Same marketing claim — "Built on Pingora" is equally true for embedded connector
  • Genuine value — Pingora's shared pool is the actual Cloudflare advantage, not the server
  • Feature-gated--features pingora enables it; default build stays reqwest (no cmake dependency)
  • Incremental — proxy path migrates to PingoraPool gradually; MCP/admin/auth stay on axum untouched

Decision

Embed pingora-core::connectors::http::Connector inside stoa-gateway behind a pingora feature flag.

Architecture

Client → stoa-gateway (:8080)

├─ MCP / admin / auth / OAuth → axum handlers (unchanged)

└─ Proxy routes → PingoraPool.send_request()

└─ pingora-core shared connection pool
→ Backend (H1/H2, TLS, keepalive)

One binary. One port. One deployment. Pingora manages upstream connections; axum manages HTTP routing.

Implementation

PRWhat
#1799stoa-pingora/ standalone binary (sidecar POC — superseded)
#1801PingoraPool embedded in stoa-gateway (production path)
#1803CI/CD: FEATURES=kafka,pingora in Docker build

Phase Compatibility

Our ProxyPhase trait maps 1:1 to Pingora's ProxyHttp:

STOA ProxyPhasePingora ProxyHttpStatus
request_filterrequest_filterMatch
upstream_selectupstream_peerMatch
upstream_request_filterupstream_request_filterMatch
response_filterupstream_response_filterMatch
loggingloggingMatch
error_handlererror_while_proxyMatch

If a full Pingora migration is needed at v2.0, phase implementations port directly.

What STOA Has That Pingora Doesn't

CapabilitySTOAPingora
eBPF kernel-level HTTP parsingXDP + TC programsNot built-in
UAC policy enforcement at kernel levelBPF maps synced from gatewayNot built-in
WASM plugin runtimewasmtime integrationNot built-in
MCP protocol (AI agent gateway)Full SSE/WS/JSON-RPCNot applicable
Multi-gateway federation7 adapter typesNot applicable

STOA uses Pingora for what it does best (connection pooling) and adds layers Pingora doesn't offer.

Consequences

  • Production image built with FEATURES=kafka,pingora (cmake required in Docker)
  • PingoraPool available for proxy path; reqwest remains as fallback
  • Default build (no features) still works without cmake dependency
  • Marketing: "STOA Gateway — powered by Pingora's connection engine"
  • NOTICE file includes Pingora Apache 2.0 attribution
  • Re-evaluate full migration at v2.0 or 50K+ RPS