Mail piling up in the Postfix deferred queue? Before you crank up qmgr's concurrency, learn what it is actually doing. You will see where the queue manager fits, inspect the live queue defaults, and make one controlled delivery change that survives a reload. Allow about 20 minutes, plus time to watch the result. The examples are for the installed Postfix 3.8.6 package on this machine.
qmgr is a daemon, not a command-line queue viewer. Postfix's master process starts it, and it arranges delivery through the delivery processes. Do not try to launch qmgr by hand.
Start with these unprivileged checks:
$ postconf mail_version queue_directory config_directory
mail_version = 3.8.6
queue_directory = /var/spool/postfix
config_directory = /etc/postfix
Your package revision may differ while the major and minor Postfix version stay the same.
Tip: The queue manager is a persistent process that reads main.cf settings, so editing the file alone does not change its running behaviour.
Checkpoint: You know which Postfix installation you are inspecting and where its queue and configuration live.
The queue manager keeps a separate directory for each stage:
incoming holds new mail waiting to be picked up.active holds messages opened for delivery.deferred holds messages that previously got a temporary failure.hold holds mail deliberately kept back.corrupt is where damaged queue files go.bounce, defer and trace keep delivery status data separately.Listing them is read-only, but the spool is normally restricted, so use elevated privileges for this inspection only:
$ sudo find "$(postconf -h queue_directory)" -maxdepth 1 -mindepth 1 -type d -printf '%f\n' | sort
active
bounce
corrupt
defer
deferred
hold
incoming
trace
The exact list depends on the installation. A large deferred queue means delivery has been postponed; it does not tell you why. Read the Postfix log and the destination's response before increasing concurrency.
Start with the settings for retry timing, per-destination parallelism and recipients held in memory:
$ postconf minimal_backoff_time maximal_backoff_time queue_run_delay maximal_queue_lifetime
minimal_backoff_time = 300s
maximal_backoff_time = 4000s
queue_run_delay = 300s
maximal_queue_lifetime = 5d
$ postconf initial_destination_concurrency default_destination_concurrency_limit default_destination_recipient_limit
initial_destination_concurrency = 5
default_destination_concurrency_limit = 20
default_destination_recipient_limit = 50
These are defaults, not promises that every message uses all of them.
transport_... parameter.minimal_backoff_time defaulted to 1000s before Postfix 2.4, so old tuning advice may quote that figure.Two easy traps:
queue_run_delay is not a retry schedule. It is the interval between deferred-queue scans. Each deferred message also has its own backoff and timestamp, so nothing guarantees a retry exactly on that schedule.default_destination_concurrency_limit is per destination, not a server-wide delivery cap.Checkpoint: Save the output in your change record, and decide whether the bottleneck is retry timing, destination concurrency, recipient batching or the remote system.
For a temporary remote outage, easing pressure is usually safer than making Postfix more aggressive. For example, set a longer queue scan interval so deferred mail is checked less often. This changes the persistent configuration:
$ sudo postconf -e 'queue_run_delay = 600s'
$ postconf queue_run_delay
queue_run_delay = 600s
The command edits /etc/postfix/main.cf through Postfix's configuration tool. It does not restart the service and does not immediately alter the running queue manager. Record the old value first so recovery is exact.
Tip: Only shorten the scan interval when you have a real reason to check deferred mail more often; that can increase disk and network activity.
Warning: Do not lower retry intervals or raise concurrency to hide remote 4xx responses, rate limits or connection failures. That can amplify load and make the outage worse. Change one setting at a time, and never edit the queue directories by hand.
After a main.cf change you must reload Postfix.
Warning: A reload is a service-disrupting control action. Use a maintenance window if your mail flow is sensitive.
$ sudo postfix reload
$ postconf queue_run_delay
queue_run_delay = 600s
The reload asks the Postfix process manager to apply configuration to persistent daemons, including qmgr.
Checkpoint: The system's Postfix log shows the reload and subsequent delivery activity. The qmgr manual says problems and transactions are logged through syslogd or postlogd; the exact log file is distribution-specific.
Recovery: If the change was wrong, restore the recorded value and reload again. That is the undo path for this example.
$ sudo postconf -e 'queue_run_delay = 300s'
$ sudo postfix reload
$ postconf queue_run_delay
queue_run_delay = 300s
Warning: Do not remove deferred messages to make a queue count look better. Deleting queued mail is a separate, potentially irreversible operation.
A few qmgr behaviours explain most "why is this mail still stuck?" moments:
Together these explain why a new message can be delivered while older mail stays deferred, and why repeatedly forcing scans is not a cure.
corrupt for inspection. Preserve them and the related log entries until you understand the failure.main.cf and confirmed the setting.