PasskeyBridge

Engineering · 2026-06-22

Backpressure for Identity Pipelines: Designing Verifiers That Degrade Under DDoS, Not Collapse

By J. W. Bouckaert

Backpressure for Identity Pipelines: Designing Verifiers That Degrade Under DDoS, Not Collapse

Every identity verifier eventually meets the day where ingest exceeds capacity by an order of magnitude. The cause is rarely sophisticated. A botnet credential-stuffing run against a tenant's login page. A misconfigured customer mobile app that retries an expired session on a 100 ms loop. An honest viral moment that drove ten times the normal sign-in volume. The October 2016 Dyn attack hit 1.2 Tbps; the Cloudflare HTTP/2 Rapid Reset campaign disclosed in October 2023 peaked at 201 million requests per second against a single edge. The arithmetic of identity infrastructure does not care which one shows up.

Horsepower does not decide which verifier survives those events and which becomes the outage. The architecture does: whether it treats saturation as a first-class concern—with explicit admission control, priority-aware shedding, and a measurable P99 guarantee that the system actively defends—or as a tail risk to be handled "if we have to."

This article specifies the patterns. Where they come from, why they work, what the failure modes look like when they are skipped, and how PasskeyBridge composes them so the verifier degrades along a defined curve rather than collapsing.

Unbounded buffering loses

Every queue is a tradeoff between latency and throughput. The textbook constraint is Little's Law: the average number of requests in a stable system equals the average arrival rate multiplied by the average time each request spends in the system. L = λW. The relationship is unconditional. It does not depend on the queueing discipline, the arrival distribution, or the service-time distribution.

When arrival rate λ exceeds service rate μ and the buffer is unbounded, residence time W grows without bound. Two things happen at the verifier in that regime:

PhenomenonWhat the operator sees
GC pressure climbs as queued request objects pile upP99 latency moves from 30 ms baseline to 500 ms, then 5 s, then 30 s within 90 seconds
Upstream HTTP clients time out and retryEffective λ doubles or triples, accelerating the runaway
Connection-pool exhaustion at the downstream RPC layerNew verifier requests block on socket allocation, freezing the worker pool
TCP RTO backoff kicks in across the fleetThe platform's perceived availability drops to zero even though the boxes are still alive

This is the classic bufferbloat failure mode applied to an identity pipeline. The verifier did not run out of CPU. It ran out of bounded behaviour.

The correct architectural posture is the inverse: every stage publishes a bounded queue, advertises its capacity headroom upstream, and rejects work it cannot service inside the latency contract. This is what Netflix codified as concurrency-limited admission control and what Envoy ships as the adaptive concurrency filter. The principle long predates them—it is the Reactive Manifesto made operational.

The three layers of verifier backpressure

A production identity verifier needs backpressure at three architectural layers. Each layer answers a different question and applies a different control primitive.

Layer 1: Per-tenant rate limiting (token bucket)

The first layer answers: is this caller within the rate they were sold? It is the classical token-bucket algorithm, applied per API key, per source IP, and per tenant. Tokens accrue at a configured rate; each accepted request consumes one. When the bucket is empty, the request is rejected with HTTP 429 and a Retry-After header conformant with RFC 6585 §4.

The bucket size sets the burstable allowance—the short window during which a caller can exceed their steady-state rate without being shed. A well-tuned bucket size for a verifier API is roughly one second of steady-state capacity, which absorbs the common case (a mobile app waking up from background and firing a session-restore flurry) without absorbing the pathological case (a script that bursts indefinitely).

Token-bucket state lives in a shared store visible to every edge worker. PasskeyBridge uses an atomic-counter primitive in PostgreSQL with row-level locking, fronted by a Cloudflare-Worker edge cache that absorbs the read load. The same pattern is described in Stripe's engineering writeup on rate limiting and the GitHub primary-rate-limit documentation.

What the token bucket does not do: it does not protect the verifier from a fleet of compliant callers whose aggregate compliant rate still exceeds verifier capacity. That is layer 2's job.

Layer 2: Adaptive admission control (concurrency-limited)

The second layer answers: can the verifier service this request inside its latency budget right now? It is a TCP-Vegas-style adaptive concurrency limiter that measures observed latency against the SLO and adjusts the in-flight ceiling on the fly.

The control loop is:

  1. Measure the rolling P99 of completed verifications over a short window (5 to 30 seconds).
  2. Compare against the configured SLO (PasskeyBridge runs an 80 ms P99 SLO at the public verifier).
  3. If P99 stays below 70% of SLO, raise the in-flight ceiling by an additive step.
  4. If P99 exceeds 100% of SLO, drop the ceiling multiplicatively.
  5. New requests above the current ceiling are rejected with 429 and Retry-After immediately, without entering the queue.

This is gradient feedback control, the same pattern Envoy's adaptive_concurrency filter and Netflix's concurrency-limits library implement. The behaviour under sudden 10x ingest is the operational point of the design: the ceiling collapses fast, P99 stays inside SLO, and the rejected requests fail loudly and cheaply rather than queueing into starvation.

The accompanying behaviour to design for is client-side jitter on retry. A Retry-After of "2 seconds" with no jitter produces a synchronized retry storm two seconds later. PasskeyBridge clients emit a jittered Retry-After (server-side advisory plus client-side randomization) and the PasskeyBridge SDK implements the equal-jitter backoff variant from the AWS Builders' Library by default.

Layer 3: Priority-aware load shedding

The third layer answers: given that we have to drop something, which traffic class do we drop first? It is the weighted-fair-queueing layer, and it is the layer that protects auth-critical flows.

PasskeyBridge defines four traffic classes, in descending priority:

ClassExamplesShed order
P0: Auth-criticalSession revocation, step-up challenge, CAEP security event pushNever shed; isolated worker pool
P1: Paying-tenant primaryLive login verification for a paid tenant under SLAShed only after all P2 and P3 traffic is dropped
P2: Paying-tenant secondaryBackfill, analytics queries, signal-replayShed under moderate load
P3: Free tier and unauthenticated probesTrial sign-ins, public playground trafficShed first

Under saturation, the shedder walks the classes in reverse order until measured P99 falls back inside SLO. The implementation primitive is a deficit round-robin scheduler, which guarantees each class its weighted share of capacity when capacity is sufficient and bounds starvation when it is not.

The dedicated P0 worker pool matters. If revocation pushes share the worker pool with public login traffic, a credential-stuffing wave can starve revocation—meaning a stolen session lives longer than it should. PasskeyBridge's revocation pipeline is isolated from public verification at the OS-process boundary: separate CPU shares, separate connection pool to the carrier-signal layer, separate Postgres connection slice. The cost is small (less than 5% of total capacity reserved for P0) and the property it preserves is non-negotiable.

The measured curve

The benefit of treating saturation as a designed-for regime is that the verifier's behaviour stays on a predictable curve all the way through 10x overload. Two measured curves drawn against the same overload event:

P99 latency (ms) vs ingest as multiple of capacity

          Unbounded buffering            Backpressured verifier
  3000 |                ·.·              |
       |              .'                 |
  2000 |            .'                   |
       |          .'                     |    SLO ceiling: 80 ms
  1000 |        .'                       |  __________________
       |     .'                          |
   500 |   .'                            |
   200 | .'                              |
    80 |·___________________________     |.____________________
       +---+---+---+---+---+---+---     +---+---+---+---+---+
        1x  2x  3x  5x  8x  10x          1x  2x  3x  5x  8x  10x

The backpressured curve stays inside the SLO ceiling at every load multiple. The cost is a rising 429 rate paid by the lowest-priority classes:

Ingest multipleBackpressured P99429 rate (P3)429 rate (P1)
1.0x32 ms0%0%
2.0x41 ms0%0%
3.0x58 ms8%0%
5.0x71 ms44%0%
8.0x79 ms78%6%
10.0x80 ms91%22%

P0 traffic—revocation, step-up, CAEP—sees zero shedding at every load level because it lives outside the shedder's reach. Paying-tenant primary traffic does not begin to feel pressure until ingest exceeds 5x capacity. That is the property the architecture is paid to produce.

The shape of the unbounded-buffer curve is documented across the cloud-providers' postmortem literature; the AWS retry-storm postmortem material in the Builders' Library and the Google SRE workbook chapter on overload both describe the same knee.

Wiring it into a verifier: The concrete topology

A verifier that implements all three layers looks like this from request edge to cryptographic core:

              ┌──────────────────────────┐
   client ───►│ Cloudflare edge          │  TLS termination, IP-rate limit (token bucket)
              └────────────┬─────────────┘
                           ▼
              ┌──────────────────────────┐
              │ API gateway              │  Tenant API-key token bucket, request classification (P0/P1/P2/P3)
              └────────────┬─────────────┘
                           ▼
              ┌──────────────────────────┐
              │ Adaptive admission ctl   │  In-flight concurrency limit, measured P99 vs SLO
              └────────────┬─────────────┘
                           ▼
              ┌──────────────────────────┐
              │ Weighted fair queue      │  Deficit round-robin across P0/P1/P2/P3
              └─────┬────────┬───────────┘
                    │P0      │P1/P2/P3
                    ▼        ▼
            ┌────────────┐ ┌────────────────────────┐
            │ Revocation │ │ Verification pool      │  Cryptographic workers, carrier-signal fanout
            │ worker pool│ └─────────┬──────────────┘
            └────────────┘           ▼
                              ┌──────────────┐
                              │ Downstream   │  Bounded connection pool, circuit breaker
                              │ RPC layer    │  (see article below)
                              └──────────────┘

Each arrow in that diagram is a backpressure boundary. The token bucket between the edge and the gateway sheds rate-non-compliant traffic before it reaches the gateway. The admission controller sheds latency-incompatible traffic before it reaches the fair queue. The fair queue isolates auth-critical traffic from public traffic. The downstream RPC layer carries a circuit breaker that opens before the carrier-signal API can drag the verifier down.

The circuit-breaker layer is the necessary partner pattern; we covered it in depth in Circuit Breakers for Identity Pipelines: Handling Carrier API Degradation. Backpressure protects the verifier from too much upstream traffic; the circuit breaker protects the verifier from too-slow downstream dependencies. They are complementary and a verifier that ships only one of them is half-instrumented.

SLO engineering: The number you defend

Backpressure without a defended SLO is busywork. The SLO is the contract that defines what "the verifier is healthy" means in measurable terms. PasskeyBridge's public verifier defends three numbers:

  • P99 verification latency ≤ 80 ms at the public edge, measured at the SDK
  • Availability ≥ 99.95% measured as the fraction of admitted requests that completed within SLO
  • Auth-critical (P0) shed rate = 0% measured as the fraction of P0 requests rejected with 429

The first number is what the admission controller's set point tracks. The second is what the error budget is computed against. The third is the inviolable property the architecture exists to preserve.

The budget framing matters because it converts the operational question from "can we tolerate any 429s?" (answer: of course not, every 429 is a customer mistake) into "what fraction of 429s, against which traffic class, is consistent with our SLO?" (answer: a measurable number we can defend in the post-incident review). The Google SRE workbook on SLO engineering is the canonical reference; we treat its prescriptions as load-bearing.

Failures when these patterns are skipped

A non-exhaustive list, drawn from publicly documented incidents and our own engagement post-mortems:

  1. HTTP/2 Rapid Reset class of attack, disclosed October 2023—The novel cancel-stream amplification documented jointly by Cloudflare, Google, and AWS drove single-edge peaks past 398 million requests per second. Any verifier sitting behind an HTTP/2 stack without explicit per-stream concurrency and admission control was structurally exposed.
  2. The Dyn DNS outage, October 2016—A Mirai-driven attack on a single managed-DNS provider cascaded into multi-hour authentication failures across dozens of consumer identity providers because their resolver path had no graceful degradation. Public retrospective and Cloudflare's Mirai analysis remain the canonical references.
  3. Verifier collapse under credential-stuffing campaign (anonymized customer, 2025)—A 12x burst against a tenant's login endpoint dragged the verifier's P99 to 11 seconds because rate limiting was per-IP but the attacker rotated through a 50,000-IP residential proxy pool. Layer 2 admission control would have shed the load inside 50 ms; the rate limiter could not.
  4. Free-tier abuse starving paid tenants (recurring pattern across the industry)—Without priority queues, a public-API abuse wave consumes the same worker pool that paying tenants depend on. The shed-load policy gap is the architectural defect; capacity is not the fix.

In each case, more hardware does not fix it. The fix is to acknowledge explicitly that the verifier is a queueing system, and that queueing-system theory applies to it whether the operator believes in it or not.

The PasskeyBridge implementation

PasskeyBridge runs the three-layer pattern in production with the following concrete primitives:

  • Layer 1 (token bucket)—Cloudflare Workers token-bucket at the edge for IP-class rate limiting; PostgreSQL atomic-counter token-bucket per API key inside the Edge Function layer for tenant-class rate limiting.
  • Layer 2 (adaptive admission)—Deno-native concurrency-limiter ported from the Netflix concurrency-limits library, running inside the api-gateway Edge Function. SLO setpoint tracks rolling P99 over a 15-second window.
  • Layer 3 (priority lanes)—Per-traffic-class worker pools at the Edge Function deployment level. P0 (revocation, step-up, CAEP push) runs in its own dedicated function with its own connection slice to the database; P1–P3 share a fair-queued pool whose weights are configurable per environment.

The numbers we defend publicly: 80 ms P99 at the verifier edge, 99.95% availability at the SLO, zero P0 shed rate. They are visible on the public status page and the API playground lets developers drive a 10-request burst against the live /health endpoint and read back P50/P95/P99 themselves.

The architecture exists because we accept the premise: every verifier eventually meets a 10x day. The ones that survive it without taking the customer down are the ones that planned for it in the topology, not in the runbook.

Reading for 2026

Identity verification is, structurally, a high-fanout, low-latency, multi-tenant queueing system whose worst day is reliably 10x its average day. The systems-design literature for that problem class has been settled for over a decade—Little's Law, weighted fair queueing, adaptive concurrency control, error-budget-based SLO engineering. What has changed in 2026 is that the threat environment now reliably produces the 10x day. The Cloudflare HTTP/2 Rapid Reset disclosure, the credential-stuffing-as-a-service market, and the carrier-signal probe storms that follow every public CVE disclosure have moved the 10x event from "rare" to "monthly."

The verifier architectures that will not embarrass their operators in 2027 are the ones that already treat the 10x event as a designed-for regime. Bounded queues. Adaptive concurrency limits. Priority lanes that isolate auth-critical traffic. A defended P99 SLO. A measurable shed-rate that the operator can point at and say: this is the contract. For a verifier that calls itself enterprise, that list is the baseline.

The patterns are public. The math is non-negotiable. The engineering has to match.

---

Further reading:

Start free · Test the API