Inspect the Postfix Mail Queue with showq
You will check which messages are waiting in Postfix, distinguish deferred mail from messages selected for delivery, and obtain machine-readable queue data without editing queue files. Allow about 10 minutes. You need Postfix installed and a shell account that can run postqueue; elevated privileges are not normally needed to list the queue.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Confirm the installed Postfix version
This guide follows the Ubuntu package installed on the reference system: Postfix 3.8.6. Check your own daemon before relying on version-specific fields or queue ID behaviour.
$ postconf mail_version
mail_version = 3.8.6
If postconf is missing, stop here and install or repair the Postfix package using your distribution's normal package process. Do not create a queue directory by hand.
2. List the queue through the supported client
showq(8) is the daemon that reports queue status. Its output is intended to be formatted by postqueue(1), which is the command you should use for an ordinary inspection.
$ postqueue -p
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
72D6CD1C0583 5222 Thu Sep 24 14:01:07 MAILER-DAEMON
[email protected]
-- 5 Kbytes in 1 Request.
Your IDs, dates and recipients will differ. A queue count of zero is a valid result. The listing can change while it is being produced, so treat it as a point-in-time view rather than a transactionally consistent snapshot.
Checkpoint: read the important parts
- The queue ID identifies the message for later administrative work.
- The size and arrival time describe the queued message.
- The sender and recipients show the envelope addresses still awaiting delivery.
- A reason below a recipient normally explains the last failed delivery attempt.
- An asterisk after a queue ID marks the active queue, where the message is selected for delivery.
- An exclamation mark marks the hold queue, where delivery is paused.
Do not treat a visible queue entry as proof that delivery will fail. A message may be in active processing, and another process can remove or alter an entry immediately after the listing.
3. Produce JSON Lines for a script
For monitoring or a one-off count, use postqueue -j. Postfix emits one JSON object per queue file, one object per line. This option is available from Postfix 3.1 onwards, so it is present in 3.8.6.
$ postqueue -j | head -n 1
{"queue_name":"deferred","queue_id":"72D6CD1C0583","arrival_time":1727186467,"message_size":5222,"sender":"MAILER-DAEMON","recipients":[{"address":"[email protected]","delay_reason":"temporary failure"}]}
Fields can grow over time. A consumer should ignore members it does not recognise. The queue can change during the scan, so a message may be missed or appear more than once. Use a JSON parser in a script rather than splitting the traditional display on spaces.
$ postqueue -j | jq -r 'select(.queue_name == "deferred") | [.queue_id, .sender] | @tsv'
72D6CD1C0583 MAILER-DAEMON
The jq command is optional and must already be installed. If it is absent, keep the raw JSON or use the parser already approved for your monitoring host.
4. Check configuration changes without touching the queue
The daemon reads relevant main.cf settings when its short-lived processes start. After changing a setting that affects queue display, ask Postfix to reload so new processes pick it up quickly.
$ sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system
$ postqueue -p
postfix reload changes service state, so use sudo and schedule it like any other service operation. It does not flush, delete or requeue messages. If the reload reports an error, inspect the Postfix log rather than repeatedly retrying.
5. Recover visibility when Postfix is down
showq can run in standalone mode as the superuser, which is useful when the Postfix mail system is stopped. This is an emergency inspection path, not a replacement for postqueue. Resolve the daemon directory from the live configuration instead of assuming a hard-coded installation path.
$ sudo "$(postconf -h daemon_directory)/showq"
$ printf 'showq exit status: %s\n' "$?"
The normal daemon interface is designed for Postfix clients, so direct output and exit status are not a stable scripting interface. If this command fails, check the system log for showq, postlogd or syslogd messages and confirm that the queue directory from postconf queue_directory is present. Do not run it as an unprivileged user and do not modify files under the queue directory manually.
Common traps
- Using
showqas a user-facing filter: it is a daemon, not a queue-management command. Start withpostqueue -porpostqueue -j. - Confusing listing with delivery: neither listing command sends mail. Queue flushing and message deletion are separate operations with their own safety risks.
- Assuming IDs are globally unique: queue IDs can be reused by a Postfix instance. Include the host when storing them in external records.
- Expecting a static answer: queue contents change while delivery workers run. Record the command time with monitoring results.
- Ignoring local exposure: the showq service port is accessible to local untrusted users and can be susceptible to denial-of-service attacks. Keep the service protected by the Postfix service configuration and investigate unexpected local load.
Done means
postconf mail_versionidentified the local Postfix version.postqueue -pproduced a readable queue listing, including an honest empty result if appropriate.- You can explain the queue ID, recipient status and active or held markers.
- Any script uses
postqueue -jand tolerates changing contents and new JSON fields. - You know that standalone
showqrequires the superuser and is for recovery inspection, not routine parsing.