When I was placed on Viacom’s Content Distribution team, one of my first tasks was to evaluate the usability of AWS Lambda (an as-needed serverless function host in the cloud) and Amazon API Gateway as an alternative to our then-current Apigee. At the time, Lambda looked like an excellent option. It was fast, cost-effective, and able to handle high loads without much risk beyond the cost of spinning up extra Lambda containers. As an alternative to a few always-on servers or a set of managed containers, it looked very attractive for our content API, especially once I’d made a couple of proof-of-concept Lambdas.
As time went on and the development process moved to the next stage, we began encountering issues. What follows is a thorough exploration of Lambda as a tool and, ultimately, a move to EC2 (a virtual machine server, also hosted in the cloud) to negate some of Lambda’s more glaring issues.
High availability, one of Lambda’s main selling points, has some hidden downsides. On a “cold start,” or a function start after not calling the function for a long time, Lambda functions spin up a virtual machine and execute within approximately 100 milliseconds of being called. Sounds great, right? For something that isn’t customer facing, sure. But when a user application needs a latency of less than fifty milliseconds per call from start to finish, 100 milliseconds for startup alone suddenly starts to drag. On the other hand, an EC2 server will stay up for as long as needed and accept connections for as long and as quickly as it is configured to do so.
Configuration used to be an issue, as we had to deploy applications across multiple accounts with multiple permissions. We ended up using several unwieldy configuration files. There was no way to automatically configure a Lambda until instance variables were introduced. Thankfully, this weakness is no longer an issue as of November 2016, when expression-specific environment variables were introduced and supported by AWS’s command line interface.
Any developers who had to deal with the S3 outage at the end of February 2017 know that putting all your eggs in one AWS basket carries risks with it. AWS Lambda, which relies on S3 for code storage, was suddenly unreachable, taking out API functions, Amazon Echo skills, and other codebases that relied on Lambda for execution. Of course, several other applications were effected, including EC2 instances that used S3 for new launches, so both services have this hidden dependency.
Eventually, the start-up time became too much of a blocker for our team and we switched from hosting our function in Lambda, accepting connections on an as-needed basis, to an EC2 server that listened for connections constantly.
It may seem like after all this criticism that Lambda is a poor tool for development, but that isn’t true. When properly used with managed expectations, AWS Lambda can be a strong mix of power and cost-effectiveness.
Lambda’s pricing and EC2’s pricing are designed differently enough that cost analysis becomes a bit tricky. A Lambda function with 512 MB of memory run for 1 hour (or, more likely, as several calls of the same function adding up to an hour of uptime) costs $0.030024, while an on-demand EC2 server with the same statistics (a t2.nano server with 0.5 GB of memory) costs $0.0059 per hour. At first glance, this is clearly in favor of the EC2 server. However, that server is designed to be up and listening for connections that entire hour, possibly only performing a few computations, whereas a Lambda expression that’s running for an hour straight is doing something very, very wrong.
With concrete timeouts, rate-based blacklisting, and containers being spun up and down as needed, Lambda expressions are, by design, more DDoS attack resistant than EC2 instances. EC2 instances require additional services, such as AWS Web Application Firewall, load balancers, and elastic IP services, to resist heavy loads.
I enjoy developing for Lambda in the situations it’s designed for. I would definitely recommend it to anyone looking to develop an application with highly variable load and short, frequent tasks, as long as they take its usefulness with a grain of salt and don’t buy into all Amazon’s hype.
(Addendum: Lambda and EC2 were both only meant to be interim solutions while we completely revamped the content API. However, any interim solution needed to uphold the standards of the previous version. Lambda was poorly suited for this task, while EC2 emerged as the better choice.)