Serguey Asael Shinder: Most arguments about adding a queue are arguments about retries, not throughput
Every few months a team decides it needs a queue, and the case is made with throughput: requests per second, peak versus average, the graph that goes up. I have sat through many of these and I now think the numbers are almost never the real reason.
The real reason is that something downstream fails, and nobody wants to decide what happens next in the request path. A queue lets you postpone that decision by making it somebody's problem later — which is useful, and is also exactly where the difficulty moves rather than disappears.
The questions that actually decide it
Throughput is usually the easiest constraint to satisfy and the first one discussed. The hard ones are all about failure:
What does the caller learn? If the work is queued, the answer to the caller is "accepted", not "done". Every screen, email and API contract that said "done" now needs a second state, and half the disappointment with queues comes from teams that added the queue but not the state.
Who retries, and how many times? The queue will redeliver. If the handler is not idempotent, redelivery is not a safety net, it is a duplicate-charge generator. Deciding idempotency after the queue is in place means retrofitting keys into code that has already shipped.
Where does a permanently failing message go? A dead-letter queue nobody reads is a directory of incidents you have agreed not to look at. The useful question is not whether you have one, but whose dashboard shows its depth.
What is the ordering guarantee, and does the domain need one? Most systems need ordering in a few narrow places and nowhere else. Teams that assume global ordering are surprised; teams that assume none are surprised differently.

The cheaper move that often wins
Before the queue, there is a smaller change that solves the same failure and keeps the request path synchronous: bound the work, make it idempotent, and give it a timeout and a bounded retry with backoff. A large share of "we need a queue" turns out to be "this call has no timeout and we retry it forever".
If that is not enough — because the work genuinely takes minutes, or because the downstream is unavailable for hours at a time — then the queue is right. But it should be adopted for its failure semantics, which is what you are actually buying.
What I would put in the design doc
One sentence, before any diagram: "When the downstream is down for an hour, here is what the user sees, here is what we retry, and here is who is paged." Every team that writes that sentence first ends up with a smaller design than the one they arrived with, and a better one.