70

What's the postfix equivalent to sendmail -bp?

10 Answers 10

86

Or, less typing:

mailq
32
postqueue -p
30
qshape active

will show you the number of emails being sent to each domain and how long they have been in the active queue

qshape deferred 

will show you the same but for the deferred queue

21

Here's what I use, culled from the postfix mailing list. I removed the author's name, in case he doesn't want it here (you can see it at the source). It only displays totals.

#!/usr/bin/env perl

# postfix queue/s size
# author: 
# source: http://tech.groups.yahoo.com/group/postfix-users/message/255133

use strict;
use warnings;
use Symbol;
sub count {
        my ($dir) = @_;
        my $dh = gensym();
        my $c = 0;
        opendir($dh, $dir) or die "$0: opendir: $dir: $!\n";
        while (my $f = readdir($dh)) {
                if ($f =~ m{^[A-F0-9]{5,}$}) {
                        ++$c;
                } elsif ($f =~ m{^[A-F0-9]$}) {
                        $c += count("$dir/$f");
                }
        }
        closedir($dh) or die "closedir: $dir: $!\n";
        return $c;
}
my $qdir = `postconf -h queue_directory`;
chomp($qdir);
chdir($qdir) or die "$0: chdir: $qdir: $!\n";
printf "Incoming: %d\n", count("incoming");
printf "Active: %d\n", count("active");
printf "Deferred: %d\n", count("deferred");
printf "Bounced: %d\n", count("bounce");
printf "Hold: %d\n", count("hold");
printf "Corrupt: %d\n", count("corrupt");

EDIT: Fixed a typo on line 26.

3
  • Great script, and IMHO should be a part of the standard Postfix distribution. Unlike mailq/postqueue returns immediate answer for a queue under duress Aug 14, 2012 at 16:27
  • 1
    Just a word of caution on the particular implementation of count function. It will fail in Postfix 2.9+ when enable_long_queue_ids=yes'. I think it should not be too hard to fix it for long queue ids. Aug 15, 2012 at 15:58
  • Fixed version posted below, serverfault.com/a/1119113/52485. Dec 30, 2022 at 4:00
15

postqueue -p | tail -n 1

Last line in the postqueue -p shows how many requests and size:

-- 317788 Kbytes in 11860 Requests.

1
  • 1
    This command executes quickly since it doesn't waste cycles displaying the individual emails in the queue. If just want the total, run this. Nov 16, 2017 at 17:35
6

[root@server ~]# time mailq | grep -c '^[0-9A-Z]'

10

real 0m1.333s

user 0m0.003s

sys 0m0.003s

(above result indicating that there are 10 email is queue)

1
  • 3
    More concisely: mailq | grep -c '^\w' Mar 28, 2013 at 8:51
6

If you don't have qshape you can install it via the following yum commands:

yum groupinstall perl development
yum install postfix-perl-scripts

qshape prints Postfix queue domain and age distribution information. You can read more about it here:

http://www.postfix.org/QSHAPE_README.html

Example output

% qshape -s hold | head
                         T  5 10 20 40 80 160 320 640 1280 1280+
                 TOTAL 486  0  0  1  0  0   2   4  20   40   419
             yahoo.com  14  0  0  1  0  0   0   0   1    0    12
  extremepricecuts.net  13  0  0  0  0  0   0   0   2    0    11
        ms35.hinet.net  12  0  0  0  0  0   0   0   0    1    11
      winnersdaily.net  12  0  0  0  0  0   0   0   2    0    10
           hotmail.com  11  0  0  0  0  0   0   0   0    1    10
           worldnet.fr   6  0  0  0  0  0   0   0   0    0     6
        ms41.hinet.net   6  0  0  0  0  0   0   0   0    0     6
                osn.de   5  0  0  0  0  0   1   0   0    0     4
3

Here is an example.

#!/bin/bash

for q in active  bounce  corrupt  defer  deferred  flush  hold  incoming  maildrop  pid  private  public  saved  trace

    do
        count=$(find /var/spool/postfix/$q ! -type d -print | wc -l)
        echo $q $count
    done
2

I have jq on my system. I like the following approach a lot:

postqueue -j | jq -s 'group_by(.queue_name) | map({"queue": .[0].queue_name, "count": length})'
[
  {
    "queue": "active",
    "count": 2
  },
  {
    "queue": "deferred",
    "count": 314
  },
  {
    "queue": "hold",
    "count": 2630
  }
]
1

Elaborating on @mikewater's answer here, since it didn't fit in a comment: this should handle old and new postfix and also shows the total.

#!/usr/bin/env perl

# pfq - quickly print postfix queue sizes.
# Unlike mailq/postqueue returns immediate answer for a queue under duress.
#
# http://tech.groups.yahoo.com/group/postfix-users/message/255133,
# https://serverfault.com/a/329884/52485,
# SM

use strict;
use warnings;
use Symbol;
sub count {
    my ($dir) = @_;
    my $dh = gensym();
    my $c = 0;
    opendir($dh, $dir) or die "$0: opendir: $dir: $!\n";
    while (my $f = readdir($dh)) {
        if ($f =~ m{^([A-F0-9]|[0-9B-Zb-z]){5,}$}) {
            ++$c;
        } elsif ($f =~ m{^[A-F0-9]$}) {
            $c += count("$dir/$f");
        }
    }
    closedir($dh) or die "closedir: $dir: $!\n";
    return $c;
}
my $qdir = `postconf -h queue_directory`;
chomp($qdir);
chdir($qdir) or die "$0: chdir: $qdir: $!\n";
my $incoming = count("incoming");
my $active   = count("active");
my $deferred = count("deferred");
my $bounce   = count("bounce");
my $hold     = count("hold");
my $corrupt  = count("corrupt");
printf "Incoming: %7d\n", $incoming;
printf "Active:   %7d\n", $active;
printf "Deferred: %7d\n", $deferred;
printf "Bounced:  %7d\n", $bounce;
printf "Hold:     %7d\n", $hold;
printf "Corrupt:  %7d\n", $corrupt;
printf "-----------------\n";
printf "Total:    %7d\n", $incoming + $active + $deferred + $bounce + $hold + $corrupt;

And a wrapper to make testing easy:

#!/bin/bash                                                                                                                                                                       
# pfqcheck [N] - Check for no more than N queued postfix messages, default 50.                                                                                                    
                                                                                                                                                                                  
MAX="${1:-50}"                                                                                                                                                                    
NUM=$(pfq | tail -1 | awk '{print $2;}')                                                                                                                                          
MSG="$NUM queued emails, limit is $MAX"                                                                                                                                           
if [[ $(expr "$NUM" '<=' "$MAX") == 1 ]]                                                                                                                                          
then echo "ok: $MSG"; exit 0;                                                                                                                                                     
else echo "fail: $MSG"; exit 1;                                                                                                                                                   
fi                                                                                                                                                                                

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .