A small guide to send mails using doctrine for queue in Mautic 5

Hi, thanks … sorry, only saw it today. Will have a look into it and probably create a new version soon. I also plan to improve it further.

1 Like

This version I shared in this thread days ago is far better, it let you control hours of send

#!/bin/bash
set -euo pipefail

########################################

USER CONFIG – EDIT THIS SECTION

########################################

Paths

PHP_BIN=“/usr/bin/php”
MAUTIC_BIN=“/mautic_installation_dir/marketautomation/bin/console”
LOCKFILE=“/mautic_installation_dir/var/lock/consume_mautic.lock”

Lock timeout (seconds)

LOCKFILE_TIMEOUT=50

Working days (ISO: 1=Mon … 7=Sun)

Default: Monday–Friday

WORKING_DAYS=(“1” “2” “3” “4” “5”)

Time window (24h format, server time)

START_HOUR inclusive, END_HOUR exclusive.

Example: 8–18 = from 08:00 up to 17:59

START_HOUR=8
END_HOUR=18

Burst & run limits

INTERVAL=2       # seconds between bursts
PER_BURST=6      # messages per burst
HARD_LIMIT=50    # max seconds this worker is allowed to run per execution

Messenger limits

TIME_LIMIT=1     # seconds for messenger:consume
MEMORY_LIMIT=“1096M”

########################################

DO NOT EDIT BELOW THIS LINE

########################################

Day & time restriction

DOW=$(date +%u)   # 1=Mon … 7=Sun
HOUR=$(date +%H)  # 00..23

Check working day

IS_WORKING_DAY=false
for d in “${WORKING_DAYS[@]}”; do
if [ “$d” = “$DOW” ]; then
IS_WORKING_DAY=true
break
fi
done

if [ “$IS_WORKING_DAY” = false ]; then
echo “Not a working day. Allowed days: ${WORKING_DAYS[*]}. Exiting…”
exit 0
fi

Check time window

if [ “$HOUR” -lt “$START_HOUR” ] || [ “$HOUR” -ge “$END_HOUR” ]; then
echo “Outside allowed time window (${START_HOUR}:00–${END_HOUR}:00). Exiting…”
exit 0
fi

Lock handling

if [ -e “$LOCKFILE” ]; then
LOCKFILE_AGE=$(( $(date +%s) - $(stat -c %Y “$LOCKFILE”) ))
if [ “$LOCKFILE_AGE” -ge “$LOCKFILE_TIMEOUT” ]; then
echo “Lock older than ${LOCKFILE_TIMEOUT}s. Removing stale lock…”
rm -f “$LOCKFILE”
else
echo “Process already running (lock younger than ${LOCKFILE_TIMEOUT}s). Exiting…”
exit 1
fi
fi

touch “$LOCKFILE”
trap ‘rm -f “$LOCKFILE”’ EXIT INT TERM

Burst sending loop

SENT=0
START_TS=$(date +%s)

while (( $(date +%s) - START_TS < HARD_LIMIT )); do
“$PHP_BIN” “$MAUTIC_BIN” messenger:consume email 
–limit=“$PER_BURST” 
–time-limit=“$TIME_LIMIT” 
–memory-limit=“$MEMORY_LIMIT”

SENT=$((SENT + PER_BURST))

NOW=$(date +%s)

If sleeping would push us past HARD_LIMIT, break without sleeping

if (( NOW - START_TS + INTERVAL >= HARD_LIMIT )); then
break
fi

sleep “$INTERVAL”
done

echo “Total planned in ~${HARD_LIMIT}s (bursts of $PER_BURST every ${INTERVAL}s): $SENT”
exit 0
1 Like

I read this thread and I’m still having questions. We have the standard setting that mails are being send out immediately. Sometimes this causes errors while sending, especially for large mailings (10.000+). The AWS EC2 instance can’t handle everything and we have to reboot the instance or we ran into problems with the limit of 18 mails we can send per second with AWS SES.

I’ve looked at various sources and see different ways to set up the queue, but I think I’m also reading contradictions, so I still don’t fully understand it. I read about scripts, but i’m not really confident and familiar with these methods, so I would like to avoid that.

I have the following questions:

  1. Can I just set the queue settings (Mautic 7.0.0) to:
    Schema → doctrine
    Host → default
    And then setup the cronjob → php /www/var/html/bin/console messenger:consume email --time-limit=55 –limit=1000

This seems the simplest way So without any scripts.
But I’m not sure if the –limit doesn’t conflict with the maximum of 18 mails per second AWS SES allows me to send. I read that this can still mean the 1000 e-mails are being sent right away and not evenly spread out during one minute.

  1. Can I use the broadcast and messenger:consume cronjob together when scheduling a segment mail?

Hi @klaasvna - you probably need to test drive your setup. The way you describe it doesn’t limit mails per second in any way. If you server is fast enough - too fast - AWS may drop mails above limit as far as I know.

Regarding your 2nd question:
It goes through a two-stage process:

  1. mautic:broadcasts:send (The Producer) This command looks for any published segment emails that are due to be sent. Instead of sending the mail directly to the recipient’s inbox, it packages the emails into “jobs” and pushes them into your message queue (e.g., Doctrine, RabbitMQ, or Redis).

  2. messenger:consume email (The Consumer) This command is the “worker.” It watches the queue, picks up the jobs created by the broadcast command, and actually handles the heavy lifting of communicating with your SMTP or API provider (like Amazon SES or Mailgun) to deliver the message.