Serverless Pros & Cons – when should you and when shouldn't you use serverless?
Okay so you've heard of serverless, maybe even built a toy project or two and you think it's neat. But should you really go serverless for your next project?
Most of the time ...
Serverless is a great option for most projects most of the time. You save some configuration and maintenance time, gain a lot of flexibility, and in some cases spend more $$ per request than building your own servers.
For the most part only very large apps hit the cost curve limits of serverless. Bank of America, for example, recently announced $2B in savings from building their own data centers.
You won't hit those issues. And if you do, I hope there's a business model to back it up so you can afford real professionals. 😛
Large orgs often provide a cloud or serverless-like environment internally. If you have access to that, use it.
When I say serverless, I don't mean just throwing up some code on a function-as-a-service platform like AWS Lambda and calling it a day. I'm talking about the whole ecosystem.
The core idea is this:
- Backend does as little as possible
- Clients tie everything together
- Static files come from fast content delivery networks
- Database handles most data consistency
- As much work as possible happens at compile and deploy time
Users' and developers' machines do most of the hard work.
Part of your app the same for every user? Package it up at deploy time. No need to bother either the server or the client with that stuff.
Part of your app specific to individual users? Let the client handle it. Every phone is a powerful computer these days.
Dynamic data that needs to synchronize across multiple sessions or users? Background processes that aren't tied to a specific session? Perfect fit for your server or database.
We go more in depth about this architecture in the chapter on Serverless Architecture Principles.
The biggest benefit of serverless is that you don't have to deal with servers. Somebody else handles that for you.
You focus on application server code. No more tedious maintenance tasks unspecific to your problem.
Bye bye yak shaving
"I need an API. That means I have to run a server. Which means I need Apache or Nginx to map HTTP requests to my server. So I need a computer to run all that. So I have to set up a whole operating system. Then I have to make sure everything runs at boot. And if a process goes down, it needs to restart. And ..."
And eventually after all that work you get to build your application server.
You save time otherwise spent managing servers. Whether that's you personally or a devops team in your organization doesn't matter.
You save time managing servers and you're writing backend code more productively.
Smaller more self-contained server code, often just a single function, means most clarity and focus. Do one thing and do it well
With increased focus in your code, you get:
- easier testing
- quicker understanding
- shorter development cycles
Serverless is often cheaper to run.
Yes, you save opportunity and employee cost, and you're also not paying for servers you aren't using.
As mentioned in the Getting Started chapter: before serverless, you'd have to (over)provision a bunch of machines. Just in case there's a traffic spike. So most of the time, you're paying for servers you aren't using.
With serverless, you pay per execution and run time. Almost like pay-as-you-go pricing: Run some code, pay for that run.
When there's no traffic, there's no cost. 👌
Google likes to call serverless architectures from prototype to production to planet-scale. You don't actually want to use serverless at planet scale though.
But Google is right: Serverless scales. A lot.
The details on why serverless is so scalable are tricky to get into. It's got to do with how much more work you can pack into a single physical machine ... but there's still a machine somewhere and you might run out of those machines with truly planet-scale work 🤔
It boils down to this: You're running a hyper-elastic server that can adapt to changes in workload at millisecond precision.
As much as I think serverless is the next big thing in web development, it's not all fun and games out there. There are disadvantages to using serverless.
There's two parts to performance:
- Speed or bandwidth
Latency talks about the time it takes from making a request to getting a response. Speed talks about the time it takes to do some work.
Each execution is fast because the code is small and your provider provisions fast computers. A couple milliseconds and you're done.
But your latency can be high. You're hitting the server cold every time. That means each request waits for boot up time, caching to kick in, and the computer to warm up.
That's why most providers keep your servers live between requests. But only if they come often enough.
For low traffic applications with low latency demands, you might need a constantly provisioned server.
As Bank of America found out pay-as-you-go pricing can gets expensive when used a lot.
Most providers price based on number of requests and computational resources used. You pay a little for every request and a little for every millisecond of run time.
If you've got a lot of requests or very long run times, you could rack up the costs beyond what you'd pay with your own servers.
I wouldn't recommend training a machine learning model on a serverless architecture, for example. Learned that excruciating lesson with my first startup in 2010 and GoogleAppEngine. Flicked the On switch and our credit card melted 😅
You should also avoid serverless, if you're serving millions of requests per second.
In a nutshell: serverless becomes expensive at extremely high loads. Where that inflection point lies depends on what you're doing and how much time you're saving.
This one's simple: You're building to somebody else's infrastructure.
If that infrastructure changes, you're screwed. If they crank up the price, you're screwed. If you want to move, you're screwed. If you want to deploy your own, you're screwed.
You can do all those things but it's a tedious and difficult task that might break your app. And you're not building features or working on your business better while you do so.
Most startups don't live long enough to run into this problem. Most enterprises are acutely aware and take defensive measures in advance.
Building architecture agnostic code is hard. You must be certain you need to.
You're trading some application code simplicity for system complexity. Individual functions are simpler and easier to test. Complexity now comes from how they interact.
We'll talk more about that in the Robust Backend Design chapter.
I don't have all the answers and I don't know your specific situation. You will have to think about this yourself :)
(or you can reach out for advice)
My general approach is to look at the problem I'm solving and think:
- "Will this require a lot of computation? if the answer is yes, I consider building my own servers.
- "Will this have crazy high traffic? if the answer is yes, I'd probably still use serverless because I hate doing devops. Hopefully high traffic means I can afford a professional :)
- "Is this a small side project idea?" serverless all the way
- "Does every request need to be served under 10ms?" you're gonna have to roll your own
Hope that clears things up :)
Next chapter, we're going to talk about some of the different serverless providers.