# How do I set up a Circuit Breaker for a flaky third-party API dependency?

> A breaker alone won't hold: pull `connect_timeout` and `timeout` down to 800ms-2s, isolate the dependency behind a bulkhead, and define a cached fallback.

- Asked: 2026-05-25
- Answered: 2026-05-28
- Asked by: Tunç
- Tags: dayaniklilik, mimari, laravel
- Source: https://muhammetsafak.com/just-ask/circuit-breaker-for-flaky-third-party-apis/
- Language: en-US
- Author: Muhammet Şafak

---
**Question:** Our app fetches shipping prices from an external carrier API. When the carrier slows down or goes down, our requests hit the timeout, the Octane/PHP-FPM workers block, and the whole system locks up.

How do I set up a Circuit Breaker with Guzzle middleware or a Go library to stop this cascade? How should the system behave in the Open/Closed/Half-Open states?


Short answer: a circuit breaker alone won't save you — it saves you when you pair it with an **aggressive timeout**. Because what kills your workers isn't the error itself, it's the 30 seconds of waiting that lead up to it.

## Short answer

What you're hitting is a classic **cascading failure**: a slow dependency makes every request wait on the timeout, the pool fills, the system locks. The breaker's job is to stop calling a failing dependency entirely. I covered why this hits harder in an architecture where the worker survives between requests in the [Laravel Octane post](/blog/laravel-octane-persistent-process-performance/).

## Why

1. **It isn't the error that kills you, it's the wait.** If the dependency failed fast the worker would be freed instantly; a 30-second timeout fills the pool.

2. **The breaker's three states are a protocol.** `CLOSED`: calls pass, failures are counted. Once the threshold trips, go `OPEN`: don't call the dependency at all, return a fallback immediately, stay that way for a cooldown. When the cooldown ends, go `HALF-OPEN`: let a few trial calls through — on success go back to `CLOSED`, on failure flip back to `OPEN`.

3. **One dependency shouldn't be able to consume the whole pool.** Without isolation, the carrier API's slowness drags cart and checkout down with it.

## What to do

1. **Cut the timeout first — that's the real killer.** Keep `connect_timeout` and `timeout` short: Guzzle takes them as float seconds, so something like `0.8` to `2` rather than the default of waiting indefinitely. A breaker is useless without a short timeout.

2. **Set up the breaker with its three states.** Choose the threshold and cooldown against your real failure rate.

3. **Isolate that dependency with a bulkhead.** Cap the number of concurrent requests allowed to the carrier API so only a small reserved slice is consumed when it slows down.

4. **Define the fallback in advance.** Return the last cached shipping price, and if there's none, say "estimate unavailable right now." Serve a degraded-but-working experience instead of an error page.

5. **Pick the right tool.** In Laravel wrap the Guzzle client in middleware and keep the state in Redis. In Go don't hand-roll it — `sony/gobreaker` already gives you these three states.

**Bottom line:** I'd never leave the breaker alone: I set it up as a trio of short timeout + bulkhead + cached fallback. Workers blocking while they wait on a timeout hits especially hard in a persistent-process architecture (Octane), so cut the timeout first, then add the breaker.

## Related Reading

- [Laravel Octane: the performance that comes with a persistent process](/blog/laravel-octane-persistent-process-performance/) — Blog
- [How do I handle poison-pill messages and a Dead Letter Queue in the queue?](https://muhammetsafak.com/just-ask/poison-pill-messages-and-dead-letter-queues-in-laravel/) — Just Ask
- [Graceful degradation: how do I isolate non-critical services under load?](https://muhammetsafak.com/just-ask/graceful-degradation-isolating-non-critical-services-under-load/) — Just Ask
- [For comments across many models should I use a polymorphic relation or separate tables, given indexing and foreign keys?](https://muhammetsafak.com/just-ask/comments-polymorphic-relation-separate-tables-indexing-foreign-keys/) — Just Ask
