This text was taken from the book and a Udemy course The DevOps Toolkit: Catalog, Patterns, And Blueprints
Help us choose the next subject for the course by filling in a survey at https://www.devopsparadox.com/survey
We should ask two significant questions when contemplating whether we should use managed Functions as a Service (FaaS) flavor of serverless computing. Should we use them? If we should, shall it be AWS Lambda, Azure Functions, Google Cloud Functions, or something completely different?
So, should we use managed FaaS? We probably should. But that’s not the right question. We can almost certainly find at least one good example. A more important question is whether managed FaaS can be the solution for a significant percentage of our workload. That’s the question that is much more difficult to tackle. To answer it, we might need first to establish good use cases for deploying and running functions.
By now, most of us are using or are experimenting with microservices. They are smaller applications that are loosely coupled, independently deployable, organized around business capabilities, and owned by small teams. I will not dive deeper into microservices. You probably know what they are, and you likely have at least one in your system. You might have even converted everything into microservices by now.
What matters is that you do develop and deploy microservices. If you do not, you can just as well forget about functions. If you failed to transition to microservices or you do not see value in them, functions will almost certainly not work for you. From a very simplistic point of view, they are smaller microservices. We could just as well call them nano services.
On the other hand, if you do have good use cases for microservices, you might benefit from functions. You might just as well continue the trend of shrinking your applications into very focused and small entities which we call functions.
Some use cases are natural candidates for functions, some might produce a questionable return of investment, while others can be discarded right away. Let’s start with the situations that do not fit well into the FaaS model.
If the workload of an application is, more or less, constant, FaaS is not a good idea. The model is based around a mechanism capable of spinning up an instance of a function for each request. Such operation is expensive both in time required to make it operational and the cost, which is often calculated per-request or time of execution. Even though initialization time is usually measured in milliseconds, if we have relatively constant and massive traffic, wasting time on initialization is not a good idea. If, for example, you have an API that is receiving thousands of concurrent requests and the volume does not change drastically from one minute to another, you are likely better of with a different deployment and execution model.
Initialization or the cold-start time has been improved. Service providers managed to reduce it drastically, and they might keep your functions "warm" for a while. Nevertheless, all that only improved the situation, but did not entirely remove the issues with initialization.
There is one more crucial reason why we are better off not using FaaS when we have, more or less, constant workload. They are too expensive. As a matter of fact, if we calculate the cost based on CPU or memory utilization, FaaS is much more costly than most of the alternatives. It can be a couple of times of magnitude more expensive. And that’s where the real importance of variable load comes in. If an application’s workload changes drastically from one moment to another, or if your application is used sporadically, FaaS is way cheaper since we are usually paying for CPU per millisecond, second, or anything in between. But, if we do have constant usage of a resource (e.g., CPU), that is usually much cheaper without FaaS. Under certain conditions, the difference can be expressed with a multiplier of five, ten, or even more.
Let me make it clear. FaaS is very expensive when used extensively. It is likely the most costly way to run our applications at scale. From the cost perspective, managed FaaS tends to make sense only when functions are used sporadically, or when there is a considerable variation in the amount of workload, from one moment to another. That does not necessarily mean that FaaS is a bad idea. Those costs might be overshadowed by the benefits and operational or development savings. Nevertheless, the price is not something to be ignored, but, instead, factored into the decision whether to use FaaS.
Another potentially problematic issue is related to vendor lock-in. How important is it to avoid being locked into a single provider? Think about it and, while you are at it, remember that it is not only about being locked into a specific compute vendor but also that there is not yet a widely accepted standard. You will be locked not only into a vendor but into a particular product of a vendor that is likely very different from other FaaS solutions.
Now, vendor lock-in is not necessarily a bad thing. It is all about a calculation in which you put benefits on one side, and the cost on the other. If benefits are higher than the cost, it is okay. If the return of investment you will gain by kick-starting your project fast is sufficiently high to warrant the potential loss incurred by being locked-in, you should go for it. Just remember that managed FaaS is probably one of the best examples of vendor lock-in we have seen so far.
Now, you might say that you do not see what is so difficult. Why would it be hard to switch to a different vendor or a different service? Everything we did with the Serverless Framework seems to be simple enough, no matter the vendor. That might lead you to conclude that it should be easy to move from one provider to another. But that would be misleading. We saw a simple example of a single function. When your functions increase in number, so will increase the number of auxiliary services around them. At one moment, you will realize that there’s much more code required to glue together all the functions, than functions themselves.
All in all, FaaS is rarely the right solution if any of the following cases are true.
- Workloads are, more or less, constant
- Workloads are high
- Lock-in is not desirable
We can turn those upside down, and say that a use case could be the right candidate for FaaS, if workloads are variable and not high, and if the benefits are greater than the downsides of being locked-in.
Now that we know which situations are not a good fit for FaaS, let’s see a few examples that might be good candidates.
Static content is an excellent candidate for conversion into Functions as a Service. To be more precise, the interface between users and static content can benefit significantly from being functions. Static content, which is not accessed all the time by many, could be on the top of the list for conversion to FaaS. For example, we could store artifacts (binaries) in an external drive, and spin up an instance of a function whenever we want to push or pull something.
Batch processing is another excellent example of something that could be served well with FaaS. It could be, for example, an ETL process initiated when we push a change to storage. Or it could be image processing triggered by an upload. It could also be scheduled creation of backups, which we would typically do through a CronJob.
All in all, the best candidates for FaaS are variable or occasional executions of processes that can be encapsulated into small units (functions).
Does that mean that we cannot build whole systems based on FaaS? It doesn’t. We can undoubtedly split everything we have into thousands of functions, deploy them all independently from each other, and glue them altogether through whichever means our provider gives us. But that would probably result in a costly decision. The bill from your compute provider would likely be much bigger than it tends to be, and you would spend more time in maintenance than you’re used to. That would defy some of the main reasons for using FaaS. It is supposed to be easier to manage and cheaper to run.
Do not go crazy. Do not make a plan to convert everything you have into functions. Heck, we are still debating whether microservices are a good thing or not. Functions applied to everything would be an extreme that would likely result in a miserable failure. Choose well candidates for conversion into functions.
In my experience, the cases when functions are the right choice are relatively small in number, when compared with other ways to run applications. But, if you do find a good use case, the results will likely be gratifying.