Inspect and Trigger the Postfix Mail Queue with postqueue
postqueue is the ordinary-user tool for checking Postfix's deferred mail queue and nudging delivery along, without postsuper's sharper privileges. This covers a repeatable inspection, a machine-readable listing you can save, and requesting delivery for one message, one destination or the whole queue. Examples use Postfix 3.8.6-1ubuntu0.1, the postfix package. Budget ten minutes if Postfix is already running.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell account allowed to view the queue. Viewing and most delivery requests are ordinary user commands, though Postfix authorisation and local service configuration still apply. The command itself has set-group-ID privileges so it can reach Postfix daemons; you do not need sudo just because it is an administrative tool.
1. Confirm the installed command
Check which executable runs, and read its local manual before borrowing a flag from another Postfix release:
$ command -v postqueue
/usr/sbin/postqueue
$ dpkg-query -W -f='${Package} ${Version}\n' postfix
postfix 3.8.6-1ubuntu0.1
$ postqueue 2>&1 | head -2
postqueue: fatal: usage: postqueue -f | postqueue -i queueid | postqueue -j | postqueue -p | postqueue -s site
The exact wording can vary. What matters is that the command resolves to the Postfix install you expect, and that the version is a known quantity. This guide describes the installed 3.8.6 behaviour; a different version means the local manual page takes over as the authority.
2. Read the traditional queue listing
Start with -p, which gives the familiar sendmail-style listing:
$ postqueue -p
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
72D6CD1C0583 5222 Sat Sep 26 09:14:27 MAILER-DAEMON
www-data@a1b2c3d4e5f6
-- 5 Kbytes in 1 Request.
Your queue will differ, and an empty one normally says so at the end. Each entry has a queue ID, size, arrival time, envelope sender and the recipients still waiting. A previous delivery failure reason can appear below the recipient it belongs to.
Do not treat a queue listing as a complete, frozen snapshot. The showq daemon can list mail while delivery is still happening, so a message can disappear, move or show up more than once between two runs. Re-run the command before you act on what you see.
Checkpoint
Only copy a queue ID from the current listing. Queue IDs can be reused within a Postfix instance, and they are not unique across separate instances.
3. Produce JSON Lines for scripts
Use -j when another program needs to parse the listing. It emits one JSON object per queue file, one per line:
$ postqueue -j
{"queue_name":"deferred","queue_id":"72D6CD1C0583","arrival_time":1790254867,"message_size":5222,"forced_expire":false,"sender":"MAILER-DAEMON","recipients":[{"address":"www-data@a1b2c3d4e5f6","delay_reason":"Host or domain name not found. Name service error"}]}
Here, arrival_time is seconds since the Unix epoch, message_size counts the header and body but not envelope data, and recipients is an array. A recipient may carry a delay_reason, or not, if delivery is still in progress or stopped abruptly.
JSON output has been available since Postfix 3.1. Keep parsers tolerant, because the manual reserves the right to add object members later. For a quick count with jq installed:
$ postqueue -j | jq -s 'length'
1
Diagnostics go to standard error, the listing to standard output. Redirect the output but keep errors separate, so a failure message can never be mistaken for JSON:
$ postqueue -j > queue.jsonl
$ jq -e 'select(.queue_id)' queue.jsonl > /dev/null
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
4. Request delivery for one queue ID
After checking the current listing, request immediate delivery for one queue ID with -i:
$ postqueue -i 72D6CD1C0583
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
This contacts Postfix's flush service. It schedules delivery, it does not guarantee it, and it fixes nothing about DNS, authentication, routing or recipient problems. Check the queue again afterwards, and read the logs your machine actually uses.
This changes delivery scheduling, not the message itself, and there is no separate undo. If you triggered it by mistake, let normal delivery run its course, or fix the actual problem underneath it. Warning: do not repeatedly flush an undeliverable message; the manual warns that frequent flushing can hurt delivery performance for everyone else's mail too.
5. Target a destination, or flush the whole queue
Use -s with a site when you have one specific destination to retry:
$ postqueue -s example.net
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
A numeric destination must be written as an RFC 5321 address literal with square brackets, like [192.0.2.10], and it must also be eligible for Postfix's fast flush service. A normal domain name configured for that service is usually the simpler choice.
Use -f only when you deliberately want Postfix to attempt every queued message:
$ postqueue -f
$ printf 'postqueue returned %s\n' "$?"
postqueue returned 0
Warning
This can generate a lot of delivery activity. It is not a diagnostic and not a way to force mail through permanently. Fix the cause of a queue backlog first, then use a targeted request instead where you can.
6. Use a non-default configuration carefully
Pass -c when the target main.cf lives in a different configuration directory:
$ postqueue -c /etc/postfix-test -j
{"queue_name":"deferred","queue_id":"...","arrival_time":1790254867,"message_size":5222,"forced_expire":false,"sender":"...","recipients":[]}
Swap in a real directory holding the intended main.cf. An ordinary user can only use a non-standard directory when the standard configuration lists it in alternate_config_directories; the super-user is held to a different restriction entirely. Never set MAIL_CONFIG or use -c to try to route around that check with an untrusted directory.
Add -v for verbose diagnostics if needed. On Postfix 2.3 and later, the manual restricts this option to the super-user, and repeating it increases verbosity further. Only capture verbose output when you need it, since it can put operational detail into logs or terminal history you did not plan for.
7. Keep destructive queue work separate
postqueue cannot delete queued messages or change their hold status. Those are postsuper's privileged operations. Treat anything that removes or expires mail as its own separate change: pin down the exact queue ID, confirm sender and recipients, check retention requirements, and have a recovery plan before running it. A delivery request from this guide is reversible only in the sense that the normal queue process can continue; deletion is not reversible at all.
Done means
- Command confirmed. Installed Postfix version and executable checked.
- Queue inspected.
postqueue -pfor reading,postqueue -jfor scripts. - Targeted requests only. A current queue ID for
-i, a configured site for-s. - Full flush reserved.
-fused deliberately, never repeated blindly. - Limits understood. Delivery is scheduled, not guaranteed, and nothing here deletes mail.