Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 62

Minimizing Tail Latency in Distributed Systems

Recommended resources

Introduction

In our last lesson, we constructed a blueprint for high-performance systems by designing multi-layer caching architectures. Our focus was on drastically improving the average- and median-case latency by serving data from progressively faster storage tiers. However, in large-scale distributed systems like those at Google, user experience isn't defined by the average case. It's often determined by the outliers—the frustratingly slow requests that make a service feel unreliable.

This lesson directly addresses that challenge, focusing on the learning outcome: Explain techniques for reducing tail latency in distributed systems, such as speculative requests and request hedging. We will move beyond averages and percentiles like P50 to dissect the P99 and P99.9 latencies. You will learn why these "tail" events become common at scale and analyze the seminal Google techniques designed specifically to mitigate them. This is a crucial topic for anyone aspiring to a Principal Engineer role, as it involves optimizing for the worst-case scenarios that define a system's predictability and reliability.


The Nature of Tail Latency

Before we can "tame the tail," we must first understand what it is and why it's so pernicious in distributed environments. While we often talk about "average latency," this metric can be dangerously misleading. A system can have a fantastic average response time while a small but significant fraction of users experience extreme delays.

To get a precise definition of tail latency and understand how it's measured using percentiles, the following segment from a university lecture on distributed systems provides an excellent conceptual foundation.

CSE138 (Distributed Systems) L14: Dynamo: Merkle trees, quorum consistency, tail latency

This video excerpt from a course by Professor Lindsey Kuper clearly explains what tail latency is, why average latency is an insufficient metric, and how percentiles (like P99.9) are used to characterize the performance of the slowest requests.

Please watch the segment from "tail latency". Pay attention to the visual explanation of the latency distribution curve and the distinction between the average and the 99.9th percentile.

As Professor Kuper explained, tail latency refers to the performance of the slowest fraction of requests. But why is this so critical at Google's scale? The reason is a phenomenon of amplification. When a single user request fans out to hundreds or thousands of independent services or shards—a common pattern in systems like Google Search or Bigtable—the overall latency is dictated by the slowest of those sub-requests.

The following blog post provides a brilliantly concise mathematical illustration of this effect.

Implementing The Tail at Scale in Golang | Jitesh's Blog

This article breaks down the core problem discussed in the famous "Tail at Scale" paper. It crystallizes the issue of tail latency amplification with a simple probability calculation.

Please read the first part of the article, from the beginning down to the end of the section "3. Even tiny tail probabilities blow up at scale." Focus on the example where a 99% chance of a fast reply from a single server results in only a 36% chance of a fast overall response when querying 100 servers. Read from the beginning.

This simple calculation () is profound. It demonstrates that even with highly reliable individual components, the probability of a slow user-facing request becomes the norm, not the exception.

The sources of this variability are numerous, especially in the shared, multi-tenant data centers that Google operates. In the following talk, Google Senior Fellow Jeff Dean—co-author of the "Tail at Scale" paper—explains the real-world causes of this unpredictable performance.

Taming Latency Variability and Scaling Deep Learning, by Jeff Dean, Google, 20131016

In this clip from a 2013 talk, Jeff Dean describes the challenges of latency variability in Google's production environment, where interactive jobs and batch computations coexist.

Watch from this segment on the downside of shared environments. He discusses factors like network congestion, background daemons, and interference from other jobs ("noisy neighbors") that contribute to the long tail.


The Primary Technique: Hedged Requests

Now that we've established the problem, let's analyze the solution. Since we can't eliminate all sources of latency variability, we must design systems that are tolerant of it. The most well-known technique for this is the hedged request, also known as a speculative request.

The core idea is simple: if you don't hear back from the first server you sent a request to within a certain time, you send a second, identical "hedge" request to another replica. You then take whichever response comes back first and cancel the other.

This diagram illustrates the hedged request pattern. A primary request is sent to a replica. After a short, predetermined delay, a secondary "hedge" request is sent to another replica. The client uses the first response it receives, mitigating the risk of the primary replica being a slow "straggler."

The crucial design parameter is the delay before sending the hedge request. Sending it immediately would double the load on the system. Sending it too late defeats the purpose. The common practice, as pioneered by Google, is to wait for a duration that corresponds to a high percentile of the expected latency distribution, such as the 95th percentile (P95).

As this diagram shows, the hedged request is triggered only after waiting for a period longer than the P95 latency. This ensures that the extra load from hedge requests is only incurred for the small fraction of requests that are genuinely slow, striking a balance between latency reduction and system load.

The following summary of "The Tail at Scale" paper formalizes this.

The Tail at Scale - by Indrajit Bhosale

This section of the article succinctly describes the mechanics of hedged requests and the rationale for the delay.

Please read the paragraph explaining the concept. Note the key detail: "By delaying the secondary request until the first request has been outstanding for longer than the 95th percentile expected latency, the additional load is limited to around 5% while substantially shortening the latency tail."


A Refinement: Tied Requests (Backup Requests with Cancellation)

Hedged requests are powerful, but they can be refined. A variation known as tied requests aims to reduce the redundant work done by replicas even further. In this model, requests are sent to multiple replicas nearly simultaneously, but each replica is made aware of the others processing the same request. As soon as one replica begins actual work (e.g., starts a disk read), it sends a cancellation message to the others.

Jeff Dean describes this advanced implementation in his talk, calling it "backup requests with cross-server cancellation." Watching this segment will give you a direct view into the engineering details and performance results of this technique as implemented at Google.

Taming Latency Variability and Scaling Deep Learning, by Jeff Dean, Google, 20131016

This is the most critical part of the talk, where Jeff Dean details the mechanics of tied requests and presents experimental data showing their dramatic impact on tail latency.

Watch the segment from "Tolerating Latency Variability". He explains the analogy to fault tolerance, describes the protocol with diagrams, and shows graphs comparing latency distributions with and without the technique, both on an idle cluster and a heavily loaded one. The results are striking.

The key takeaways from his explanation are:

  • Minimal Overhead: The technique adds only about 1% extra disk reads for a nearly 70% reduction in P99.9 latency under load.
  • Free Throughput: An interactive job running on a heavily loaded cluster with backup requests achieves the same tail latency as the same job running on a completely idle cluster without them. This essentially allows you to run large batch jobs "for free" without impacting the interactive user experience.
  • Network Dependency: The effectiveness of the cancellation message depends on low network latency, a trend that works in this technique's favor as data center networks get faster.

Broader Strategies for Tail Latency Reduction

While hedged and tied requests are a cornerstone of tail latency tolerance, they are part of a broader family of techniques. A Principal Engineer should be aware of the entire toolkit. The Golang blog post you read earlier also provides a good summary of other strategies mentioned in the "Tail at Scale" paper.

Here are some of the other important patterns:

  • Micro-partitioning: Instead of having a few large data shards, create many small ones. This improves load balancing and makes it easier to re-route work around a single slow shard.
  • Tail-Aware Load Balancing: Move beyond simple round-robin. Track the recent performance of replicas, including their P99 latency, and route requests to replicas that are consistently performing well. The "Power of Two Random Choices" is a simple but effective strategy here: pick two random replicas and send the request to the one with the lower load.
  • SLA-aware Admission Control: When a system approaches overload, it should start shedding or throttling low-priority requests to protect the latency of high-priority ones. This prevents a catastrophic failure spiral where high latency leads to more retries and even higher load.
  • Request Slicing: Break very large requests into smaller, independent pieces that can be executed in parallel and speculatively retried individually.

These techniques, combined with hedged requests, form a powerful defense-in-depth against the unpredictable performance that is inherent to large-scale distributed systems.


Conclusion

In this lesson, we delved into the critical challenge of tail latency. We established that in systems with high fan-out, optimizing for the average case is insufficient; the user-perceived performance is dictated by the slowest outliers.

Here are the key takeaways:

  • Tail Latency Dominates at Scale: Due to statistical amplification, rare slowdowns in individual components become common events for user-facing requests that touch hundreds of machines. P99 and P99.9 latency, not the average, become the defining metrics for user experience.
  • Hedged Requests are the Core Solution: By sending a speculative-retry (a "hedge" request) after a P95-latency delay, systems can dramatically cut down tail latency. This trades a small, controlled increase in load (around 5%) for significant improvements in predictability.
  • Tied Requests Offer Refinement: The "backup request with cross-server cancellation" pattern is a more advanced form that minimizes redundant work by having replicas communicate to cancel duplicate efforts, further reducing overhead.
  • It's a Holistic Approach: Taming the tail requires a suite of techniques, including intelligent load balancing, fine-grained partitioning, and proactive load shedding, in addition to speculative execution.

In our next lesson, we will shift our focus back to the data layer to address another fundamental aspect of performance. We will analyze local versus global secondary indexing approaches and their performance trade-offs, exploring how the choice of indexing strategy impacts query latency and system scalability in distributed databases.