What Is Serverless?
“Serverless” is a slight misnomer—your code will still be ran on a server somewhere. You just won’t have to worry about it, because the metal it runs on will all be managed for you “in the cloud,” leaving you to focus purely on software. This is the allure of serverless solutions; cutting out the cost of managing servers saves you money, both the labor cost of sysadmins and the cost of running a VPS, especially one that might be more than you need.
Serverless is a broad category, but most services will include three main things:
No servers to manage (obviously). Automatic scaling with no extra configuration. Because code is ran in small containers, it’s easy to fire up multiple containers in parallel. Pay-per-use billing. This can make serverless code cheaper than a traditional VPS-based solution, as you probably aren’t operating that VPS at max load all the time.
This makes serverless a competitive model based off cost alone. For a site like Bustle, moving to AWS Lambda earned them an 84% cost savings over their old architecture. Scaling up serverless solutions is much more linear, because you won’t have to pay for individual server instances.
PaaS vs. FaaS
It’s important to clarify the difference between PaaS and FaaS “serverless” models, because the marketing for each type is largely the same.
Platform as a Service (PaaS) cuts out servers, but doesn’t touch your underlying code or enforce any new coding practices. This is usually done through containers like Docker, where snapshots of your application can be deployed very quickly across multiple servers. With some services, like AWS Fargate and Azure Container Instances, you don’t have to worry about servers at all, rendering them “serverless.” With other services, like Heroku, you’re still charged per server, but you don’t have to worry about setting it up yourself, and scaling across multiple instances is easy.
Function as a Service (FaaS) cuts out the idea of servers entirely. Instead, your code is triggered, runs a quick function, and charges you for the memory and compute time that you used. FaaS models enforce the idea of “microservices,” breaking down your app into its component parts, and developing each one individually. This doesn’t work for everything, but when it does, it can greatly speed up development and maintenance versus traditional “monolithic” application designs. AWS Lambda, Google Cloud Functions, and Azure Functions are all FaaS models.
FaaS is generally regarded as “serverless” compute, though perhaps that’s not the most descriptive term for it. “Microservices” is much more representative of the ideas behind FaaS and “serverless” models. You can still build microservices with PaaS services, but FaaS forces you to do so.
Where Microservices Shine
Imagine your app is a large, monolithic application, with many different moving parts.
All these parts of your app talk to each other, and depend on each other to make everything work. But, it’s messy, everything is interlaced, and dependency management becomes a pain. If you want to have multiple teams working on different parts of the app, you’ll be bumping each others shoulders quite often.
A microservices-based application model splits everything apart into its own service. These could still run on the same machine, but perhaps you might want to package them up with Docker to run on seperate servers, or scale them across a cluster with Kubernetes. That’s much easier to do when you can scale one piece separately from the others.
This can be broken down further with FaaS providers, where now these building blocks can be single functions instead of whole services. For example, you could have a function to automatically resize images for different devices, like the Seattle Times uses Lambda for. You could build separate functions for each REST API endpoint, and forego running an API server altogether.
Obviously, this model doesn’t work for every application. Some things aren’t designed to be split up, and doing this retroactively can be a huge pain. But when it works, you can end up with a very structured application that’s easier to fix when it starts to break.
Microservices Aren’t Always Simpler
Microservices are cleaner, and when you lay it all out, they look much nicer than the messy monolithic design many apps use. But someone has to design all of that structure.
Building a microservices-based app puts a lot of pressure on your DevOps cycle, particularly when planning everything out. While you might be able to bootstrap a monolithic application and build everything as you go, microservices require careful planning from the start. This requires good architects, and good communication with the rest of the team about the structure of the app.
And with more services come more things to monitor, debug, and maintain. If you only have a small development team, trying to build and fix many services at once can be overwhelming.
FaaS specifically also forces vendor lock-in. While you can usually take a Docker image and deploy it on a different provider, building your application on a service like Lambda forces you to only use Lambda to host your application. You become locked into the ecosystem, and suddenly you’re not writing JavaScript code, you’re writing Lambda code. You still have control over what you write, so it’s possible to port it to another service, but detaching from a service you rely on is usually harder than it seems.
Also, FaaS services usually aren’t intended to be ran 24/7. If you’re using Lambda functions to build an app that’s constantly triggering Lambda functions, you’re going to run up your bill higher than just paying for a VPS.
When and When Not to Use Serverless
PaaS services like AWS Fargate simply run containerized apps without bugging you about the metal they’re running on. You could switch your entire application infrastructure to a service like this with no problems. Also, with PaaS comes easy clustering, and adopting a few ideals from the microservices model can help you improve your app’s scalability without much restructuring.
FaaS services are more complicated. They’re not right for everything but are very useful when used correctly. They’re great for simple lightweight backend services that don’t need much configuration or a whole VPS to run them. You can use them as complements to your existing app, and while you could build an entire microservices-based application using only serverless cloud functions, that decision is much more complex.
But money is also a major factor, and while microservices and serverless application models might be harder to plan out, if you can manage to do it, you’ll be saving a lot of money.
AWS Lambda is also very useful in conjunction with other AWS services. Lambda functions can be triggered based on actions in your AWS infrastructure, such as automatically running a function when a file is dropped into an S3 bucket. If you’re already making use of AWS services, Lambda can be a great automation tool.