Representative interview topic

Backend interview: How would you design QUIC migration and safe 0-RTT use?

BackendHard
Offer.cc Editorial TeamPublished Updated

Question

A mobile client switches between Wi-Fi and cellular. How do you preserve its QUIC connection while preventing 0-RTT replay from duplicating writes, and how do you design validation, routing, monitoring, and TCP fallback?

Prompt and context

A mobile client switches between Wi-Fi and cellular. How do you preserve its QUIC connection while preventing 0-RTT replay from duplicating writes, and how do you design validation, routing, monitoring, and TCP fallback?

This fits backend, networking, edge, and platform roles. QUIC separates connection identity from the UDP four-tuple with connection IDs, so an address change can trigger migration; RFC 9001 states that 0-RTT lacks full replay protection. The design must turn those protocol constraints into server state, idempotent APIs, and deployment controls.

What the interviewer is testing

  • Distinguish connection IDs, paths, address validation, and when migration is allowed.
  • Know that an endpoint cannot actively migrate before handshake confirmation and explain PATHCHALLENGE and PATHRESPONSE.
  • Restrict 0-RTT to replay-safe requests instead of allowing arbitrary writes.
  • Consider load balancers, connection-ID routing, key rotation, and state sharing.
  • Design fallback for blocked UDP, NAT rebinding, loss, and failed migration.
  • Prove migration with metrics beyond handshake success rate.

30-second answer framework

“I use the connection ID as the connection identity. When a new source address appears, I validate the path before switching transmission; no active migration occurs before handshake confirmation. I classify 0-RTT by replay risk, allowing idempotent reads or writes protected by an idempotency key, and keep an anti-replay window. The edge routes by connection ID and rotates identifiers. I monitor migration, validation, rebinding, and fallback, and use HTTP/2 or HTTP/1.1 when UDP is unavailable.”

Step-by-step deep dive

Step 1: Separate connection from path

TCP commonly identifies a connection by an address-and-port four-tuple. QUIC uses a connection ID, so a source-address change need not create a new connection. A server must not treat packets from a new path as trusted immediately; validate the path before sending application data and handle NAT rebinding and temporary interface changes.

Step 2: Build the path-validation state machine

While the old path carries traffic, send PATHCHALLENGE on the candidate path and wait for PATHRESPONSE. Track a token, send time, validation state, and failure count for each candidate. A timeout should not immediately destroy the connection. Before and after migration, respect congestion control and anti-amplification limits so an unvalidated address cannot be used to amplify traffic.

Step 3: Handle connection IDs and load balancing

An edge load balancer needs stable backend routing from the connection ID, or a verifiable routing token that forwards the connection to a node holding its state. The server must issue, retire, and rotate IDs according to the protocol, avoiding topology leakage and unbounded validity. Define whether state, tokens, and keys are shared; a single-node memory design cannot safely support arbitrary migration.

Step 4: Set the 0-RTT business boundary

An attacker may replay 0-RTT data, so a server cannot treat it as proof of one-time execution. Accept idempotent GETs or safely retryable requests by default. If a write is required, use a client-generated idempotency key, a time window, and account and resource constraints, then deduplicate atomically. Payment, inventory, and entitlement side effects should wait for 1-RTT confirmation.

Step 5: Observe migration and failure paths

Record a connection ID, privacy-safe summaries of old and new paths, validation time, migration success, NAT rebinding, loss, congestion window, 0-RTT acceptance and rejection, duplicate hits, and fallback reasons. Do not log full addresses or sensitive tokens; use hashes or buckets. Alerts should distinguish client network changes, server validation failures, routing errors, and blocked UDP.

Step 6: Establish fallback and canarying

An HTTP/3 client should try a TCP version when QUIC setup fails, UDP is blocked, or path validation repeatedly fails. Canary by region, client version, and edge node, comparing migration success, p99 latency, CPU, loss, and duplicate business writes. Fallback must not execute one request once over HTTP/3 and again over HTTP/2; application-level idempotency remains required.

Trade-offs, boundaries, and information gain

QUIC migration improves mobile-network continuity but adds path state, routing, anti-amplification, and observability complexity. 0-RTT reduces first-byte waiting while weakening replay guarantees. A strong design carries the protocol-level possibility of duplication into the business layer through idempotency and audit, while retaining a reliable TCP fallback.

Model high-quality answer

“I identify the connection with a connection ID rather than the UDP four-tuple. A new source address enters a candidate-path state; I send PATHCHALLENGE, validate PATHRESPONSE, then switch the sending path while respecting congestion and anti-amplification limits. The load balancer routes by connection ID or forwards to a shared state boundary, and IDs support rotation and retirement.

0-RTT has no full replay protection, so I allow only idempotent reads or safe requests carrying a time-bound idempotency key. Payment, inventory, and entitlement writes wait for 1-RTT; the server atomically records keys and audits duplicate hits. Metrics cover validation time, migration success, NAT rebinding, 0-RTT acceptance, duplicates, and fallback reasons.

I canary by client, region, and edge node, fall back to HTTP/2 or HTTP/1.1 when QUIC fails, and preserve application idempotency so the same side effect is not executed on both protocol paths.”

Common mistakes

  • Switching immediately on a new address → the path is unvalidated → complete PATHCHALLENGE and PATHRESPONSE first.
  • Treating 0-RTT as one-time execution → data can be replayed → restrict methods and use a key and time window.
  • Keeping state only in one node's memory → migration to another node fails → design connection-ID routing or shared state.
  • Ignoring anti-amplification → an unvalidated address can be abused → respect validation and sending limits.
  • Monitoring handshake only → migration, rebinding, and fallback failures stay hidden → measure the full lifecycle.
  • Repeating a write during fallback → HTTP/3 and HTTP/2 may both arrive → use the same business idempotency key.

Follow-up questions and answers

Why cannot an endpoint actively migrate before handshake confirmation?

RFC 9000 forbids active migration before handshake confirmation while keys and path trust are still being established. Complete the handshake, then switch according to path validation state.

How does NAT rebinding differ from active migration?

NAT rebinding changes a mapping outside the endpoint, so it may continue with the same connection ID. Active migration intentionally changes an address or interface. Both validate a new path, but their triggers and telemetry labels differ.

When is a 0-RTT write safe?

Only when repetition cannot change the final result or the server atomically deduplicates it with an idempotency key, resource version, and time window. Irreversible side effects wait for 1-RTT; a TLS ticket is not business authorization.

What if an enterprise network blocks UDP?

Fall back to HTTP/2 or HTTP/1.1 while preserving authentication, idempotency, and timeout semantics. Track fallback by region and client so UDP blocking is not mistaken for a server outage.

Public sources

Related questions