Have you ever wondered when one service calls to another service and you get no response back? its hard to tell of the other side is slow , dead or message got lost. These are 4 techniques how systems cope.

I give you what these terms are with analogy and the CS term as well for better understand.

Timeouts

Analogy: You call a restaurant and it just rings. Eventually you hang up instead of waiting forever.

In CS: A timeout is the maximum time a client waits for a response before treating the request as failed. Without one, stuck requests hold threads and connections until the caller runs out of resources, and one slow service drags down everything that depends on it. Note that a timeout doesn’t mean the work didn’t happen; the server may have finished and the reply got lost.

Retries

Analogy: You hung up, so you call again. Often someone picks up the second time.

In CS: A retry re-sends a failed request, which turns transient failures (dropped packets, restarting servers) into successes. Two cautions: only retry idempotent operations (or use an idempotency key), or you might charge a card twice; and cap attempts, because retries add load to a service that may already be struggling.

Exponential backoff

Analogy: You don’t hit redial every second. You wait one minute, then five, then fifteen.

In CS: Backoff is the wait between retries, usually doubling each time up to a cap: delay = min(cap, base * 2^attempt), e.g. 100 ms, 200 ms, 400 ms, 800 ms. Short blips get retried quickly, while real outages get breathing room to recover.

Jitter

Analogy: When a concert ends, 20,000 people rushing one exit at once jams it. Staggered, they all get through.

In CS: If thousands of clients fail together and use the same backoff, they retry in synchronized waves that knock the recovering server down again: the thundering herd. Jitter adds randomness to each delay so retries spread out. Full jitter, sleep = random(0, backoff), is a solid default.

Putting it together

Wait a limited time, retry a few times, wait longer between tries, and randomize the wait.

In code, the whole pattern fits in a few lines. Here’s a TypeScript sketch:

const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

async function fetchWithRetries(
  url: string,
  { maxAttempts = 4, baseMs = 100, capMs = 10_000, timeoutMs = 2_000 } = {}
): Promise<Response> {
  for (let attempt = 0; ; attempt++) {
    try {
      const res = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) }); // 1. timeout
      if (res.status !== 429 && res.status < 500) return res; // success or non-retryable error
      throw new Error(`Retryable status ${res.status}`);
    } catch (err) {
      if (attempt >= maxAttempts - 1) throw err;              // give up eventually
      const backoff = Math.min(capMs, baseMs * 2 ** attempt); // 3. exponential backoff
      await sleep(Math.random() * backoff);                   // 4. full jitter
      // 2. loop around and retry
    }
  }
}