Loading...
āœ“

12-Hour Money-Back Guarantee

šŸ“˜ Backpressure & Load Shedding

šŸ“˜ Backpressure & Load Shedding

šŸ“˜ Backpressure & Load Shedding

3 Apr 20223 min read

How Healthy Systems Say ā€œNoā€ to Stay Alive

Systems don’t fail because they get traffic.
They fail because they accept too much traffic.

The Core Problem: Unbounded Demand

What Most Systems Do āŒ

  • Accept all requests

  • Queue indefinitely

  • Let latency explode

  • Die under their own queues

Queues are not backpressure. Queues are deferred failure.

What Is Backpressure?

Backpressure is the ability of a system to slow down or stop upstream traffic when it is overloaded.

It answers:

ā€œI am unhealthy — please send me less.ā€

What Is Load Shedding?

Load shedding is intentionally dropping requests to protect the system.

It answers:

ā€œI cannot handle this request — fail fast.ā€

Why This Matters (Tail Latency Link)

When load > capacity:

  • Queues grow

  • Context switches explode

  • GC pressure rises

  • P99 goes to infinity

Protecting P99 requires rejecting work.

🧩 Failure Mode — No Backpressure

āŒ Naive Server

app.get("/data", async (req, res) => {
  const result = await db.fetch();
  res.send(result);
});

What Happens

  • DB slows

  • Requests pile up

  • Memory explodes

  • Process crashes

🧩 Solution 1 — Backpressure via Concurrency Limits

āœ… Semaphore-Based Control

import pLimit from "p-limit";

const limit = pLimit(100); // max 100 concurrent

app.get("/data", async (req, res) => {
  try {
    const result = await limit(() => db.fetch());
    res.send(result);
  } catch {
    res.status(503).send("Overloaded");
  }
});

Why This Works

āœ” Caps resource usage
āœ” Prevents queue explosion
āœ” Stabilizes latency

🧩 Solution 2 — Load Shedding (Fail Fast)

āœ… Reject Excess Traffic

let inFlight = 0;
const MAX = 200;

app.get("/data", async (req, res) => {
  if (inFlight > MAX) {
    return res.status(429).send("Too Busy");
  }

  inFlight++;
  try {
    res.send(await db.fetch());
  } finally {
    inFlight--;
  }
});

Key Insight

A fast failure is better than a slow success.

🧩 Solution 3 — Adaptive Load Shedding

Shed Based on Latency

let shed = false;

setInterval(() => {
  shed = metrics.p99 > 500;
}, 1000);

app.get("/data", async (req, res) => {
  if (shed) return res.status(503).send("Degraded");
  res.send(await db.fetch());
});

āœ” Protects P99
āœ” Self-healing
āœ” Production-grade

🧩 Solution 4 — Priority-Based Load Shedding ⭐

Idea

Not all requests are equal.

āœ… Code

app.get("/data", async (req, res) => {
  if (overloaded && req.headers["x-priority"] !== "high") {
    return res.status(503).send("Shed");
  }
  res.send(await db.fetch());
});

āœ” Premium users survive
āœ” Internal traffic survives
āœ” Graceful degradation

🧩 Solution 5 — Queue with Backpressure (Correct Way)

Queues must be bounded.

āŒ Bad Queue

  • Infinite size

  • Hides overload

āœ… Good Queue

const queue = [];
const MAX_QUEUE = 1000;

function enqueue(req) {
  if (queue.length >= MAX_QUEUE) {
    throw new Error("Queue Full");
  }
  queue.push(req);
}

🧠 Backpressure vs Load Shedding

Aspect Backpressure Load Shedding
Goal Slow traffic Drop traffic
User impact Delay Failure
Latency Controlled Minimal
Complexity Medium Low

Healthy systems use both.