One of the best reasons to go serverless is that you might save a lot of money. This is especially true when your load is peaky and has quiet times; because when your infrastructure isn’t working, you’re not paying. But, not all loads are peaky. And here’s a quote from an AWS internal mailing list: “For every compute load, there’s some level of TPS where Lambda is going to be more expensive than servers.” So, when is that? And how much should you care?
[This is part of the Serverlessness series.]
Saving money with servers · The answer, of course, like always, is “it depends”. But let’s just jump straight to what strikes me as the canonical example of someone for whom serverless didn’t work out financially. To learn about it, check out this blog piece by Cory O’Daniel, From $erverless to Elixir.
Tl;dr: No, wait, I don’t want to do a Tl;dr! The piece is funny and wise and instructive and if you care about this stuff, you should just go read it. Go ahead, I’ll wait and be here when you get back.
There’s no doubt at all that they saved a lot of money. The key lessons I took away from O’Daniel’s piece:
They were smart to start up serverless, the app was running fine and requiring no management.
It was hard to get the serverful version running; they saw success on the third attempt, and ended up needing to know a whole lot about the inner workings of the Erlang ecosystem.
As Cory says, “Mind that we already have an ops team and we already have a Kubernetes cluster running.”
Elixir is massively cool. I want to use it for something before I give up on computers.
And of course, Cory’s closing soundbite (most highlighted on Medium) is worth reproducing:
So, should everyone go and rewrite their Serverless services in Elixir? Roll out Kubernetes? Get a nose piercing? Absolutely not … What everyone should do is think about where your service is going, and can you afford those costs when you get there. If you don’t have a team of ops people and you aren’t familiar with serverful stuff, spending $30k/mo on HTTP requests might be cheaper than an ops team.
Do I agree? · Mostly, I think. Although if Cory worked for me I probably would have been sort of pushy about making absolutely sure that there was no way to keep the current system around and still save some money, rather than toss-and-replace (on the third attempt). I note that a lot of their charges were API Gateway, and there are other ways to get data into the system. The data was on Kinesis, which is fine, but there are cases where something like SQS or Kafka can be cheaper. But in the last analysis, it’s not written in letters of gold on stone that serverless will always be cheaper.
Cheaper serverless · To get a feel for the kind of thing I’d look for, let’s head over to another blog piece, How We Massively Reduced Our AWS Lambda Bill With Go, by Sam Bashton of Runbook.cloud, a nifty-looking monitoring/troubleshooting service. His narrative sort of echoes Cory’s, off the top: A popular Lambda-based app started running up some big bills, to the point where it was becoming painful.
This particular Lambda (like Cory’s) didn’t do much more than pull some data in over the network and persist it. What was hurting is that they were running the function for each customer, for each AWS region, every five minutes. And since business was good the number of customers was increasing fast; well, you do the math.
Rather than retreating to servers, what they did was smash all those functions together into one, and bring the magic of the Go language Lambda runtime to bear. Let me quote Sam:
In a single morning we refactored the code to use a single Lambda invocation every minute, operating on 20% of the customer base each time. This Lambda spawns a Goroutine per customer, which spawns a Goroutine per region, which spawns a Goroutine per AWS service. The Lambda execution time hasn’t increased significantly, because as before we’re mainly waiting on network I/O - we’re just waiting on a lot more responses at the same time in a single Lambda function. Cost per customer is now much more manageable however, becoming lower and lower with every sign up.
Isn’t that nice? And no throwaway code, either.
Closing thoughts · My opinion hasn’t changed at all: For building software, use serverless where you can. Obviously, “where you can” depends a lot on the specifics of your app and your budget and your sensitivities.
And when you’re working out the costs of serverless vs serverful, ask yourself: How much is it worth to you to not have to manage hosts, or containers, or capacities, or Kubernetes? I don’t know the number, but I’m pretty sure it’s not zero.