Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

MQ Mail - Backend Architecture / Design

Context
This interview is a roleplay. We (your interviewers) have recently launched a consumer email
product in the market, ​MQ Mail​ (to compete with GMail), and need your support in improving our
backend to meet the expected increase in consumer demand.

Since we want to compete against Gmail, we have come up with the following Service Level
Objectives.
● 99.99% availability to users
● Inbox view in <1000ms at 95th percentile and <500ms at 50th percentile

What we’ve built so far

Send & Receive Partnership


We have established a partnership with an “infinitely scalable” 3rd-party service to send and
receive emails on our behalf. We interact with this service through simple RESTful APIs.

Send
Our 3rd-party partner exposes an endpoint ​“/send”​ which accepts JSON encoded emails via an
HTTP POST. ​“/send”​ returns a 201 response if the message will be successfully delivered and
a 5XX upon failure. These responses are ​definitive​.

Example ​“/send” ​request​:

$ curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: <something>" \
--data '​{ \
"id": "some-mq-generated-unique-id", \
"to":"foo@bar.com", \
"from": "baz@mqmail.com", \
"subject": "Test", \
"message": "Test test." \
}​' https://api.3rd-party-service.net/send

Receive
Our 3rd-party partner receives (via SMTP) all email for our registered domain (mqmail.com) and
notifies us upon each email receipt via ​webhook​: a JSON encoded HTTP POST. They will
retry the webhook for up to 24 hours until receiving a 2XX response from our server.
Example simulated ​webhook​ request​:

$ curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: <something>" \
--data '​{ \
"id": "some-3rd-party-generated-unique-id", \
"to":"baz@mqmail.com", \
"from": "foo@bar.com", \
"subject": "Test", \
"message": "Test test." \
}​' https://api.mqmail.com/receive

MQ Mail Backend
We have built a simple backend, which consists of an application server (which serves requests
from the frontend via RESTful APIs), deployed as a Docker container in “the cloud”, and a single
relational database server.

Database Schema
We have 2 tables in our database. ​users​, which stores the consumer email accounts, and
emails​, which stores the emails sent and received.

users​ table

emails​ table
Authentication and Authorization
Our frontend manages authentication and authorization. For the sake of this discussion we can
assume that each request our backend receives has been appropriately validated and includes
a simple, performant way to extract a ​user_id​ from it.

Sending Email
Our backend receives an HTTP POST to send an email from our frontend and:
1. Generates a unique id for the email
2. Formats and sends an HTTP POST to the 3rd-party ​“/send”​ endpoint
3. Upon success:
a. Inserts an ​emails​ row into our database
b. Sends a 201 response to our frontend
4. Upon failure:
a. Sends a matching 5XX response to our frontend

Receiving Email
When our 3rd-party partner receives an email to our domain on our behalf, they forward it to our
backend via an HTTP POST (​webhook​) and:
1. Searches for a matching user record based on the “to” field in the JSON body
2. Upon finding a matching user:
a. Generates a unique id for the email
b. Inserts an ​emails​ row into our database
c. Sends a 201 response to the 3rd-party
Known Limitations

Feature Limitations
By design, MQ Mail currently does not support:
1. Multiple recipients
2. Cc, Bcc
3. Attachments

Performance Limitations
Our system has performed well enough (we think) so far (we have signed up roughly 10K users
in the 3 months since our launch) but we are concerned about performance as we grow. Our
goal is to reach GMail size (100M users) over the next year. There are two specific areas that
concern us:
1. Application​ ​server availability, latency and load
2. Database reads and writes, specifically from and to our ​emails​ table

Major Bugs
We have intermittently heard complaints from our users about seeing duplicate inbound emails.
It isn’t reproducible but we do see the duplicate entries in our database in each case (with
similar timestamps).

We’ve also heard a few reports of users seeing “strange” error messages when attempting to
send an email. In each of these cases, when debugging, we have found that the email was
actually sent to (and received by) the intended recipient. However, the email was not stored in
our database and not visible in the user’s outbox.

What we need your help with


In your conversation with us we will discuss ways to handle our expected growth, add a feature
or two, and identify / fix these bugs we’ve seen. We don’t expect you to come with a
presentation prepared but just to have digested this document and be ready to dive into an
in-depth technical discussion.

You might also like