Your 3 x 3 x 3 example points at the one guardrail your list doesn't cover. Each technique on it works per call, so every layer can follow all six and C still sees 27 attempts. The fix sits between the layers. The SRE book chapter you cite says to avoid retrying at multiple levels, because attempts multiply by the count at each layer, and suggests a process-wide retry budget, for example 60 retries per minute, after which you fail the request instead of retrying.
In your A, B, C setup that could mean only B retries C, and when B gives up it returns a specific overloaded status that tells A not to retry. Your simulation would show the difference well: add a counter for attempts reaching C, run it once with retries at every layer and once with retries at B only.
This is a really good catch. The distinction between per-call retry limits and controlling retries across layers is important, and I should have covered it.
Thanks for pointing this out! I'll add that.
I've updated the article with a section on coordinating retries across layers and added a small simulation comparing retries at every layer with retries at just one layer.
Your 3 x 3 x 3 example points at the one guardrail your list doesn't cover. Each technique on it works per call, so every layer can follow all six and C still sees 27 attempts. The fix sits between the layers. The SRE book chapter you cite says to avoid retrying at multiple levels, because attempts multiply by the count at each layer, and suggests a process-wide retry budget, for example 60 retries per minute, after which you fail the request instead of retrying.
In your A, B, C setup that could mean only B retries C, and when B gives up it returns a specific overloaded status that tells A not to retry. Your simulation would show the difference well: add a counter for attempts reaching C, run it once with retries at every layer and once with retries at B only.