Read this first
From my experience Amazon SES might be the cheapest option out there for bulk mailing, but is it technically good? I consider it OK at best, but in some areas it is an epic failure.
SMTP is old
Yes ladies and gentlemen SMTP is really old, as in older than “Back to the future old” and in tech terms that’s pretty damn old. SMTP was introduced in 1982 and received its last revision in 1998. Let’s also be clear SMTP is not designed for mass mailing out of the box.
Why is SMTP not suitable for bulk mailing?
Well you’ve probably heard people talk about how chatty SMTP is. Yes it is extremely chatty, but that isn’t the biggest problem. SMTP was designed ideally for a 1:1 instruction per email, with CC and BCC addressing the need to send more than 1 email from 1 instruction. This is acceptable for transactional email, but when it comes to bulk email, the idea is to minimize the total instructions as much as possible and by doing that reduce the network consumption, IO and time to bulk send.
The protocol simply isn’t up to scratch for mass mailing when you consider the following scenarios:
- Personalised body per recipient
- Varied attachments per recipient
- Large volumes of recipients
in 2 of the above scenarios using CC and BCC is not an option, and so truly 1 instruction must be created per email! When it comes to bulk sending, this is outrageous. Imagine using c# having to create 1 mail object per email when you have 2 million emails to send off?
In the 3rd scenario you can lesson the problem if you are not offering personalized email, by reusing CC or BCC. However with CC other recipients are aware of each other, so that is out of the question for mass mailing, leaving BCC, and here again you encounter issues depending on your mail host, what limits they impose to the max number of BCC’s you can include. In the case of Amazon SES that number is 50!
The solution is custom APIs
Providing developers and users with a custom API to your mailing solution means you allow your developers to bypass the limitations of traditional SMTP, and deal with the limitations your side. I’m not implying this is cheap or easy. But this is the only way to implement a professional mass mailing solution – SMTP simply isn’t a good approach.
So for example – imagine if you were a mass mailing provider. You would want to provide your developers with an API that could for example allow uploading attachments upfront for reuse for a campaign. Or HTML and TXT templates, where they could reference the template and do server side replacements for personalization. All of this is not rocket science, a lot of existing mass mailing solutions offer this type of thing, why? Because they too came to the same conclusion that the SMTP interface is just too taxing on the end user.
Amazon API is nothing more than SMTP wrapped
The Amazon SES API might be slightly less chatty than SMTP, but realistically this offers no tangible performance value. The crux of the matter is that Amazon did not implement their API to solve mass mailing problems, but I think it had to do with their billing policies (speculation!). Eventually though Amazon started offering a standard SMTP interface which they might as well have done all along.
Multi-threading to the rescue
I know what you’re thinking, and I thought it too, and I went a step further I actually implemented a full blown dynamic multi-threaded C# app to send emails at max speed through Amazon SES, and here is what I found:
Based on all the limitations in the Amazon SES offering and limitations in SMTP (And this includes their SMTP wrapped API), 1 or 2 threads is all you are ever going to need.
Here is why:
1. Amazon impose a max send rate – starting at 5/sec and the max they’ll allocate is 99/sec – That is it! That essentially means 99 unique emails per second, not instructions!
2. Let’s say you went down the full blown multi-threaded route and created 1 thread * max rate. You might think this is a reasonable approach because this way you can personalize mails client side, and have a truly 1:1 mapping of instruction : email (which again is outrageous). At the end of the day the max you’re going to get is 99 emails per second at best (and most likely slightly less).
3. Since BCC is limited to 50, and assuming you can create a non personalized email instruction in a second, well that means technically with 2 threads you could push 100.
So as you can see from this basic example – batching instructions is much more efficient. 2 threads can do the work of 100. Furthermore if Amazon did not impose a 50 BCC limit, then 1 thread would suffice.
I eventually had my arm twisted to continue using Amazon SES, and so because of this ditched email personalization and went with a single thread for handling emails.
If you can avoid personalization then you can get 99 emails per second to Amazon with just 2 threads. If you really have to personalize then 1 thread * limit is your solution, but beware the more IO you are doing the more you can expect problems, timeouts, network issues, etc.
Ideally if you’re after personalization with high volumes, you DO NOT WANT TO BE USING AMAZON