Day 19: Handle High Concurrency with Connection Pools and Backpressure — and Prevent Resource Exhaustion

Distributed Key Value Store : DurableKV ~7 min read 60 min hands-on

Day 19: Handle High Concurrency with Connection Pools and Backpressure

In Day 18, we built a functional, single-node storage engine for DurableKV that handles basic read and write operations. It works perfectly when a single client issues sequential requests. However, if we expose that implementation directly to the network under production-level concurrency, it will quickly fall apart.

Today, we will address the most common cause of high-concurrency service degradation: resource exhaustion. You will learn how to protect DurableKV from incoming traffic spikes using connection pooling and explicit backpressure. By the end of this lesson, you will have implemented a concurrency-limiting middleware that sheds load gracefully under pressure, keeping p99 latencies stable while preventing Out-of-Memory (OOM) crashes.


The Production Stakes: The Cassandra Mutation Queue Catastrophe

In distributed databases, accepting every incoming request as soon as it arrives is a recipe for catastrophic failure. A classic example of this occurs in Apache Cassandra deployments. Cassandra uses a Staged Event-Driven Architecture (SEDA), where different stages of request processing (reading, writing, replication) communicate via internal queues.

Under a massive write spike, if the incoming mutation stage accepts requests faster than the storage engine can write them to disk (SSTables), these internal queues grow without bound. In the JVM, millions of queued mutation objects consume massive amounts of heap memory. This triggers stop-the-world Garbage Collection (GC) pauses. During these pauses, the node cannot heartbeat, leading other nodes in the cluster to mark it as dead. This routes even more traffic to the remaining healthy nodes, triggering a cascading, cluster-wide OOM collapse.

To survive, a system must practice load shedding and backpressure: it must know when to say "no" to protect its own health.


The Intuition: The Bouncer and the Lobby

Imagine a popular restaurant with a dining room that holds exactly 50 people (our worker pool).

If the restaurant has no lobby and no front door controls, hundreds of customers will crowd inside, standing over dining tables, shouting orders, and overwhelming the kitchen. Service times spike to hours, and the kitchen eventually runs out of ingredients and shuts down.

To fix this, we introduce two mechanisms:

  1. The Lobby (Bounded Queue): A waiting area that holds exactly 10 people. If the dining room is full, waiting customers stand here.

  2. The Bouncer (Backpressure/Load Shedding): If both the dining room and the lobby are full, the bouncer stands at the door and immediately tells new arrivals, "We are at capacity. Please try again later."

This is fail-fast backpressure. It is far better to tell a client immediately that you cannot serve them (allowing them to retry elsewhere or back off) than to accept their request, hold their connection open, consume memory, and fail minutes later due to a timeout or crash.


Component Architecture

To protect our key-value engine, we insert a concurrency coordinator between our raw TCP listener and our storage engine execution path.

Code

When a request arrives:

Keep going with the full lesson

The rest of this lesson — plus its implementation guide, runnable scripts and source code — is included with the course or an All Access plan. Create a free account to start the free lessons in every course.

Already a member? Sign in