There are two ways to configure how Magento send order related emails (order confirmation, invoice, shipment and credit memo emails):
- Either immediately when an action is performed (for example, right after you place an order).
- Or cron-based (asynchronous).
Magento itself recommends to configure this to be asynchronous for performance reasons, so the email dispatch process doesn't block nor delay what the customer is doing (for example, less time consumption when the customer is placing an order), or to avoid long cron runs (or total crons block) when an ERP is updating orders status in bulk.
Enabling the “Asynchronous email notifications” setting moves processes that handle checkout and order processing email notifications to the background.
Configuration best practices by Magento
For my personal experience, it is also recommended to configure emails sending to be asynchronous to avoid having unsent emails.
When this is configured as immediately (not async), if an email fails to be dispatched because of any reason (like a server timeout) then Magento won’t try to send that email again in the future and the customer won’t be ever notified of his/her action.
Basically, there are a lot of good reasons to have this to be async.
Before setting this up
If you are going live for the first time on a new site there's not much to worry about, but if you are changing this setting from not-async to cron-based on an already live site then there's something to consider first.
The way this works when it's configured to be async is that Magento will rely on a cron to pick up from the database (from those tables related to Orders, Invoices, Shipments and Credit Memos) all those entities where the email was not dispatched, and it will send it.
Problem is that Magento doesn't care much about the date of those entities.
For example, if there’s an Order from 2019 whose order confirmation email was not sent because of any reason (for example, because there was a PHP error that stopped the execution), the cron will now pick this Order up and Magento will send the email related to that order.
To avoid this behaviour we should mark all pending emails from Orders, Invoices, Shipments, and Credit Memos as if they doesn't need to be dispatched, which can be done by executing the following SQL statements before enabling the asynchronous sending.
UPDATE sales_order SET send_email = 0;
UPDATE sales_invoice SET send_email = 0;
UPDATE sales_shipment SET send_email = 0;
UPDATE sales_creditmemo SET send_email = 0;
What we are doing here is ignoring the sending of emails for old Orders (and Invoices, Shipments and Credit Memos) so when we change this to be async the cron will only cares for future stuff.
Changing the configuration
Enable the “Asynchronous sending” option under “Stores → Settings → All Stores → Sales → Sales Email → General Settings”.