Software Engineering

Retries Are Not Reliability

Repeating a failing action can be useful. It can also multiply load, duplicate side effects, and hide the fact that the system was never designed to fail safely.

Why retries help only when failure modes are understood, and why they often become a lazy substitute for idempotency, backpressure, and real resilience design.

Jay McBride

Jay McBride

Software Engineer

3 min read

Introduction

Retries make teams feel safer because they look like resilience in motion.

Something failed. Try again. Maybe it works. Great.

Sometimes that is the right response. Plenty of failures really are transient.

But I have watched retries get treated like a magical reliability upgrade when they were actually:

  • repeating a broken request
  • amplifying load during an outage
  • duplicating side effects
  • delaying detection of a deeper design flaw

This article is for teams building systems where failure is normal enough that retry logic has become part of the design. Retries are useful. They just stop being useful the moment you confuse repetition with resilience.

The Core Judgment: Retries Help Only When the System Can Safely Be Asked Twice

That is the part people skip.

Before I add retries, I want to know:

  • is the failure transient or structural?
  • is the action idempotent?
  • what happens if the first attempt partially succeeded?
  • how much additional load do retries create during trouble?

Without good answers to those questions, retries are not protection. They are optimism with loops.

This is why retry policy belongs to system design, not just helper functions.

How This Breaks in the Real World

The classic failure mode happens during degraded dependency behavior.

An external service slows down. Timeouts rise. Your workers retry aggressively. Now the downstream dependency is under even more pressure, your queue grows, and the retry storm becomes part of the outage.

Or the original action succeeds but the confirmation response is lost. The system retries anyway and now the side effect happens twice because nobody designed for uncertainty around acknowledgement.

Both of those scenarios are common. Neither is solved by “just retry.”

A Real Example: The Retry Loop That Made the Incident Bigger

I watched a team treat retry count like a sign of robustness.

Their background jobs retried external syncs quickly and often. Under normal conditions, it worked well enough. During a vendor slowdown, though, those retries stacked up into a flood. Queue depth exploded, workers spent their time reprocessing doomed work, and the team ended up in a worse position than if they had failed fast and recovered more deliberately.

The fix was not removing retries entirely. It was making them smarter:

  • slower backoff
  • stronger limits
  • clearer dead-letter behavior
  • idempotent downstream handling

In other words, actual reliability thinking.

What I Would Do Instead

If I need retries, I want them paired with:

  • idempotency
  • backoff
  • failure classification
  • queue visibility
  • explicit give-up behavior

I especially want to know which failures deserve retry and which deserve immediate human or system attention.

A good retry policy reflects the shape of the dependency. A bad one reflects the team’s discomfort with uncertainty.

Closing

Retries are not reliability.

They are one tool inside a reliability strategy, and they only help when the system is safe to retry, the failure is likely transient, and the load implications are understood.

Otherwise you are not building resilience.

You are building a machine that asks the same bad question louder.

Share

Pass it to someone who needs it

About the Author
Jay McBride

Jay McBride

Software engineer with 20 years building production systems and mentoring developers. I write about the tradeoffs nobody mentions, the decisions that break at scale, and what actually matters when you ship. If you've already seen the AI summaries, you're in the right place.

Based on 20 years building production systems and mentoring developers.

Support my work on Buy Me a Coffee
Keep Reading

More Articles

/ 3 min read

The Backend Is Not Boring. It Is Where Bad Decisions Get Expensive.

Frontend trends change every year. Backend mistakes keep charging interest long after the UI refresh ships.

Read article
/ 3 min read

Background Jobs Are Where Web Apps Go to Hide Complexity

Teams love pushing work into the background because the request gets faster. They forget the complexity did not disappear. It just moved somewhere less visible.

Read article