← All articles
technologysoftwarereliabilityarchitectureSeptember 17, 20263 min read

When a Service Is Down, Stop Calling It. Waiting in Line Kills Everything Else

By the BrainSnail editorial team. How these articles are written and checked, and how to tell us when one is wrong.

Software borrowed the idea of a trip switch, so that a component which keeps failing is cut off deliberately rather than being called again by every request that arrives.

The failure being prevented

When one service calls another that has become slow or unresponsive, each call waits for a timeout before giving up. Requests arriving meanwhile pile up waiting for the same thing, each holding a thread, a connection and memory, until the calling service exhausts its own resources and stops responding to anything at all. Its own callers then queue up behind it. A fault in one unimportant component therefore takes down an entire system, one layer at a time, and the collapse is faster than any human response.

How the mechanism works

The pattern borrows both the name and the behaviour from electrical protection:

  • Failures against a dependency are counted over a recent window
  • Past a threshold, the switch opens and calls stop being attempted
  • Callers get an immediate failure instead of a long wait
  • After a cooling period, a single trial call is allowed through
  • If it succeeds, normal operation resumes
  • If it fails, the switch opens again and the wait restarts

Why failing fast is better

Refusing to try looks like giving up and is the opposite. An immediate failure returns the caller's resources at once, so the calling service stays healthy and continues serving everything that does not depend on the broken component. It also stops the struggling dependency being hammered by retries at exactly the moment it is trying to recover, which is frequently what prevents recovery in the first place. And it converts an ambiguous slow failure, which is the hardest kind to diagnose, into an explicit and immediate one that monitoring can see.

The settings that have to be chosen

Every number in the design is a judgement and getting one wrong makes the mechanism worse than nothing. A threshold set too low opens the switch during ordinary transient errors and cuts off a service that was working. Set too high it never opens and provides no protection. A cooling period that is too short hammers a recovering dependency with trial calls, and one that is too long leaves a feature broken after the fault is fixed. Rates work better than raw counts, because ten failures out of ten thousand calls is very different from ten out of twelve.

What to do instead of the call

Opening the switch is only half the design, since something must happen in place of the call, and that is where most of the thought goes. A cached previous answer may be good enough, particularly for data that changes slowly. A default value may be acceptable, such as showing a generic list where a personalised one is unavailable. The feature may be hidden entirely, degrading the page rather than breaking it. Or the request may be queued for later where the operation is not needed immediately. What is never acceptable is a stack trace reaching a user.

The takeaway

Calls to a slow dependency pile up holding resources until the caller collapses and its own callers follow, so counting recent failures and then refusing to try at all keeps the caller healthy. A single trial call after a cooling period tests whether to resume. Refusing also stops retries hammering a dependency trying to recover, and something sensible must be returned instead.

Practise this

Questions from Software

Reading about something is not the same as being able to recall it. These are real questions from the Software unit in our Technology track, answers and explanations included. The unit has 118 in total across 23 steps.

  • Type the answerLevel 5

    1. Version numbers written as major.minor.patch, like 3.4.1, use a naming scheme called ____ versioning.

    Answer: semantic

    Semantic versioning uses the major.minor.patch pattern to show how big a change is.

  • Put in orderLevel 3

    2. Order these units of digital data from smallest to largest.

    Answer: Byte -> Kilobyte -> Megabyte -> Gigabyte

    A kilobyte is bigger than a byte, a megabyte is bigger than a kilobyte, and a gigabyte is bigger still.

  • True or falseLevel 1

    3. An operating system is the main software that runs a computer or phone.

    Answer: True

    The operating system controls the device and lets all your other apps run.