Let’s start by going into what serverless really is. No, it’s not the absence of servers but rather the abstraction of servers where you don’t have to deal with operating systems or infrastructure. This is all managed for you by Azure or your respective cloud provider.
Let’s start by saying Azure functions serverless scales very well, it is one of its big features in fact.
So as the load becomes more, functions spin up and as the load decreases, the functions shut down. The Azure functions scale all the way down to 0 Azure functions. This means you don’t get billed at all for the time that there are no functions because there is no resource consumption.
This is great so it’s super cost-effective and saves a lot of power but, this also means there are no functions running. So what happens when a request comes in? Azure will have to allocate server resources, load your function into memory and spin up a new instance of your function for it to be able to use the function. Now you’re possibly thinking but won’t it take long for this function to spin up? Actually, it will! It will, in fact take time to spin up. This is called cold start. You can read more about it here: Understanding serverless cold start.
The consumption plan is billed in two different ways:
The function can get billed based on the number of executions, and you will get the first million executions free. From there you will be charged per million executions.
The second type of billing is based on resource consumption measured in gigabyte seconds. This is an average of the memory usage of your function and the time it takes to execute.
There are a couple of ways to get around cold starts, but they aren’t without their drawbacks.
You could use the Dedicated (App Service) which means that you won’t have cold starts and possible execution time is much longer. This means though that you will have to configure the resources. It does not auto-scale and you will manually have to add virtual machines to scale out. This option is also a lot more expensive than the standard consumption plan and means you don’t get the benefits from serverless anymore.
You can keep your Azure functions up 24/7 by calling it on a trigger every 15 minutes. You can also achieve the same results by calling the function before it shuts down. This means that you are using resources of your consumption plan that could have gone to valuable compute.
You could optimize your code for the startups. This won’t get rid of cold starts, it will just reduce the time it takes to start up.
If you choose to call the function before it shuts down you might want to consider using app service plans since it will be cheaper in the long run.
Now that we’ve gone through how it works, let’s get to the interesting part. When is it a good idea to use Azure functions?
The word function in the software development world means a piece of code that performs a specific well ... function. This is also true for Azure functions: it's a piece of code written for a specific function. This is what serverless was built for and does its best in. Doing small pieces of work. When writing functions you should think of them as bite-sized pieces code with a dedicated job.
They perform at their best if you have small jobs that can be triggered, run in the background, and be completed fairly quickly. If you wish to run long tasks or larger pieces of code this will probably not work for you.
Think of Azure functions as your local handyman, coming to fix something small in your house. When you call the handyman it takes time for the handyman to come out - they aren’t going to rebuild your house - and you pay for the time he helped you.
That said, you will be able to create functions that run larger pieces of code and longer tasks but you will have to weigh the benefit of serverless to the time it takes to create all the workarounds you have to do to get it to work. I have found in many cases that these workarounds were not worth it and I would have been better off simply using other services.
So next time you want to use Azure functions, have a look at what you want to accomplish and see if it will be possible to do what you want in a bite-size piece of code that does not run for long and is not time-sensitive.