BOTHRESH

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.

BackoutCount and the Message Descriptor

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.

When BackoutCount Increments

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 tuning guide
BOTHRESHBehaviorWhen to use
0No BOQNAME routing by thresholdOnly if another poison strategy exists (rare on critical queues)
1First rollback sends to backoutStrict; no retries; idempotency elsewhere
3–5Few retries then backoutCommon production default
High (e.g. 99)Many retries before backoutFlaky downstream; risk long poison delay

BOTHRESH(0): The Default Trap

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.

Pairing BOTHRESH with BOQNAME

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.

shell
1
2
3
4
ALTER 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

Transient Failures vs Permanent Defects

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.

BOTHRESH and Message Ordering

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.

Monitoring and Alerts

  • Alert on backout queue depth > 0 (BOQNAME target).
  • Dashboard BackoutCount distribution on samples during tests.
  • Correlate BOTHRESH breaches with deploy timestamps.
  • Track mean time to requeue from backout after fix.

Explainer: BOTHRESH as “Three Strikes”

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.

Practice Exercises

Exercise 1

Choose BOTHRESH for a queue calling an external API with 30-second outages. Justify your number.

Exercise 2

BackoutCount is 2, BOTHRESH is 3. What happens on the next rollback?

Exercise 3

Why is idempotency still required when BOTHRESH is 5?

Frequently Asked Questions

Frequently Asked Questions

Test Your Knowledge

Test Your Knowledge

1. BOTHRESH is compared against:

  • BackoutCount on the message
  • CURDEPTH
  • MAXMSGL
  • Channel batch size

2. BOTHRESH(0) usually means:

  • Backout queue routing disabled
  • Unlimited backouts to BOQNAME
  • Queue is XMITQ
  • Trigger enabled

3. A sensible production BOTHRESH might be:

  • 3 to 5 with idempotent design
  • 0 always
  • 999999999 always
  • Same as MAXDEPTH

4. BOTHRESH requires which companion attribute?

  • BOQNAME
  • USAGE(XMITQ)
  • CLUSTER
  • DISTL(YES)
Published
Read time14 min
AuthorMainframeMaster
Verified: IBM MQ 9.3 documentation