Skip to content

MQ and messaging testing

IBM MQ (formerly WebSphere MQ, also known as MQSeries) carries the messages in many mainframe and distributed system integrations. Payment processing pipelines, insurance claim routing and airline booking confirmations all depend on MQ to deliver messages reliably between applications. An MQ performance test checks three things: the queue manager sustains the required message throughput, put and get latencies stay within SLA under peak concurrency, and queue depth does not grow without bound under sustained load. This page shows how to test IBM MQ with JMeter’s JMS sampler and run the test through MaxoPerf.

  • You need access to an IBM MQ queue manager that is authorized for load testing, with the queue name, channel name, port and queue manager name.
  • You need the IBM MQ JMS client JAR (com.ibm.mq.allclient.jar) from the IBM MQ client installation. JMeter’s JMS sampler needs this JAR to connect to MQ. Ask MaxoPerf support whether the runner image already has it.
  • Coordinate with your MQ administrator to confirm authorized throughput rates, queue depth limits, and the channel MCA user ID for the test.

IBM MQ implements the Java Message Service (JMS) specification through its MQ JMS client library. JMeter’s JMS Point-to-Point sampler (and the JMS Publisher/Subscriber sampler for pub/sub topics) can connect to MQ as a JMS provider. That makes JMeter a natural fit for MQ load testing, with no custom plugin required.

The JMS Point-to-Point sampler supports two operation modes:

ModeWhat it doesUse when
Request only (put)Puts a message to a queue and does not wait for a replyTesting producer throughput, measuring put latency
Request-replyPuts a message to a request queue and waits for a response on a reply queueTesting end-to-end message round-trip latency (full processing cycle)

For most mainframe MQ performance tests, request-reply is the more useful measurement. It tells you how long the consumer application (a CICS or IMS listener, a batch program, or a distributed MQ listener) takes to process the message and return a reply.

JMeter’s JMS sampler uses JNDI to look up the JMS connection factory and queue. For IBM MQ, provide a jndi.properties file that defines the MQ connection parameters.

A minimal jndi.properties for IBM MQ (placed in JMeter’s bin/ directory during authoring, and uploaded as a Test asset in MaxoPerf):

# IBM MQ JNDI configuration for JMeter
java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
java.naming.provider.url=file://${user.home}/JNDI-Directory
# Alternatively, using IBM MQ's built-in JNDI with a file-system context
# Contact your MQ administrator for the correct InitialContext class

Add a JMS Connection Configuration element to your Thread Group:

  • QueueConnection Factory: the JNDI name of the MQ JMS connection factory (as defined in your JNDI context).
  • JNDI name Request queue: the JNDI name of the queue to send messages to.
  • JNDI name Reply queue: the JNDI name of the reply queue (for request-reply mode).
  • Use persistent delivery: set to match your production MQ channel configuration (persistent messages have higher latency than non-persistent).
  • Expiry: set a message expiry so dead messages do not pile up on the queue during a failed test run.

With the connection configuration in place, add a JMS Point-to-Point sampler to each step in your Thread Group:

  • Communication style: Request Only for put-only tests, Request/Reply for round-trip latency.
  • Content: the message body. For mainframe integrations, this is often a fixed-format string, XML, or a binary record format. Use a JMeter variable or CSV Data Set Config element to vary message content across VUs.
  • Correlation: for request-reply, JMeter uses JMS CorrelationID to match reply messages to their originating request. The sampler handles this automatically in JMeter’s correlation mode.

Configure the JMS sampler in Request Only mode. Set the Thread Group to the number of concurrent producer VUs and a target rate (using JMeter’s Constant Throughput Timer to cap puts at a specific messages-per-second rate). Measure:

  • Put latency: the time QueueSender.send() takes. Under high throughput, MQ channel saturation makes it climb.
  • Throughput: messages per second as reported by MaxoPerf.

Configure the JMS sampler in Request/Reply mode. Each sampler measures the full round trip: put to request queue → consumer processes message → put reply to reply queue → JMeter receives reply. MaxoPerf records this end-to-end time as the sampler’s response time. Measure:

  • p95 response time: the 95th percentile of round-trip message latency. It includes MQ network time plus the consumer application’s processing time.
  • Error rate: messages that expire without a reply (the consumer could not keep up) appear as errors.

Run a put-only test at a rate slightly higher than the known consumer throughput and watch queue depth grow. MaxoPerf does not show queue depth directly (it is an MQ metric, not a JMeter metric). Your MQ administrator can monitor it via MQ Explorer or runmqsc DISPLAY QSTATUS while the MaxoPerf run is active. A queue depth that grows linearly without leveling off means the consumer cannot keep up with the load. You want to know that before a peak window.

The IBM MQ allclient JAR is not in the JMeter standard distribution, so you have to make it available in the MaxoPerf runner image. You have two options:

Option A (recommended): request runner image inclusion. Contact MaxoPerf support and ask for the IBM MQ JMS client JAR to be added to the JMeter runner image. After that, your JMX can use it without any Test asset upload.

Option B: upload as Test asset. Package the JAR as a ZIP with the same relative path JMeter expects (lib/com.ibm.mq.allclient.jar) and reference it in your JMX. This needs careful path handling. Confirm with MaxoPerf support that this approach is supported for your account.

In both cases, upload the jndi.properties file as a Test asset.

# Taurus YAML wrapper for an MQ load test
execution:
- executor: jmeter
concurrency: 50
ramp-up: 2m
hold-for: 15m
scenario: mq-request-reply
scenarios:
mq-request-reply:
script: mq-request-reply.jmx

MaxoPerf shows per-sampler metrics for each JMS Point-to-Point sampler:

  • Response time (latency): in request-reply mode, the full round-trip time.
  • Throughput: messages per second across all VUs.
  • Error rate: messages that expired, were rejected, or received an unexpected reply.

Compare MaxoPerf’s latency numbers with MQ channel statistics from your MQ administrator to separate network/channel latency from consumer application processing time.

Do:

  • Set a message expiry on all JMS messages during testing. Without it, unprocessed messages from a failed test stay on the queue indefinitely.
  • Test with persistent delivery if production uses it. Persistent messages have higher latency and different throughput characteristics than non-persistent ones.
  • Monitor queue depth externally (via runmqsc or MQ Explorer) during the MaxoPerf run. Queue depth is the leading indicator of consumer saturation.
  • Clean up the reply queue between test runs so residual messages from a previous run do not break reply correlation.

Don’t:

  • Use a shared production queue for testing. Use a dedicated test queue, because an unexpected message on a production queue can trigger real downstream processing.
  • Forget to configure message expiry. If your JMeter request-reply sampler times out without a reply but the message stays on the reply queue, later VUs may pick up stale replies.
  • Set concurrency higher than the MQ channel’s configured maximum connections without first coordinating with your MQ administrator.