Building A Serverless Notification App

Posted on February 27, 2019

We send a lot of notifications at my work. Over the years, you end up having various repos.

And almost all of these repos need to send notifications. Sometimes, it is just an email. Othertimes, you need to send a Slack or a text message.

It starts slowly. But, before you know it, you have several different email templates across different repositories. And, have setup a api slightly differently from several different place.

To make matters worse, sending notifications is one of the primary causes of webapps being slow.

You need to queue these notifcations to run later. But, that requires setting up a queue worker. Queue works then require you to install supervisor to make sure the worker always runs.

And, pretty soon (if your business is successful and you’re busy focusing on customer needs) you have notification a mess.

Serverless To The Rescue

Serverless to the rescue

The solution I just wrote solves all of these issues with serverless. Basically, I have one Golang endpoint that accepts post requests. It takes in a to,from,subject, and an array of strings that make up the message.

(For version two, I’m going to add a call-to-action button text & link.)

This function then creates a message on AWS SQS. AWS Simple Queue Service is an easy way for you to queue up jobs without having to manage supervisors or workers.

The response time on this endpoint is 88ms without a cold start. And 300ms with a cold start.

Usually, the email api replies in 1-2 seconds. This is quite the speed boost!

Scaling the messages

Let’s say we have a client get a bunch of leads with our software in a few seconds. In our other system, we would have to have a scaling policy written up for our queue worker.

This simply just would not happen with the resources on a engineering team of most companies sizes.

Most companies are lucky to even have a queue with a worker. Much less— a scalling policy dedicated to working through the workers.

But, now, I have another Lambda who’s only job it is to send these messsages queued up in SQS.

If there are messages, I pay for it to run. If there are no messages, I pay nothing.

There are no servers to configure, no scaling policis, no security updates, nothing. It could spin up 3,000 Lambda’s to work through the queue, and then shut them all down without breaking a sweat.

Unifying The Code Base

I now also only have to send one post request to this unified email server from all the other repos. There isn’t this awkward debate about which server the notification part should live on.

Other Benefits

  1. All of the emails are controlled from one template
  2. Deliverability can be addressed from one location
  3. Client response times are faster
  4. Debugging is easier - everything is coming from two simple function