Okay you've heard of serverless, tried it out, 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 configuration and maintenance time, gain flexibility, and in extreme cases spend more $$ per request than building your own servers.
Large apps can reach the cost curve limits of serverless. Bank of America, for example, 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 and you can afford DevOps professionals. 😛
Large orgs tend to 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 code on a function-as-a-service platform like AWS Lambda. 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 data consistency
- As much work as possible happens at compile and deploy time
Users' and developers' machines do the hard work.
Is part of your app the same for every user? Package it up at deploy time. No need to bother the server or the client with that work.
Is part of your app specific to individual users? Let the client handle it. Every phone is a powerful computer these days.
Got 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 and database.
We go in depth about this architecture in the chapter on Serverless Architecture Principles.
The main benefit of serverless is that you don't deal with servers. They're somebody else's problem.
You focus on application code. No more tedious maintenance tasks that aren't specific 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 app server. I need a computer to run all that. Which means 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 ..."
After all that work you get to build your application.
With serverless you save time otherwise spent managing servers. Whether that's you personally or a DevOps team in your organization.
You write backend code more productively.
Smaller, more self-contained code, ideally a single function, brings clarity and focus. Do one thing and do it well
With increased focus, you get:
- easier testing
- quicker understanding
- shorter development cycles
Serverless can be cheaper to run.
You save opportunity and employee cost and you're 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 in case there's a traffic spike. That means you're paying for servers you aren't using.
With serverless, you pay per execution and run time. Like pay-as-you-go pricing: Run 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 want to use serverless at planet scale though.
But Google is right: Serverless scales. A lot.
The details on why serverless is scalable are tricky to get into. It has to do with how much work you can pack into a single physical machine ... but there is a machine somewhere and you might run out of those with truly planet-scale work 🤔
It comes down to this: You're running a hyper-elastic server that adapts to changes in workload at millisecond precision. In theory this gives you perfect utilization.
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.
Performance comes in two flavors:
- Speed or bandwidth
Latency talks about how long it takes from making a request to getting a response. Speed talks about how long it takes to do work.
Each execution is fast because the code is small and servers are fast. A few milliseconds and you're done.
But latency can be high. You're hitting the server cold every time. That means each request waits for the computer to wake up.
That's why providers keep servers live between requests. But only if requests 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 gets expensive when used a lot.
Serverless providers charge based on number of requests and resources used. You pay for every request and every millisecond of computation. Known as "compute".
If you have a lot of requests or long runtimes, you can rack up the costs beyond what you'd pay with your own servers.
For example: You wouldn't want to train a machine learning model on a serverless architecture. Learned that painful lesson with my first startup in 2010 and GoogleAppEngine. Flicked the On switch and the credit card melted 🔥
Another bad case for serverless are high traffic applications. At millions of requests per second, you're better off on your own.
Serverless becomes expensive at high loads. Where the balance tips depends on what you're doing, how much time you're saving, and how much it costs to do yourself.
This one's simple: You're building on 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. You're not building features or working on your business while you migrate.
Startups rarely live long enough to have this problem. Enterprises take defensive measures like multi-year contracts with strict service level agreements.
Avoid building architecture agnostic code. It's hard and you're not likely to need it.
You're paying for the simplicity of your application code with system complexity. Individual functions are simpler and easier to test. Complexity comes from how they interact.
We'll talk more about that in the Robust Backend Design chapter.
It depends. You will have to think about this yourself :)
Ping me on twitter, if you'd like some help.
I like to use a series of questions:
- "Will this require a lot of computation? if the answer is yes, I consider building my own servers.
- "Will this have ridiculously high traffic? if the answer is yes, I'd choose serverless because I hate doing DevOps. High traffic hopefully 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
Next chapter, we're going to talk about different serverless providers.