Workers & Background Tasks
What Postal workers do and how to scale them.
All mail processing in Postal happens in worker processes (postal worker). The web and SMTP servers only accept messages and place them on a queue in the main database; workers take them from the queue, deliver them, and run housekeeping tasks. Since Postal v3 there is no message broker - workers coordinate purely through the database.
You can run as many worker processes as you need, on as many hosts as you need, provided they all share the same database.
What workers do
Each worker runs a number of threads (set by worker.threads, default 2) which repeatedly take the next ready message or webhook request from the queue and process it:
- Outgoing messages are checked against the server's settings (suspension, send limit, credential hold, suppression list and development mode), optionally inspected for spam, prepared for click/open tracking, DKIM signed and delivered by SMTP to the recipient's mail server (or your configured relays).
- Incoming messages are inspected for spam and delivered according to their route.
- Webhook requests are delivered to your endpoints. See Webhooks.
Messages which fail temporarily are retried with an increasing back-off up to postal.default_maximum_delivery_attempts times (default 18, roughly 31 hours) before being hard failed. Messages for the same destination are batched onto a single connection where possible.
When IP pools are in use, a message allocated to an IP address is only processed by a worker running on a host that has that address.
Housekeeping tasks
Workers also run periodic maintenance, such as re-checking domain DNS records, applying retention settings, expiring held messages, pruning suppression lists and webhook history, and removing servers and organizations that have been deleted. Workers elect one of themselves to run these tasks so that each runs only once regardless of how many workers you have; if that worker stops, another takes over automatically.
Scaling and restarting
- To handle more mail, increase
worker.threadsand/or run more worker processes (see the postal command for the standard installation). Thepostal_message_queue_latencymetric shows how long messages are waiting to be picked up. - Each worker holds a handful of database connections per thread, so size MariaDB's
max_connectionsaccordingly when adding workers. - Workers can be restarted safely with
SIGTERM(whichdocker stopsends): they finish the message they are processing before exiting. If a worker is killed abruptly, any message it was processing stays locked and is removed from the queue by a housekeeping task afterpostal.queued_message_lock_stale_days(default 1 day) rather than retried, so avoidSIGKILLwhere possible.