Skip to main content

Architecture Overview

Impulse is an HTTP/3-first edge runtime. A native QUIC listener accepts HTTP/3 over UDP, while a bootstrap listener on the same configured address and port accepts HTTP/1.1 and HTTP/2 over TCP/TLS. Both ingress adapters use the same runtime generation, policy, routing, backend-selection, transport, and outcome contracts.

Architecture Pages​

QuestionPage
How is the system divided and which crate owns each boundary?This page
What happens to one request?Request Lifecycle
How does configuration become active runtime state?Runtime Generation and Configuration Lifecycle
How are H1/H2 upstream execution and backend state managed?Transport and Backend Lifecycle

System Shape​

The data plane accepts, evaluates, routes, and forwards requests. The control plane validates and activates configuration, exposes runtime state and metrics, runs health, Domain Name System (DNS), and certificate work, and coordinates drain or restart behavior. Control-plane services read the same active generation as request workers.

Native QUIC and Bootstrap Boundaries​

ConcernNative QUIC listenerBootstrap listener
Downstream wire protocolHTTP/3 over QUIC on UDPHTTP/1.1 or HTTP/2 over TCP/TLS
Ingress ownershipQUIC handshake, connection IDs, packets, H3 streamsTCP/TLS accept, Hyper request intake, compatibility parsing
Request policySharedShared
Routing and backend selectionSharedShared
Upstream transportShared H1/H2 façadeShared H1/H2 façade
Response egressH3 stream writesHTTP/1.1 or HTTP/2 response writes
Upgrade behaviorNo HTTP/1.1-style upgrade semanticsHTTP/1.1 WebSocket/upgrade handling where supported

The bootstrap listener is a compatibility adapter, not a second policy engine. Protocol-specific parsing, connection management, and response writeback remain local to each adapter; policy meaning and backend execution should not diverge.

Workspace Ownership​

The current Rust workspace contains these crates:

CratePathArchitectural responsibility
impulseimpulse/CLI, startup sequencing, listener-group supervision, signals, drain, and process exit
impulse-configcrates/config/YAML model, parsing, validation, secret resolution, and normalized runtime configuration
impulse-edgecrates/edge/Ingress adapters, request orchestration, routing, admission, resilience, runtime generations, backend lifecycle, metrics, and watchdog
impulse-bridgecrates/bridge/Canonical upstream request construction, header policy, response normalization, and upgrade helpers
impulse-transportcrates/transport/Runtime-selected HTTP/1.1 or HTTP/2 backend execution, connection reuse, timeouts, DNS-aware connection establishment, and client rotation
impulse-lbcrates/lb/Balancing algorithms, upstream pool selection, health flags, and per-pool request accounting
impulse-utilscrates/utils/Shared TLS and logging utilities
impulse-errorscrates/errors/Cross-crate error and retry/hedge classification types

Crate boundaries are intentional: edge decides whether and where to send a request; bridge shapes it; transport decides how to execute it; lb provides selection and accounting primitives.

Edge Runtime Boundaries​

Within impulse-edge:

  • quic_listener owns native and bootstrap adapter mechanics, worker wiring, forwarding orchestration, and control-service integration.
  • request_pipeline provides protocol-neutral route and selected-policy contracts used by both adapters.
  • routing owns the route index and matching decisions.
  • resilience and quic_listener::admission own admission and protection policy.
  • runtime owns published generations, request state/guardrails/outcomes, backend lifecycle, TLS inventory, shared services, and task ownership.
  • metrics, observability, and watchdog own their process-wide operational contracts.

Listener code may orchestrate these services, but should not reimplement their policy or durable state.

State and Concurrency​

The binary starts one managed listener group per configured listener. Native QUIC workers use UDP sockets and may use packet shards; bootstrap accepts TCP traffic for the same listener identity. Backend I/O and control work run on Tokio runtimes.

Workers read an immutable RuntimeBundle through RuntimeBundleHandle. A successful activation publishes a whole new bundle; readers holding the prior bundle can finish without observing a partially updated configuration. Backend and process services have explicit generation or process ownership described in Runtime Generation and Configuration Lifecycle.

Architectural Rules​

  • Keep ingress-specific wire mechanics in the native or bootstrap adapter.
  • Keep request policy and outcome meaning shared across both adapters.
  • Do not infer upstream protocol in edge; consume normalized config and the transport façade.
  • Do not let transport own routing, admission, retries, or durable health state.
  • Do not reconstruct active state from listener-local fields; read the active runtime generation.
  • Keep exact configuration and endpoint contracts in their reference pages, not in architecture prose.