A growing Postfix queue is evidence, not a command to flush everything. The safe response is to capture the queue shape, follow one queue ID through the logs, stop any broken sender, repair the confirmed cause, and retry a single message before releasing more traffic. That sequence protects legitimate password resets and invoices while avoiding a second wave of failures.
This guide assumes Postfix is already installed and mail worked before the incident. It focuses on outbound queue recovery on a Linux VPS, not on building a complete mail server from scratch.
Postfix separates mail by state. A large number by itself does not explain whether the server is congested, waiting on one destination, or preserving old failures. Start with read-only checks:
sudo postfix status
sudo postqueue -p
sudo postqueue -j | head -n 5
sudo qshape deferred | head -n 15
postqueue -j emits one JSON object per line on Postfix 3.1 and later, which is useful for monitoring and scripted summaries. If the installed version does not support it, postqueue -p remains the portable listing. The official Postfix queue manual explains both formats and includes the last delay reason for affected recipients.
| Queue state | What it means | Incident signal |
|---|---|---|
| Incoming | Accepted and waiting for the queue manager | Growing count can mean the delivery system is not keeping up |
| Active | Selected for a delivery attempt | A large, persistent active set points to current congestion |
| Deferred | A prior attempt ended in a temporary failure | Age and destination concentration matter more than the raw total |
| Hold | Administratively prevented from delivery | Do not release until you know why the message was held |
The Postfix qshape guidance adds the missing time dimension. Recent messages piling up for one destination indicate a different problem from a long tail of old, low-rate failures. Incoming and active congestion deserve faster attention because they can delay otherwise healthy mail.
Before continuing, save the evidence without copying private message bodies into a ticket:
incident_dir="$HOME/postfix-incident-$(date -u +%Y%m%dT%H%M%SZ)"
umask 077
mkdir -p "$incident_dir"
sudo postqueue -p > "$incident_dir/queue.txt"
sudo postconf -n > "$incident_dir/postconf-n.txt"
sudo journalctl -u postfix --since '2 hours ago' --no-pager > "$incident_dir/postfix-journal.txt"
Queue data can contain sender and recipient addresses. Keep the directory private, redact addresses before sharing, and follow the organization’s retention policy.
Choose a representative queue ID from the dominant failure group. Do not begin with the oldest random message if most recent failures show another pattern.
queue_id='REPLACE_WITH_QUEUE_ID'
sudo postcat -q "$queue_id" | sed -n '1,45p'
sudo journalctl -u postfix --since '2 hours ago' --no-pager | grep -F "$queue_id"
On systems that write /var/log/mail.log or /var/log/maillog, search the appropriate file instead. postcat may expose headers, addresses and message content, so use it only with authorization and avoid pasting its raw output into public issue trackers.
The last SMTP response usually provides two useful facts: a three-digit status and an enhanced status such as 4.7.1 or 5.7.26.
status=sent means the next server accepted the message. It does not guarantee inbox placement or that a user read it.One queue can contain several incidents. Group by destination, sender and delay reason instead of applying one change to every message.
| Evidence in the log | Likely boundary | Next safe check |
|---|---|---|
connect ... timed out across many domains |
Outbound network, provider port policy or firewall | Test DNS and TCP reachability to one logged MX; confirm provider policy |
Host or domain name not found |
Local resolver or recipient DNS | Query the recipient MX and the chosen MX address from the VPS |
SASL authentication failed to a relay |
Relay credentials or allowed sender identity | Verify the relay configuration and credential source without printing the secret |
Repeated 421, 450 or 4.7.x for one provider |
Remote temporary policy or throttling | Measure destination concentration and wait for normal backoff |
5.7.26 or unauthenticated-sender rejection |
SPF, DKIM or DMARC alignment | Validate the actual sending domain and signed message headers |
| Sudden volume from an unfamiliar local user or web app | Compromise, form abuse or broken automation | Stop the producer, preserve logs and rotate exposed credentials |
No space left on device or write errors |
Disk space or inode exhaustion | Inspect filesystem usage before touching queue files |
These checks establish the local baseline without changing Postfix:
sudo postfix check
sudo postconf mail_version myhostname relayhost
df -h
df -i
resolvectl query example.net
dig +short MX example.net
Replace example.net with a destination from the real failure. A network test should also use the exact MX host recorded in the log; do not assume a provider’s current mail exchanger name from an old tutorial.
For policy rejections, compare the sending identity with current receiver rules. Google’s email sender guidelines require authentication, valid forward and reverse DNS and TLS for Gmail delivery, with additional SPF, DKIM and DMARC requirements for bulk senders. Those controls are not Postfix queue tuning parameters. Fix the identity or sending practice rather than increasing concurrency.
If the queue is growing, first determine what is creating new mail. A vulnerable form, a leaked application credential or a failed newsletter job can refill the queue faster than Postfix drains it.
Pause the specific application worker, campaign or cron job when its ownership is confirmed. Keep unrelated transactional paths running if the architecture permits it. Then record:
Do not edit files under /var/spool/postfix by hand. Avoid deleting the deferred queue simply to make the count reach zero. A shorter queue is not a recovery if legitimate mail disappeared. If the backlog is confirmed spam, treat cleanup as a separate, approved incident step after preserving evidence and closing the submission path.
Operators who do not want to own this incident boundary can use a managed hosting service to handle the mail stack, DNS identity and recovery checks. Self-management on an operational Linux VPS provides more control, but it also makes queue privacy, abuse response and deliverability the operator’s responsibility.
Change the smallest relevant layer. Examples include restoring a failed resolver, opening a provider-approved outbound route, replacing expired relay credentials, fixing a sender domain’s authentication, or stopping a compromised application account.
Validate Postfix configuration before reload:
sudo postfix check
sudo postconf -n
sudo systemctl reload postfix
sudo systemctl is-active postfix
sudo journalctl -u postfix --since '10 minutes ago' --no-pager
postconf -n can contain hostnames and relay details. Review it privately and never add passwords directly to an incident document. If a relay password map changed, rebuild it according to the installed distribution and relay documentation, protect the source file with restrictive permissions, and confirm the secret did not enter shell history.
Avoid opportunistic fixes that weaken TLS or disable authentication merely to make one test pass. A successful insecure delivery attempt can hide the real mismatch and create a larger security problem.
After the cause is fixed, schedule a single representative deferred message:
queue_id='REPLACE_WITH_QUEUE_ID'
sudo postqueue -i "$queue_id"
sudo journalctl -u postfix --since '5 minutes ago' --no-pager | grep -F "$queue_id"
Confirm a new status=sent result or a materially different error. Also verify that the receiving system accepted the intended sender and that application behavior is normal.
Only after several representative messages succeed should you allow Postfix’s normal retry schedule to drain the backlog. A full postqueue -f attempt is not a routine health check. The official manual warns that frequent flushing of undeliverable mail can reduce performance for other deliveries.
If the error is a remote 4xx, normal backoff is usually safer than hammering the destination. If the failure is permanent, repair the sender, recipient or policy condition first; retrying unchanged mail only repeats the rejection.
A service that says active is not enough. Recovery requires evidence across the queue, logs and application:
status=sent results without a new warning pattern.Run the original snapshot commands again and compare them with the incident baseline. For monitoring, alert on both queue depth and oldest message age. A small queue with one critical message delayed for hours can matter more than a brief burst of hundreds that clears normally.
An independent monitor is useful because a mail alert cannot report that its own mail path is broken. The same outside-the-failure-domain principle used for a private Uptime Kuma monitor applies here: deliver the queue alert through another provider or channel, and test both the alarm and recovery notification.
If the VPS still lacks a clean administrator account, current packages and deliberate firewall rules, complete the Linux VPS first-login baseline before treating Postfix as an isolated appliance.
| Situation | Fit | Reason |
|---|---|---|
| Postfix already worked and outbound mail is delayed | Strong fit | Queue IDs and logs can isolate the changed boundary |
| One application suddenly generates abnormal mail | Strong fit | Evidence and containment protect the rest of the queue |
| Building a public mail server for the first time | Incomplete | DNS, inbound security, spam controls and mailbox design need a separate plan |
| Recovering a damaged sending-IP reputation | Incomplete | Queue repair cannot erase blocklists, spam complaints or receiver history |
| Provider blocks outbound SMTP | Partial | Use an approved relay or resolve provider policy; tuning Postfix cannot bypass it |
| Queue contains sensitive or regulated messages | Conditional | Access, evidence sharing and deletion require organizational policy |
The honest limitation is that Postfix can queue and retry mail, but it cannot make a receiver trust an unauthenticated domain, repair a compromised web application, or override a network provider’s SMTP restrictions.
Take a private queue and log snapshot, select one representative queue ID, and classify its last SMTP response. Stop the producer if volume is still growing. Repair one confirmed cause, retry that one ID, and compare queue age before allowing normal delivery to continue. Document the result so the next incident starts with known-good evidence instead of a blind flush.
No. Age, growth rate, active/incoming congestion and destination concentration determine urgency. An old stable tail differs from a fresh backlog that is delaying healthy mail.
postqueue -f when mail is delayed?Not first. Diagnose and repair the cause, then retry one representative queue ID. Frequent full flushes can waste delivery capacity and repeat the same remote failure.
A 4xx response is temporary and normally leads to a deferred retry. A 5xx response is permanent for that attempt and requires a sender, recipient, authentication or policy correction.
Only after confirming ownership, preserving required evidence and separating junk from legitimate mail. Queue deletion is irreversible and should not be the default recovery step.
status=sent prove the message reached the inbox?No. It proves the next SMTP server accepted the message. Inbox placement, forwarding and later filtering happen beyond that acceptance point.
Measure queue depth, oldest message age and growth rate, then route alerts through an independent provider or channel. Test the failure alert and the recovery notification.