Messenger Setup

Messenger Setup

This documentation is for SuiteCRM 8.10.0+

What is the Messenger Worker?

SuiteCRM 8 uses Symfony Messenger to process background tasks in a separate worker process, keeping the web server responsive. Without a running worker, async tasks (manual migrations, bulk exports, etc.) will remain in "Pending" status indefinitely.

For an overview of the async task system and its benefits, see the Async Tasks overview.

Before You Begin

All Messenger worker commands in this guide must be run as the same system user that runs your web server. Common web server users include:

  • www-data (Debian/Ubuntu)

  • apache (RHEL/CentOS with Apache)

  • nginx (RHEL/CentOS with Nginx)

If the worker runs as a different user, file operations (uploads, media object storage) will fail with permission errors.

Throughout this page, examples use www-data as a placeholder — replace it with your actual web server user.

Running the Worker in Production

In production, the worker should run continuously and restart automatically if it stops. The recommended approaches are:

Supervisor is a process manager that keeps the worker running and restarts it when it exits (e.g. after reaching the time limit).

Assuming you have systemd supervisor, you can create a configuration file at /etc/supervisor/conf.d/suitecrm-messenger.conf:

[program:suitecrm-messenger]
command=php /path/to/suitecrm/bin/console messenger:consume internal-async --time-limit=3600 --memory-limit=256M
user=<web-server-user>
numprocs=1
autostart=true
autorestart=true
startsecs=0
startretries=10
process_name=%(program_name)s_%(process_num)02d
stderr_logfile=/var/log/supervisor/suitecrm-messenger.err.log
stdout_logfile=/var/log/supervisor/suitecrm-messenger.out.log

Replace <web-server-user> with your web server user (e.g. www-data, apache, nginx).

Then reload Supervisor:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start suitecrm-messenger:*

Set numprocs to 1 unless you have tested and confirmed that your tasks are safe to run with multiple concurrent workers. Running multiple workers can cause duplicate processing if tasks are not designed for concurrency.

Option 2: systemd

Assuming you have systemd installed, you can create a systemd service file at /etc/systemd/system/suitecrm-messenger.service:

[Unit]
Description=SuiteCRM Messenger Worker
After=network.target

[Service]
Type=simple
User=<web-server-user>
Group=<web-server-user>
ExecStart=/usr/bin/php /path/to/suitecrm/bin/console messenger:consume internal-async --time-limit=3600 --memory-limit=256M
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Replace <web-server-user> with your web server user (e.g. www-data, apache, nginx).

Then enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable suitecrm-messenger
sudo systemctl start suitecrm-messenger

Option 3: Cron (simple setups)

If you cannot use Supervisor or systemd, you can use cron to start the worker periodically. The --time-limit flag ensures old workers exit before new ones start.

Add the following entry to your web server user’s crontab (e.g. sudo crontab -u www-data -e):

* * * * * php /path/to/suitecrm/bin/console messenger:consume internal-async --time-limit=55 --memory-limit=256M > /dev/null 2>&1

This starts a new worker every minute. Each worker runs for up to 55 seconds, ensuring it exits before the next one starts.

The cron approach is less efficient than Supervisor or systemd because there is a brief gap between worker restarts where no messages are being processed.

Quick Start (for Development and Testing)

To start the Messenger worker, run the following command on your server:

php bin/console messenger:consume internal-async --time-limit=3600 --memory-limit=256M

This starts a worker that:

  • Listens to the internal-async transport (the default queue for all async tasks).

  • Automatically stops after 1 hour (--time-limit=3600) to prevent memory leaks.

  • Stops if memory usage exceeds 256 MB (--memory-limit=256M).

Worker Command Options

The messenger:consume command accepts several useful options:

Option Description

--time-limit=<seconds>

Stop the worker after the specified number of seconds. Recommended to prevent memory leaks from long-running processes.

--memory-limit=<bytes>

Stop the worker if memory usage exceeds this limit (e.g. 256M, 512M).

--limit=<count>

Stop the worker after processing the specified number of messages.

--sleep=<seconds>

Time to wait (in seconds) when no messages are available before polling again. Default: 1.

-vv

Verbose output — shows each message as it is received and processed. Useful for debugging.

Verifying the Worker is Running

Depending on the option you’ve chosen, there are several ways you can check whether the worker process is active on your system, a more generic one is:

ps aux | grep messenger:consume

If the worker is running, you will see a process matching the messenger:consume command. If no results appear (other than the grep command itself), the worker is not running and needs to be started.

You can also check the Messenger log file for recent activity:

logs/<env>/<env>.messenger.log

For example, logs/prod/prod.messenger.log in production.

You can increase the log verbosity by setting MESSENGER_LOG_LEVEL=info in your .env.local file (see the Configuration Reference).

Managing Failed Messages

When a message fails (e.g. due to an unhandled exception), it is moved to the failure transport. SuiteCRM provides several commands to inspect and manage failed messages:

# View all failed messages
php bin/console messenger:failed:show

# Retry a specific failed message by ID
php bin/console messenger:failed:retry <id>

# Remove a failed message by ID
php bin/console messenger:failed:remove <id>

For async tasks (Manual Migration Tasks, etc.), failures are also tracked at the item level within the task itself. You do not usually need to interact with the failure transport directly — use the task’s "Retry Failed" or "Re-run" buttons in the UI instead.

Setting Up the Messenger Database Table

By default, SuiteCRM uses Doctrine (your existing database) as the message transport — no additional infrastructure is required. This is suitable for most single-server installations.

The required messenger_messages table is created automatically when you run Admin > Repair > Quick Repair & Rebuild. In most cases, no manual action is needed.

If for any reason the table was not created, you can create it manually by running:

php bin/console messenger:setup-transports

Since SuiteCRM uses Symfony Messenger, alternative transports such as RabbitMQ (AMQP) and Redis are also available if you need to scale beyond a single server. See the Configuration Reference for transport DSN options.

Next Steps

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.