Email Best Practices
Email is a pain, but is absolutely required for many modern applications to function well. Whether it is for sending invoices, password resets, or simply for notifications, you’ll probably be making changes to your application’s email components early and often. While you can get by with a terribly implemented email system for years, you’ll eventually find that problems in such a system will get more annoying and distracting over time as your application scales up. While it’s easy to fix simple email issues early on when only a half dozen people are receiving your emails, it becomes difficult when there hundreds of people on your system, and becomes all-consuming if there happen to be thousands.
Email also seems simple. Like a logging setup, you might be tempted to think you can built out your application’s email functionality in an afternoon. And you’d be right, for a while, but like a hacky, poorly planned logging setup, it eventually causes more problems than it solves. There is a lot of complexity behind the scenes and that complexity can interfere with application stability, usability, and possibly even run your costs through the roof if you aren’t careful. Worse still, there are a lot of regulatory compliance rules around email, with steep fines if you break them. Finally, even if you manage to avoid all these problems, there is still an extremely diverse set of email account providers, mail clients, and spam filters out there, all of which do things in slightly different ways that can make your emails look horrible or even keep them from working at all.
You probably won’t be able to solve all your email issues at once. Rather, you’ll probably end up solving email-related problems piece-by-piece as you run into them. However, there are a set of general practices and rules you can observe that will dramatically reduce the number of problems that email causes for you.
Dealing with email in a large application is complex and it is getting more complex all the time. Because email had a variety of security, privacy, and spam issues in the early days, a lot of email-related interactions are complex and are not consistent across platforms. In addition, you have to get email right if you don’t want to have performance and stability problems with your application.
Don’t host your own email server
While it is tempting to do this to reduce costs, this results in a lot of downtime as well as deliverability problems, unless you are extremely good at doing this. Even if you are good, it’s probably still cheaper to outsource this to a third party. If you are doing mailing lists, sites like Mailchimp can cover a lot of your needs, while transactional emails can be handled by things like Mandrill, SendGrid, etc.
Even if you are doing cloud work, your cloud provider likely has a lot of email-related functionality available for a much lower price than the cost of hosting your own. Third party email providers also provide a lot of other infrastructure for you, such as being able to track things like email bounces and the like. If you don’t use third party providers, you may need to build out this functionality yourself. This is probably not a good use of your time.
Have a way for people to manage how you contact them.
Many anti-spam laws have been passed over the years, and you are unlikely to be able to avoid them. Further, these laws are often structured around how people react (in real life) to junk email. In this case, the law is actually reasonable guidance for how to keep from annoying your users. Additionally, users are going to want to customize the way that you contact them in general. You probably shouldn’t build out email functionality in your application unless you plan to have this in place.
Regulatory compliance is also critical to make sure that your company doesn’t get hit with a massive fine for sending spam. Whether you are doing so (or not), getting this right reduces your risk and you should do so BEFORE regulatory agencies (or lawyers) get after you. In addition to avoiding regulatory problems, allowing users to customize their interactions with you can often improve their perception of your application. While this may not be as important for transactional emails, it is critical for emails that are sent as a regular event for a SAAS app or service. Otherwise, people will start blocking your emails as spam.
Handle failures in a granular fashion.
Emails fail to send. A lot. Further, there are numerous business cases where the same email is sent to multiple people. If one of the addresses doesn’t work, you need need to handle that appropriately. Several things can go wrong here. A single failed email that causes the batch to be repeated means that people get multiple copies of the same email. Alternatively, a failure could mean that not everyone gets the email, possibly causing other problems (depending on your business).
Failures can also happen very slowly, meaning that enough of them may make delivery of email slow for your application. If your system is multi-tenant, you need to make sure that outbound email failures for one tenant don’t slow down delivery for everyone else. Also, make sure that information about failures is easily retrievable, because you will likely need it for diagnostic purposes at some point.
Send emails out of band.
If a user action triggers the sending of an email (such as within a “Create Account” workflow), it’s generally a bad idea to make the user wait for the system to send the email. Generally speaking, you are going to want to do this out of band in a backend process so that you don’t chew up scarce webserver resources for this. Sending emails in band is also not a particularly great user experience, especially if the email server on the other end is having problems.
You are probably also going to want to send some emails on a schedule and doing so out of band in another process can get bulk emailing workloads from slowing your server to a crawl. It may also be useful to have multiple third party email service providers (so you can fail over to another one). Pulling your code out of band means that you don’t have to deal with that logic in your main app and that you can scale the two concerns separately.
Be careful about the complexity of email content
Understand that a lot of email clients have their own way of rendering HTML and may modify the html you send for various reasons, some of which you will think are stupid. For instance, they may keep things like tracking pixels from working, or may set the dimensions of the email as displayed on screen. You should also consider that your users may want to find your email with a text search, possibly years down the road. Overly complex HTML in an email can make this more difficult in some cases.
Follow guidelines on email content, subject, first line etc.
You generally want to avoid long pieces of text in emails. Not only are they less likely to be read in the first place, but a lot of email clients will thoroughly mangle long-form text in a way that is unhelpful to the reader. Also be aware of email titles. If they are too long, they may not display properly in email clients, especially mobile ones.
The first line of an email should give useful information about what it contains. This is often shown in previews of the message in many email clients. Avoid using things such as excessive links, misspellings, profanity, and words likely to trigger spam filters.
Consider attachment sizes
Because printing email is often janky at best, it’s fairly common for transactional emails to also include attachments. However, like the previous considerations around html, you may also find that attachments suffer from many difficulties. Some file types (such as zip files, executables, etc.) are pretty much useless in email contexts, because virus scanning software and email rules will bar them from being received.
Other file types (Microsoft Office files, for instance) may be actively scanned by antivirus software. These things are prone to false positives, which can hurt deliverability seemingly at random. The software may even scan the internals of some files, looking for links out to hostile websites. You also need to be careful about the size of attached files, as different email providers have wildly different policies on this.
Consider spam filters
Spam filters are yet another problem. While we’ve already discussed some things that might trigger spam filters, there are quite a few other things that can do it that we haven’t discussed. For instance, many spam filtering engines will actually learn from users marking emails as spam. This can mean spotty deliverability at best.
Spam filters can also keep some resources (such as images) from loading in your emails and/or disable links that you’ve included. If your user-base isn’t particularly savvy, this can become a support issue. You may also find that spam filtering (or just email clients in general), as well as some email service providers like to tamper with links. In particular, they may redirect the user to an intermediate location first for tracking and then forward them on. While this may not be a big deal in many circumstances, it’s something to keep in mind when writing code that lives at the URL a link references, however.
Be very careful about leaking sensitive data in emails.
Emails can be forwarded on, even years after being received. Additionally, email accounts are often easily hacked (Yahoo had issues for years with this), which can mean disclosure of sensitive data if it was ever put in an email. Understand that it isn’t JUST the contents of email that is sensitive. The fact that your users even got an email from you can be enough to cause problems, depending on the situation.
Users also occasionally mis-type their email address (or use a fake one), so you should have a two step confirmation process before sending them email (other than the actual confirmation email, obviously). Sensitive data includes email addresses as well, so make sure you are careful about things like To and Cc. You’d be surprised how often this stuff gets screwed up.
Tricks of the Trade
The form of communication you choose has a big effect on the transfer of information. Email, text, or messaging such as Slack severely limit what can be passed to just the text content. They leave out tone, mood, or even sarcasm. Texting sarcasm can be dangerous, especially at work. When you are communicating via text remember that there is a lot of metadata or information about the message that you are not receiving or sending.