Two ways to get it wrong
An untuned breaker fails in two directions, and you will meet both.
Too sensitive and it trips on noise. A routine deploy causes ten seconds of connection errors, your breaker opens, and now a perfectly healthy service is being refused for a minute, an outage the breaker itself manufactured.
Too tolerant and it never trips until your thread pools are already gone. The false-positive risk is real and it peaks during traffic spikes, when a brief latency blip looks identical to early sickness.
Tune from your measurements rather than from defaults. Set your call timeout from that dependency's observed p99 plus margin. A two second timeout on a service whose p99 is 200 milliseconds means waiting ten times longer than any healthy response before giving up.
Use rate-based thresholds over a minimum number of calls, so three failures out of five at quiet times do not trip anything. Count slow calls alongside failed ones. Keep the open period modest, 10 to 60 seconds, since your half-open probes make long punishments pointless.
Watch state transitions in your metrics, and alert on a breaker that stays open for minutes, because that means your dependency is genuinely down and a person should know.
The fallback is a product decision
Treat the fallback as a product decision wearing an engineering costume, and give it the same review a product decision would get.
Climb the ladder of options. Serve a cached previous answer, since stale recommendations beat none. Serve a static default, like an empty reviews section. Compute something simpler, like rule-based fraud scoring instead of the vendor's model. Queue the work for later, accepting the order and sending the receipt when email recovers. Or return an honest error for the things that cannot degrade, like taking the payment.
Choose per endpoint, deliberately. And test that fallback path under load, regularly, because the classic failure is a fallback reading from a cache that is empty precisely because the dependency has been down, discovered for the first time during the incident it was built for.
Worked example
An e-commerce team ships breakers on all outbound calls with library defaults: 5-failure trip count, no minimum volume, 60-second open. First Black Friday, at 00:03, a 15-second latency blip in the loyalty-points service (autoscaling catching up to the surge) trips its breaker on 5 slow calls. Points vanish from checkout for a full minute, and support gets 200 chats from confused customers, a mini-outage the breaker caused. Sameer's postmortem retunes it: trip at 50 percent failures over a minimum of 30 calls in 10 seconds, timeout set to 600 ms against the service's measured 180 ms p99, open for 15 seconds. The fallback changes too: instead of hiding points, checkout shows the last cached balance with an "updating" note. The next surge blips the same service for 12 seconds, and the breaker correctly stays closed while nobody notices anything.