Postfix is a modular, queue-based MTA where mail flow depends on a chain of cooperating daemons, filesystem-backed queues, DNS resolution, and external filters. Monitoring maturity is not about collecting more metrics for their own sake. It is about closing the gap between what you can detect and what actually causes incidents: inode exhaustion hiding behind “No space left on device,” active queue saturation from one slow destination, silent filter backpressure, or deferred queues that grow for hours before anyone notices.

This four-level progression maps survival checks to expert-grade observability. Identify your current level, then target the signals at the next level that close your biggest blind spots. The model reflects incident patterns where teams had monitoring in place but still missed the signal that mattered. The gap was rarely “no monitoring” – it was monitoring the wrong layer, or collecting a metric without alerting on its rate of change.

flowchart TD
    L4["Level 4: Expert
Latency distributions, per-transport
throughput, reputation checks"] L3["Level 3: Mature
Per-destination metrics, filter health,
queue breakdown, pattern detection"] L2["Level 2: Operational
Flow rates, bounce rate, TLS,
security signals, inode monitoring"] L1["Level 1: Survival
Master alive, ports listening,
queue not growing, disk not full"] L1 --> L2 --> L3 --> L4

Level 1: Survival

Survival monitoring answers one question: is Postfix running and can it accept mail? If any of these checks fail, you have a complete outage. These are the signals your paging system must cover before anything else.

SignalWhy it mattersWhat to check
Master process livenessNo master means no mail reception or delivery. Complete outage.PID file at /var/spool/postfix/pid/master.pid exists and references a running process named master.
SMTP listener responsiveSocket present but no greeting means master issue or all smtpd processes busy.TCP connect to port 25, expect a 220 greeting with your hostname within 2 seconds.
Total queue not growingUnbounded queue growth is the earliest indicator of delivery failure.Count files across all queue subdirectories. Compare against a rolling baseline.
Queue partition has spaceDisk full halts all mail I/O immediately.df -h /var/spool/postfix below your alert threshold (typically 90%).

Master PID file check. The PID file must exist and point to a running process. A stale PID file after an unclean shutdown is a common false positive. Compare the PID file mtime against the process start time to detect this. In containers, PID namespace confusion can cause the PID file to reference PID 1 or the wrong namespace entry.

Greeting test. A TCP socket that accepts connections but never sends a 220 banner means the smtpd pool is exhausted or the master process is stuck. Test the full path, not just the port bind. If postscreen is enabled, it answers on port 25 and passes to smtpd internally, so test both the postscreen path and the backend smtpd path.

Queue size as a survival signal. At this level you do not need per-queue breakdowns. You need to know whether the total file count is trending up. A static threshold (for example, “page if total queue exceeds 50,000”) is sufficient for survival. Velocity-based alerting comes at Level 2.

Disk space only. Level 1 tracks disk space, not inodes. This is a known blind spot. Most teams at this level have been surprised by “No space left on device” when df -h shows 40% free. Inode monitoring arrives at Level 2, but if you take one thing from this article before finishing, add df -i to your survival checks today.

Level 2: Operational

Operational monitoring adds early warning. You can detect degradation before it becomes an outage. The focus shifts from “is it running?” to “is it draining?”.

SignalWhy it mattersWhat to check
Injection vs delivery ratePersistent injection exceeding delivery causes queue growth.Parse logs for client= (injection) and status=sent (delivery) over 5-minute windows. Ratio should be near 1:1.
Deferred rateHigh deferred ratio indicates destination problems or policy rejections.Count status=deferred lines. Healthy systems run below 5% of injection. Above 20% warrants investigation.
Active queue vs limitActive queue at qmgr_message_active_limit means the queue manager cannot schedule new deliveries.Compare active queue file count against postconf -h qmgr_message_active_limit (default 20,000).
Deferred queue growth rateVelocity matters more than absolute size. A static 5,000 that is shrinking is fine. The same 5,000 growing at 1,000/hour is not.Track the derivative of deferred queue file count over time. Any sustained positive growth over 4 hours is abnormal.
Bounce rateHigh bounce rates damage IP reputation and indicate data quality or routing problems.Count status=bounced lines. Above 1% sustained for transactional mail warrants a ticket. Above 5% is critical.
Inode utilizationPostfix creates one file per queued message plus metadata. Inodes exhaust before disk space.df -i /var/spool/postfix. Alert below 10,000 free inodes or above 90% usage.
File descriptor countEach connection and queued message consumes an fd. Exhaustion halts new connections.Sum open fds across Postfix processes. Compare against ulimit -n. Alert above 80% of soft limit.
SMTPD process utilizationServices at maxproc cause “to limit” log messages and connection delays.Check for to limit in logs. Monitor smtpd process count against maxproc in master.cf.
TLS certificate expirationExpired certificates cause mandatory TLS destinations to defer silently.Monitor both inbound (smtpd) and outbound (smtp) certificate expiry dates. Do not forget client certificates for mutual TLS.
Authentication failure rateBrute force against submission ports (587, 465).Count SASL authentication failed lines. Baseline is very low. Above 100/minute from a single IP is active attack.
Relay denial rateConfirms smtpd_recipient_restrictions are blocking unauthorized relay attempts.Count relay access denied lines. Any successful unauthorized relay is a security incident.

The deferred growth trap. Teams at this level often set a static threshold (“page if deferred exceeds 10,000”) and miss the transition from linear to exponential growth. Once throughput saturates, retried messages compound new arrivals. Track the rate of change, not just the absolute count. A deferred queue growing at 1,000 messages/hour with no plateau is a page, regardless of total size.

Inodes, not just bytes. This is the single most common gap at every level. Postfix stores each queued message as an individual file with associated metadata. A deferred queue with hundreds of thousands of messages can exhaust inodes while df -h shows ample free space. The error message “No space left on device” is technically correct but deeply misleading. XFS dynamically allocates inodes and is less susceptible, but ext4 with default inode density is vulnerable on /var partitions.

File descriptors in production. The default soft limit (often 1024) is inadequate for production mail servers. Each smtpd process, each queued message being processed, and each network connection consumes file descriptors. Monitor the sum across all Postfix processes and compare against the configured limit. Production servers commonly need 65,536 or higher.

Level 3: Mature

Mature monitoring moves from individual metrics to correlation. You can identify which destination is causing queue gridlock, which filter is creating backpressure, and which composite failure pattern is unfolding.

SignalWhy it mattersWhat to check
Per-destination delivery metricsOne slow destination can monopolize active queue slots via fair queueing. Identifying the destination is the first step to resolution.Parse deferred logs grouped by recipient domain. Look for one or few domains dominating.
Content filter / Milter healthFilter slowdown causes queue backup long before process failure.Monitor filter response time. Baseline is typically under 1 second. Alert at p99 above 5 seconds.
Queue subsystem breakdownKnowing which queue is growing (maildrop vs incoming vs active vs deferred) narrows the problem immediately.Track file counts per queue subdirectory independently.
Anvil connection stateRapid connection table growth indicates dictionary attack or connection pool abuse.Parse connect from lines, group by client IP. NAT/proxy environments appear as a single client.
Relay recipient map latencySlow recipient verification causes smtpd to hang before queueing.time postmap -q test@example.com hash:/etc/postfix/relay_recipients. Network-backed maps should be under 500ms.
Composite pattern detectionIndividual metrics within thresholds can still form a known failure pattern.Correlate active queue saturation with per-destination deferred rates and filter response times.

Queue gridlock pattern. Active queue near qmgr_message_active_limit with deferred growing steadily, CPU and network low, and one destination dominating deferred entries with “connection timed out” or rate-limit 4xx responses. The queue manager is working as designed, but fair queueing without priority means one slow destination stalls everything. Detecting this pattern requires correlating active queue depth, deferred growth rate, and per-destination breakdown. No single metric tells the whole story.

Filter backpressure pattern. Incoming queue growing while active queue remains small. This is the reverse of normal gridlock and is easy to miss if you only monitor deferred. The filter is accepting mail (incoming grows) but not completing processing (active stays empty because cleanup cannot finish). SMTP clients may time out and retry, amplifying load. The tell is incoming queue growth with healthy active queue depth.

Postscreen and anvil. If postscreen is enabled, its statistics reveal how effectively zombies are being blocked before reaching smtpd. Anvil tracks per-client connection counts and rates in memory. Both are cleared on restart, so there is a brief window after restart where rate limits reset. In NAT or proxy environments, all clients appear as the same IP address, which can trigger false connection count limits.

Level 4: Expert

Expert monitoring adds distributions, per-transport granularity, and external reputation signals. The focus shifts from detecting problems to predicting them.

SignalWhy it mattersWhat to check
Message age distributionAverage queue age hides long tails. A distribution reveals whether most mail flows quickly with a stuck minority, or whether the entire queue is aging.Analyze mtime of files in deferred and active directories. Bucket by age ranges.
Per-transport throughputsmtp, local, virtual, and pipe transports have different bottlenecks. Aggregate throughput hides per-transport saturation.Parse delivery logs grouped by transport. Compare throughput against configured concurrency limits per transport.
DNS latency distributionDNS is Postfix’s most critical external dependency. Latency distribution, not just failure rate, reveals resolver degradation before it causes deferrals.Postfix does not export resolver timing directly. Instrument the system resolver (unbound, systemd-resolved) or parse delay= fields from postfix/smtp log entries.
Postqueue responsivenessSlow postqueue -p response indicates queue manager under pressure.Time postqueue -p execution. Normal is under 5 seconds. Above 10 seconds indicates qmgr stress.
Predictive queue growthTime-to-full estimation based on current growth rate and remaining capacity.Calculate runway: free inodes divided by growth rate (files/hour). Alert when runway drops below a threshold.
Reputation / blocklist checksBlocklistings appear within hours of sustained high bounce rates. Proactive checks catch listings before users report them.Query major DNSBLs programmatically for your sending IP(s). Monitor sender score externally.

Message age vs message count. A deferred queue with 5,000 messages where the oldest is 10 minutes old is a transient blip. The same 5,000 messages where the oldest is 6 hours old is a delivery crisis. Count alone is insufficient. The distribution of message ages reveals whether retries are succeeding for recent messages while old messages are stuck, or whether the entire queue is aging uniformly.

Reputation as a monitoring signal. Most teams discover blocklistings when external parties report them. By then, deliverability is already damaged. Querying DNSBLs programmatically (Spamhaus, Barracuda) for your sending IPs provides early detection. Correlate with bounce rate trends: sustained bounce rates above 2% precede most blocklist appearances.

Multi-instance contention. If you run multiple Postfix instances (inbound vs outbound, per-customer, submission vs receiving), aggregate metrics hide resource starvation. One instance can exhaust file descriptors or disk I/O while others appear healthy. Per-instance resource accounting is essential at this level.

How to use this model

Assess your current state honestly. Most teams operate at Level 1 with some Level 2 signals. The gap between “we collect it” and “we alert on it” is where most incidents live. A metric you collect but never page on might as well not exist.

Pick one blind spot to close. Do not attempt to jump from Level 1 to Level 4. Pick the single most impactful signal at the next level and implement alerting for it. For most teams, that is deferred queue growth rate (velocity, not absolute size) or inode utilization.

Calibrate thresholds to your workload. The thresholds in this article are starting points. A backup MX legitimately maintains large deferred queues. A marketing sender has higher bounce baselines than a transactional sender. Establish baselines during stable operation, then set thresholds relative to those baselines.

Test recovery procedures, not just detection. Monitoring tells you something is wrong. Knowing which lever to pull (reduce destination concurrency, bypass a failed filter, hold a problem destination’s mail) is a separate skill. Document playbook steps before you need them at 3 a.m.

What teams consistently get wrong

  • Inode blind spot. Almost every major Postfix queue-growth incident eventually hits inode exhaustion. Teams monitor disk space, not inodes. Add df -i today.
  • Static thresholds on dynamic queues. A deferred queue of 5,000 that is growing is more urgent than 20,000 that is draining. Track velocity.
  • DNS as unmonitored dependency. Postfix depends entirely on DNS. Resolver failure looks like “slow mail to everyone.” Monitor resolver latency and failure rate independently.
  • Filter health measured as process liveness. “Is Amavis running” is the wrong question. “Is Amavis responding in under 2 seconds” is the right one. Slow filters cause queue backup before they crash.
  • Bounce rate blindness. Bounces count as “sent” in simple delivery metrics. Explicit bounce rate monitoring is required separately.
  • Ignoring maildrop queue. Local submission failures (cron, monitoring scripts) are invisible in SMTP logs. Pickup daemon failure manifests as missing local mail.

How Netdata helps

Netdata’s per-second collection and anomaly detection shorten the path from symptom to root cause for Postfix incidents.

  • Disk and inode metrics at per-second resolution catch the inode exhaustion cliff before it halts mail delivery. Correlating inode usage with queue file count confirms whether growth is Postfix-driven.
  • Process and file descriptor metrics reveal smtpd pool exhaustion, fd pressure, and process spawn anomalies before they cause connection failures.
  • System-level DNS latency and resolver health provide the independent DNS visibility that Postfix itself cannot surface.
  • ML-based anomaly detection on queue-related filesystem activity (file creation rate, directory growth) flags unusual patterns without requiring static thresholds that miss workload-specific baselines.
  • Correlation across system, disk, network, and process metrics in a single timeline makes it faster to distinguish between a Postfix-internal problem (active queue saturation) and an external dependency failure (DNS, filter, destination reachability).