Mailing through the database is not a good decision ... This is an extra load on the base, and therefore a drop in performance, no timeouts for the task (you need to write your crutch), no extensibility, etc. In fact, sending through the database you just write your own handwritten queue at the relational storage, but why write a bicycle when it is already written? :)
The correct solution is to use a message queue (tasks). They are designed to do the following tasks:
- deferred processing of user data;
- transfer of statistics;
- smoothing the load on a relatively slow system;
- performing periodic tasks.
Advantages of this solution:
- Sending letters is universal from any component of the system, even if it is a registration form or your newsletter. Imagine how cool, you have one interface to send, and you just send the task from anywhere without going to connect the library to send letters.
- Extensibility - you can add absolutely any distribution channel by simply adding a field type (sms, call, letter, Russian post) and supporting it in the handlers.
- The time to add a task is always instant for the client adding the message to the queue.
- The ability to speed up mailing just by adding a few more Workers
- Reliability - added messages to the queue will not be lost (if so configured), and the task will be considered completed only when the script says that everything is ok. To protect yourself from spoiling the queue daemon, you can deploy a cluster.
- Relatively fast integration into architecture
You have a Publisher publishing a message to the queue that you need to send a letter to such and such addressee, with such a text, then there are consyumers (workers) who take these tasks from the queue and send letters to customers. If the cosumer fell, could not send, it simply returns the task to the queue back and it will be taken by another consumer who will try to send it.
In terms of architecture, I think we figured out, then we will move on to how to get around the restriction on hosting and send letters. If you want to send large volumes, then you can use the service of sending emails with an API, for example, Mailgun , which allows you to send 10,000 emails per month for free, although it is possible that this is still not enough for you ..
There are services that are engaged in purely mailing - for example, unisender - even then you can not write anything , but simply upload your base of emails there and send them letters.
To limit the number of transmitted messages, use some kind of storage to store the number. You can create a table in the database and write with an atomic operation to it how many letters were sent in the current hour and stop sending when the interval is exceeded. You can add a case, stating that if the limit is over in the main delivery channel, we send it via the secondary one.
I would recommend that you switch from a regular hosting to a VPS for solving such problems, due to the possibility of your own administration and the absence of restrictions on sending emails.