Benchmark a QMQP Client Safely with qmqp-sink
You will run qmqp-sink on a loopback address, send controlled test traffic to it, and watch the number of completed QMQP deliveries. The sink discards messages, so this measures client and transport performance without creating a mailbox. Allow about 15 minutes if Postfix and its test tools are already installed.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide uses the installed Postfix package version 3.8.6-1ubuntu0.1. The manual describes qmqp-sink as an unsupported test program and makes no compatibility promise between Postfix releases. Keep the test on a private endpoint unless you have a specific, controlled reason to do otherwise.
1. Check the installed command
Confirm that the binary is available and record the package version. The command has no useful version option documented by its manual page, so the package version is the practical version record on this system:
$ command -v qmqp-sink
/usr/sbin/qmqp-sink
$ dpkg-query -W -f='${Package} ${Version}\n' postfix
postfix 3.8.6-1ubuntu0.1
The related qmqp-source program is useful for a reproducible client-side test. It speaks QMQP and can create multiple messages or parallel sessions. You do not need elevated privileges for a loopback test on a high, unused port.
2. Choose a private listening endpoint
Use an unoccupied port on 127.0.0.1. The listening syntax is [host]:port backlog; the backlog is the kernel listen queue length, not the number of messages to accept:
$ ss -ltn 'sport = :25253'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
An empty result means that this example port is not currently listening. Pick another high port if your output shows a process. Do not use a production SMTP or QMQP port merely because it is familiar.
3. Start the disposable sink
Start the sink in one terminal with a modest backlog and the completion counter enabled:
$ qmqp-sink -c 127.0.0.1:25253 4
There is normally no startup banner. The process stays attached to the terminal and updates its counter when a delivery completes. -c is a display option, not a concurrency setting. The sink accepts IPv4 and IPv6 by default; -4 or -6 restricts the address family when that distinction matters. The -6 option is unavailable in a Postfix build without IPv6 support.
Checkpoint: in a second terminal, verify that the listener belongs only to the loopback address:
$ ss -ltnp | grep ':25253 '
LISTEN 0 4 127.0.0.1:25253 0.0.0.0:* users:(("qmqp-sink",pid=...,fd=...))
The exact columns and process identifiers vary. The important part is 127.0.0.1:25253, not a wildcard address. If you see 0.0.0.0:25253 or an IPv6 wildcard, stop the process with Ctrl-C and restart it with the explicit loopback address.
4. Send a small, controlled workload
Run the client from the second terminal. This sends two generated messages over two parallel QMQP sessions and displays its own completion counter:
$ qmqp-source -c -m 2 -s 2 127.0.0.1:25253
1
2
The output may appear on one updating line because the counter uses carriage returns. A successful exit status is more reliable than the layout. Check it immediately:
$ printf '%s\n' "$?"
0
At the same time, the sink should show two completed deliveries. The sink's counter is incremented when a delivery completes, so it is the useful server-side confirmation that QMQP traffic reached the test server. The messages are thrown away by design.
5. Increase load only after the small test works
For a measured run, keep the sink command unchanged and vary one client parameter at a time. For example, this sends 100 messages through four sessions:
$ qmqp-source -c -m 100 -s 4 127.0.0.1:25253
1
2
3
...
100
Use -l on qmqp-source when payload size is part of the test, and -r when a transaction should contain more than one recipient. Those are client controls, not qmqp-sink options. Record the message count, session count, payload length, host and Postfix package version with each result. Otherwise a later comparison can confuse a changed workload with a faster client.
Do not interpret this as a protocol-compliance test. The sink exists to measure QMQP client performance and discards the received messages. It does not represent delivery to a real queue, mailbox or policy pipeline.
6. Stop the test and recover cleanly
When the run is complete, return to the terminal running qmqp-sink and press Ctrl-C. Verify that the port is closed:
$ ss -ltn 'sport = :25253'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
If the client reports a connection failure, first check that the sink is still running and that the address and port match. If the sink exited unexpectedly, rerun it in the foreground with -v for more diagnostics. A second -v can show some of the QMQP conversation, but that produces more output and is best reserved for a short failing test.
The -x time option makes the sink terminate after the specified number of seconds. It is intended to help with memory leak testing. For an ordinary benchmark, foreground control with Ctrl-C makes the lifetime obvious. If you use -x, allow enough time for the workload to finish and verify the listener has disappeared afterwards.
Done means
- The installed Postfix version and test parameters were recorded.
qmqp-sinklistened only on an intentional loopback address.- A small
qmqp-sourcerun completed with exit status 0 and matching counters. - Load was increased by changing measured client parameters, not by guessing at sink concurrency.
- The unsupported sink was stopped and its listening port is closed.