How to send emails, the simple way

If you’re an experienced developer, you probably had to build lots of email templates for the workflow of your app or for the marketing. It’s frustrating isn’t it? The standard for emails is really weird, it’s a pain to test, doesn’t work the same on every email client and, sometimes, you’re asked to change a wording every 2 days, which could be done by someone else.

On my last project, I had to send transactional emails, asynchronously. It was not the first time I had to do that. I looked for some SaaS that allowed to send transactional emails through my own internal SMTP for a reasonable price. But nothing interesting.

So we decided to build a micro-service that was dedicated to sending emails. Then I remembered the many exchanges I had with the client, the product owner and the designers in order to modify the templates. I lost many hours on small things. What if the client could change the wording from a nice web application? What if the designer could change the colors and layout by himself?

Let’s make the plan

TLDR: Go take a look at the github repository at the end of this article

My needs are quite simple: sending an email and if needed, add an attachment. So I’ll make 2 endpoints:

  • POST /mails to send an email
  • POST /attachments to store a file in a cache before sending it

So, in this case, I need a cache to store a file for a few minutes and a queue to asynchronously send the email. For the cache I chose Redis, because it’s the obvious choice and RabbitMQ for the queuing system.

The workflow will be the following (in italic when I send an attachment)

  1. An application persists an attachment in the cache through the API
  2. The application tells the micro-service to send the “example” email to an email address (with the attachment) through the API
  3. The micro-service formats the request and puts it in a queue
  4. The queue tells a worker to build the template, put everything together and send the email through the configured SMTP
  5. It’s sent, the job disappears and the stored file expires

Quite simple, right? By using this architecture, I can scale up the endpoints and the workers around the RabbitMQ and the Redis instance.

Basic representation of the architecture

But wait… I talked to you about a nice interface where your client or designer could have some fun without slowing you down… Well, now think about where the templates of the emails are coming from. In the schema above, we can suppose that the templates are stored on the filesystem. But that’s not really convenient. Let’s introduce a SaaS from which we can fetch the templates.

Architecture with the template provider

Ok, now it’s complete. Let’s redo our workflow (without the attachments to make it clear).

  1. The application tells the micro-service to send the “example” email to an email address through the API
  2. The micro-service formats the request and puts it in a queue
  3. A worker takes the job and fetches the template from Jolimail
  4. The worker puts everything together and sends the email through the configured SMTP
  5. It’s done.

Not way more complicated than the previous version, no more template on the file system or in your versioning system. It’s cleaner!

Ok, now we have a nice architecture but it kind of has an inconvenient. RabbitMQ has a big footprint and we only use one queue. What about using Redis as a queue? Well, we can, there are some libraries to do that in a simple way. So here is the final architecture.

Final architecture

Time to work!

And because I like the language, and also because I know I’ll have all the tools I need for the implementation, I decided to make this micro-service in nodejs.

The work on the micro-service is all done. You just need to create a template on, set the environment variables, start it and you’re all set up. You can deploy it on Heroku or use it on any machine with the docker image.


You don’t need to implement a mailing system and spend your time exchanging with the team regarding the comma that is missing in that order confirmation email.

You can now dedicate your whole time implementing cool features, like a magic link authentication system or whatever else… And if you want to improve this micro-service, a pull request is always welcomed!

You expected more from this article? I’ll be writing other articles in addition to this one, but in the meantime if you have questions or need more details, you can leave a comment on this article…

If you want to see what we do, or who we are, take a look at our website