How to flush postfix queue one mail at a time?

Sometimes, mails stay stuck in my postfix queue, the distant server saying "Too many connections, slow down". I already configured my postfix for specific domains to send only one mail per second, but sometimes it seems insufficient.

I know of postqueue -f, but it send all mails at the same time and the mails stays in queue with the same status.

I would like to flush the queue of a postfix one mail at a time, let's say one mail every second (or 2, or more).

It's possible to flush one particular email, instead of the whole queue. If you do this for each message in turn, with a two-second sleep between messages, that should do what you ask for.

First, you need to find the queue IDs of the mails in the queue. You can get this by using the command postqueue -p. Here's an example output:

-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
6777D6E1E      3517 Mon Jan 25 03:03:02  sender@example.se
recipient@example.com

69F6471CA      2820 Tue Jan 26 03:24:17  sender@example.se
recipient@example.net


What you need is in the first column. You can get all of the IDs by some piping through grep and cut, like so:

[jenny@sameen ~]$postqueue -p | grep -v ^- | grep -v "(" | cut -d' ' -f1 |grep -e [[:alnum:]] 6777D6E1E 69F6471CA  Now that you know how to get at the IDs, you can throw them in a bash loop with some sleep: [jenny@sameen ~]$ for ID in postqueue -p | grep -v ^- | grep -v "(" | cut -d' ' -f1 |grep -e [[:alnum:]] ; do postqueue -i $ID; sleep 2; done  • Nearly perfect, just had to exclude lines beginning with "(", thanks ! Which gives : for ID in postqueue -p | grep -v ^-| cut -d' ' -f1 |grep -e [[:alnum:]] | grep -v "("; do postqueue -i$ID; sleep 2; done – vincent.m Jan 29 '16 at 15:52
• First of all, congratulations to @JennyD for the great idea and to @vincent.m for the necessary improvement (I have done +1 to both of you). Unfortunately vincent.m's answer has the backtick in the wrong position. Here you are the correct command, tested in Debian 8: for ID in postqueue -p | grep -v ^-| cut -d' ' -f1 |grep -e [[:alnum:]] | grep -v "("; do postqueue -i \$ID; sleep 2; done – lucaferrario Aug 28 '17 at 8:56
• Thanks @lucaferrario, I've updated the answer to include your edit - except that I moved the grep -v "(" earlier, since I usually want to get rid of all the lines that shouldn't be processed before starting the processing. Thanks for the heads-up on the errors! – Jenny D Aug 28 '17 at 9:14
• Thanks to both of you, i'm still using this every once in a while ! – vincent.m Sep 7 '17 at 9:59