Skip to content

Only one percent of packets are lost. Why did API p99 explode?

The Network Was Up. The Requests Were Not. · Part 2 of 6 · 5 min read

Read the worked explanation ↓

Interview question. A payment API is normally around 80 ms at p50 and 300 ms at p99. After a network change, its cross-region clients report p99 above two seconds. Hosts are not CPU-bound, the backend traces look healthy, and packet loss on one path averages one percent. Someone argues that losing one packet in a hundred cannot explain a tenfold slowdown. Do you agree?

Not without knowing which packets are lost and how each TCP connection recovers. A one-percent average is not a one-percent tax on response time. TCP delivers an ordered byte stream. When bytes in the middle are missing, the receiver cannot deliver later bytes past the gap to the application as one contiguous stream, even if many later segments have already arrived.

Think of a response carried in 60 full-sized TCP data segments. Under an illustrative independent one-percent packet-loss model, the probability of at least one lost segment is 1 - 0.99^60, about 45 percent. That is a rough model, not an estimate of real user error rates. Real losses are often correlated, not independent. Still, it illustrates why a small per-packet loss fraction can affect a much larger fraction of responses.

The delay incurred depends on recovery, not just loss frequency.

A missing TCP segment holds back ordered application delivery while later segments arrive, followed by fast recovery or a retransmission timeout.
A missing TCP segment holds back ordered application delivery while later segments arrive, followed by fast recovery or a retransmission timeout.
Think first

An API handles 2 KB requests and 400 KB responses. Cross-zone p99 doubles only for the larger response, while average interface loss is below one percent. Explain the likely transport interactions, how you would measure them and what evidence would rule out packet loss as the cause.

Take a few minutes to form an approach, then compare it with the worked explanation.

Check the exercise numbers

With an illustrative 1,460-byte TCP payload, a decimal 400 KB response needs about 274 segments versus two for a 2 KB request, ignoring TLS and other framing. Under an independent per-segment loss probability p, the chance of at least one lost response segment is 1 − (1 − p)^274. At 1% as a comparison point this is about 93.6%, but the exercise specifies only loss below 1%, not an exact p or an independent loss pattern. These inputs cannot uniquely predict p99 or prove that loss caused the slowdown.

Reveal the worked explanation

What happens after one gap

If enough later packets arrive, the receiver can signal a hole through duplicate acknowledgments and selective ACK information. In classic fast retransmit behavior, the sender can resend a segment before its retransmission timer fires. Modern stacks have more sophisticated loss detection, but the useful idea is the same: the sender needs evidence that something did not arrive.

A small request or short response may not provide that evidence quickly. Suppose the final segment of a response disappears. There may be no later data segments to generate duplicate acknowledgments. The connection might sit waiting for a timer-based recovery. RFC 6298 describes an initial retransmission timeout of one second before RTT measurements under its standard algorithm, while real implementations and established connections can have different adaptive timers. I would not claim every lost packet adds exactly one second.

Congestion control matters too. TCP generally treats inferred loss as a possible congestion signal. Depending on the implementation and controller, the sender can reduce its permitted in-flight data or adjust its pacing, which hurts throughput beyond the retransmitted packet itself. A long-lived cross-region connection can recover and then spend time rebuilding its sending rate. That's why the effect of loss depends on RTT, congestion-control algorithm, burstiness and connection lifetime.

Do not confuse that with the head-of-line blocking discussion from HTTP/2 versus HTTP/3. Here the first-order issue is TCP's ordered-stream recovery within a connection. If multiple application streams share that TCP connection, missing transport bytes can affect unrelated streams too. QUIC can avoid cross-stream head-of-line blocking, but its lost packets still need recovery and the network path can still be congested.

Why the backend trace looks normal

A server span often begins when the application receives a complete request. Missing packets during TLS setup, request delivery or a stalled response might not be included in that span. The server can finish its computation in 30 ms while the client waits through retransmissions or a connection timeout. Looking only at downstream service duration would falsely clear the network.

I would compare client-observed durations with server spans and correlate failures by source region, egress gateway, address family, connection reuse and route. On controlled hosts, I would inspect TCP retransmission counters and per-socket RTT/RTO state, selective-ACK behavior, connection resets and packet traces. In cloud networks, traces on both sides of a path can help locate where sequence numbers disappear, but capture itself must respect traffic and privacy policies.

The symptom may also come from packet reordering, policers, congestion, MTU problems or a flaky middlebox. Retransmission counters alone do not prove physical packet loss. Capture on both ends and inspect what was sent, what arrived, and what the sender inferred. An average interface drop percentage cannot answer which client requests suffered.

Repair the path, then reconsider the timeout budget

For this scenario I would first isolate the affected route, compare it with a healthy path under similar load, and work with the network owner to investigate queue drops, interface errors, routing asymmetry, traffic shaping and link congestion. If one regional path is unhealthy, route around it deliberately with capacity and retry limits. Do not let an emergency failover stampede the supposedly healthy path.

Client changes can help, but they need judgment. Persistent connections avoid repeated handshakes, and request concurrency can help hide delay for independent operations. Neither repairs data loss. Making every request timeout at 100 ms might reduce waiting but increase retries and payment ambiguity. Retrying a payment on a new connection may duplicate a side effect unless the application has an idempotency contract. Here the design decision is to distinguish transport recovery time from the business action's completion semantics.

I would monitor connection-establishment latency, retransmissions per path, TCP RTT distribution, client completion time and the ratio between client and server latency. The acceptance test would include small versus large payloads and warmed versus new connections, because their loss-recovery patterns differ.

One percent packet loss is not harmless or universally catastrophic. It can be almost invisible for some requests and dominate others. What matters is which packets are missing, how quickly the sender recognizes the gap, how congestion state reacts, and how long the application can wait.

Go deeper

RFC 5681 specifies classic slow start, congestion avoidance, fast retransmit and recovery, while RFC 6298 describes the retransmission timer. SACK lets a receiver report discontiguous received blocks so the sender need not blindly resend everything after a gap. TCP RACK and tail-loss probes, available in modern implementations, change recovery behavior relative to naive duplicate-ACK examples. The independent-loss probability assumes each of 60 packets has independent one-percent loss and is illustrative only. Real-world correlated bursts, ACK loss, reorder and middlebox behavior require path-level measurements.

Check your reasoning

  • Explain that a response with many segments has a higher chance of experiencing some loss.
  • Differentiate duplicate ACK/SACK-based recovery from retransmission timers.
  • Describe ordered byte delivery and possible congestion-control reaction.
  • Use both client timing and transport traces to locate path-specific failures.
  • Avoid conflating transport retries with safe business operation retries.

Common mistake: A one-percent packet-loss rate can delay no more than one percent of multi-segment responses.

How should you investigate high client p99 when packet loss is low on average and server spans look healthy?

Read the answer explanation

Trace lost TCP bytes and recovery timing by path and payload size — Multi-segment responses and loss-recovery delays can inflate p99 even when server application spans are short.

Apply it elsewhere

A livestream control connection and high-volume media transport traverse the same congested edge. Design traffic-priority, admission and network monitoring policies that protect control latency without claiming that switching protocols automatically cures congestion.

Compare your approach

Distinguish packet loss rate from request-impact probability, explain ordered delivery and loss recovery, identify timer and congestion-window effects, use end-to-end evidence and avoid unsafe blanket retries.

One more constraint

If one percent of individual segments are lost, is it correct to say at most one percent of multi-segment responses experience loss-related delay?

Quick revision

A small packet-loss percentage can affect many multi-segment requests. For 60 independent segments at one-percent loss each, almost 45 percent of responses would contain at least one lost segment in the simplified model. TCP must recover missing ordered bytes, sometimes through duplicate ACKs and SACK, sometimes through timers, and congestion control may reduce sending rate. The resulting delay appears at the client even when application spans look fast. Diagnose the path and recovery behavior before changing timeouts or switching protocols.

References