BOTHRESH is the backout threshold: a simple integer on your queue definition that decides how many times a message may fail processing before IBM MQ stops giving it to your application and sends it to the backout queue named in BOQNAME. It is one of the most important reliability knobs on application queues, yet it is often left at default zero until a poison message incident blocks a payment or inventory feed. This page explains BackoutCount in the message descriptor, how rollback under syncpoint increments it, how BOTHRESH compares at get time, tuning values for transient versus permanent errors, and how BOTHRESH interacts with idempotent application design—written for beginners who are configuring MQSC for the first time.
Every IBM MQ message carries an MQMD (message descriptor). BackoutCount records how many times this message has been rolled back on the current queue. When BOTHRESH is 3, delivery attempts with BackoutCount 0, 1, and 2 may still reach your consumer (subject to API behavior); when BackoutCount reaches the threshold, the queue manager routes the message to BOQNAME instead of your get call. Developers can log BackoutCount in application logs to see “retry 2 of 3” patterns during incidents. Tools that browse the queue can display BackoutCount for forensic review without consuming messages.
The classic pattern: MQGET under syncpoint, business logic throws, MQBACK. The message reappears on the queue with BackoutCount increased by one. Commit does not increment BackoutCount for poison handling on that attempt—successful processing ends the cycle. Non-syncpoint gets change failure semantics; production consumers processing business data should use syncpoint where rollback is meaningful. Client auto-commit modes that hide rollback may surprise teams who expected BackoutCount to rise—verify session transacted settings in JMS and .NET.
| BOTHRESH | Behavior | When to use |
|---|---|---|
| 0 | No BOQNAME routing by threshold | Only if another poison strategy exists (rare on critical queues) |
| 1 | First rollback sends to backout | Strict; no retries; idempotency elsewhere |
| 3–5 | Few retries then backout | Common production default |
| High (e.g. 99) | Many retries before backout | Flaky downstream; risk long poison delay |
New queue definitions often inherit BOTHRESH(0). Administrators see BOQNAME set in documentation examples but forget BOTHRESH—poison handling never activates. In audits, run MQSC to list application queues where BOTHRESH is 0 or BOQNAME is blank. Promotion pipelines should fail a build if critical queues lack BOTHRESH and BOQNAME in exported definitions.
BOTHRESH without BOQNAME is incomplete; BOQNAME without a positive BOTHRESH is ineffective. Define both in the same ALTER or DEFINE statement. Example: BOTHRESH(3) BOQNAME('PAYMENTS.BO'). The backout queue should not reuse the same threshold loop—define PAYMENTS.BO without BOTHRESH or with careful thought if you implement secondary handling.
1234ALTER QLOCAL('PAYMENTS.IN') BOTHRESH(3) BOQNAME('PAYMENTS.BO') DISPLAY QLOCAL('PAYMENTS.IN') BOTHRESH BOQNAME * Simulate: transacted consumer, rollback three times; * fourth path should land on PAYMENTS.BO
BOTHRESH(3) helps when attempt two succeeds because a database was briefly down. It does not help when every attempt fails because the message body is permanently invalid—after three rollbacks the message still needs human or tooling intervention on the backout queue. Complement BOTHRESH with idempotent handlers so retries 1 and 2 do not double-post transactions. For extended outages, consider pausing consumers instead of burning through BOTHRESH on all messages.
On a FIFO queue, one poison message below BOTHRESH can block later messages if your consumer always gets the same failing message first (unless you use browse/skip patterns or multiple queues). Moving to BOQNAME after threshold unblocks the queue—a key reason poison handling matters for throughput. Some architectures use priority queues or separate error topics; BOTHRESH remains the built-in MQ safety net.
A player gets three tries (BOTHRESH) to hit the ball. Each miss (rollback) adds a strike (BackoutCount). After three strikes, the player sits on the bench queue (BOQNAME) so the game continues for everyone else.
Choose BOTHRESH for a queue calling an external API with 30-second outages. Justify your number.
BackoutCount is 2, BOTHRESH is 3. What happens on the next rollback?
Why is idempotency still required when BOTHRESH is 5?
1. BOTHRESH is compared against:
2. BOTHRESH(0) usually means:
3. A sensible production BOTHRESH might be:
4. BOTHRESH requires which companion attribute?