Azure Functions – not always a good choice

Azure Functions are Microsoft realization of serverless applications approach. They’re obviously awesome – allowing to publish your piece of code written in C# or JavaScript in dozens of ways, in no time, for very small cost. However, recently I’ve learned they’re not always a good choice.

I had a chance to take part into a project which uses Azure Functions App as a part of production solution. Serverless application is the essential backend piece of the system, providing endpoint integrating two other systems. The diagram below gives a general overview of the system.


The simplicity of this solution is a big advantage. However, I started running into some performance troubles – time difference between the registration of incoming request (InputFunction) and the end post call to target endpoint (ProcessFunction) was good straight after deploying the solution, but was getting far from expected after some time.

The reason this happened was Azure Functions polling algorithm, which checks for new queue messages less frequently after some idle checks. Our application indeed doesn’t record a big traffic. Unfortunately, the polling algorithm is something you cannot control in Azure Functions.


I solved the problem by moving the logic implemented in ProcessFunction to a continuous Azure Web Job. In fact РAzure Functions have much in common with Azure Web Jobs Рboth can be triggered by similar actions, including Azure Storage queue. The resemblance is even bigger РWeb Job triggered by queue is also limited by polling algorithm. However, this time we can control its behavior in job startup:

static void Main(string[] args)
    JobHostConfiguration config = new JobHostConfiguration();
    config.Queues.MaxPollingInterval = TimeSpan.FromMilliseconds(100);
    JobHost host = new JobHost(config);

Note: MaxPollingInterval value has some limits – it cannot be lower than 100 milliseconds and cannot be higher than 1minute.


Leave a Reply

Your email address will not be published. Required fields are marked *