Sitemap

Azure Function benchmark as of November 2025

7 min readNov 9, 2025
Press enter or click to view image in full size
Generated using Nano Banana from Gemini

As FaaS (Function as a Service) is one of the favorite computing models appreciated both for his generous pricing and its conciseness, Azure has continuously adopted more and more programming languages over the years.

This article will attempt to provide guidance on how to configure and run your Azure Function on Microsoft’s Cloud.

TL ; DR

  • Node is a surprisingly good and reliable language, almost on par with compiled languages
  • Go is the fastest to start, even though it produces a slightly bigger package than Rust.
  • Rust, Go and Node have similar mean run times; Java and Python are lagging behind
  • “Always On” seems to improve both the start and execution times
  • Package Size and Bundling seem to impact negatively the performance

Disclaimer

The results below have been ran in an experimental fashion and don’t take in account several criteria you should consider :

  • These results as experimental. They don’t take in account constraints you may face in productions such as concurrency.
  • Your team proficiency in eventually learning new programming languages
  • The Azure SDK maturity, some less popular languages like Go and Rust don’t have an as active support for the Azure ecosystem. For example Rust’s Azure Tables crate last update received an update the last time over a year ago, and isn’t stable, while Node’s is at its 13th major release.
Press enter or click to view image in full size
Rust Azure table’s crate, crates.io
Press enter or click to view image in full size
Node’s Azure table library, npmjs.com
  • The same way, the development ecosystem has to be considered : both Python and Javascript are easy to develop locally, Java is easy enough even though a bit more tedious, while you are on your own for Go and Rust given these languages need to be deployed using Azure’s custom runtime…
  • … oppositely, from my personal experience again, it is easier to package and deploy Go and Node, while all the others tend to be a bit more tricky.
  • Microsoft is constantly updating their datacenters hardware, please note that over the months, these benchmarks may completely be outdated. I have noticed myself an improvement between early and late 2025 for the regions I am usually deploying on.

What this won’t cover

  • Dotnet : as I am not proficient with using C# and dotnet, it has been taken out of the scope.
  • Premium plans : we are interested in instances that can scale down to zero.
  • Persistence : in order to keep it simple, there will be no connection to databases during the tests. While in a production use case you will surely have your event driven layer connected to your Function, the difference in the performance will go down to the language and the libraries you will be using to reach the layer.
  • Non-HTTP triggers : we can assume that other Azure Functions trigger will have a similar cold start time
  • Concurrency : as explained below, our functions will only receive a single request on a irregular basis. If concurrency is a matter of concern, you should probably consider a PaaS solution for your application.
  • Regions differences : the tests have all been ran in the same region, we can then expect that given how recent servers are in each Microsoft datacenters, the performances would differ from one region to another.
  • OS : Only Linux has been used

Methodology used for this benchmark

Azure Functions in Flex Consumption are known to stop within ten minutes of idle. As Azure doesn’t publish in their logs the cold start time, we will send through a CRON based Azure Function every thirty minutes a request every minute for ten minutes to each of the functions.

That means for instance if it is 9am, a request will be received by each function at 9:00, 9:01, …, 9:09, then it will stop and resume the same process from 9:30 to 9:39.

The thirty minutes gap will help us ensure our Functions indeed go idle and get unprovisionned by Azure as well as ensuring we do have enough data to compare the cold starts with. Hence why we will compare below the average execution times with its 90th and 95th percentiles.

The results below do come from a 24 hours continuous testing, meaning around 50 cold starts have been measured on 500 executions per Function.

const { app } = require('@azure/functions');
const axios = require('axios');

const API_URLS = [
// Removed from original code snippet
];

app.timer('timerTrigger', {
schedule: '0 0-9,30-39 * * * *',
handler: async (myTimer, context) => {

const requestPromises = API_URLS.map(url =>
axios.get(url)
);

context.log('Timer function processed request.');
try {
const responses = await Promise.all(requestPromises);

context.log("--- API Results ---");
responses.forEach((response, index) => {
const data = response.data;
const status = response.status;
const url = API_URLS[index];

context.log(`[${status}] Fetched from: ${url}`);
const identifier = data.title || data.name || data.login;
context.log(`Data Identifier: ${identifier}`);
context.log('--------------------');
});

} catch (error) {
context.error("An error occurred during one of the API calls:", error.message);
if (error.response) {
context.error(`Request failed with status: ${error.response.status} at URL: ${error.config.url}`);
}
}

context.timeEnd("Concurrent Axios Calls");
}
});

The results have been plotted using the following KQL query in Application Insights

requests
| summarize
AverageTimeMs = avg(duration),
Percentile90thMs = percentiles(duration, 90),
Percentile95thMs = percentiles(duration, 95)
by cloud_RoleName
| where cloud_RoleName in ("nodebundled", "nodecoldstart", "nodebiggerpackage", "nodealwayson", "node2048")
| order by AverageTimeMs desc

A last side note that has to be taken in consideration : as Java, Python and Node all have an official Azure Function SDK, Go has been benchmarked using the standard net/http package, while Rust is using tokio and warp, both using Microsoft official documentation that can be found here.

First benchmarks : Languages

  • Languages : Rust 1.91 (labelled as cargo in the charts), Go 1.25, Java 17, Python 3.13, Node 22 LTS
  • Memory : 512MB
  • Region : France Central
Execution time per language
Press enter or click to view image in full size
Execution time plotted per language

Outcome : Python seems to be the most sensitive language to cold starts, Node’s execution time is close enough to compiled’s but suffers from longer cold starts, Go outperforms slightly Rust.

Second benchmark : Configuration

Once I had the results per languages in hand, I wanted to see how the performance for an Azure Function could be improved with configuration.

This time what interested me was the following :

  • Does package size impact performances or cold start ?

To answer this, I added Express to my package, without using it directly, doubling the package size

  • Does a higher memory improve the performance ?

I thus created a second function with a 2056 MB memory size, while the rest will use 512MB

  • Does always on limit the cold starts ?

Always on will be turned for one function

  • Does bundling improve the performance

One function will be bundled using esbuild.

All of these results the below are then taken from an Azure Function in NodeJS with a simple HTTP Trigger.

Cold start per configuration
Press enter or click to view image in full size
Cold starts plotted

Outcome : With little surprise, Always On is not impacted by cold starts. A 2048 MB Azure Function also appear a little less impacted than a 512 MB one. On the other hand, increasing or bundling package size seems to impact negatively the performance.

Conclusion

While Rust and Go seem to outperform every other languages, it is important to remind that their support is limited and working with a custom runtime is a bit tedious as you have to define your own endpoints every time through a function.json file.

Go outperforms Rust on this benchmark, but I believe if Rust’s Axum was being used, it would be the opposite. The same way, using Go’s Fiber on Azure would probably also improves the performance.

Java is a disappointment to me : it’s actually on par with Python, which I would say is mainly due to booting the JVM. If this benchmark was about concurrency though, I am pretty sure Java would outperform Python.

Always On is the game changer for time critical workloads, as it completely kills the cold start time. Bundling or increasing the package size impacts negatively the performance.

On a personal note, I think I would favor NodeJS in the future for HTTP triggers, as the ease to package it and the response times seem to be the best compromises. For workloads that must accept sudden pikes, I would go with Go as I would assume it is handling concurrency better, even though it should probably the time I would consider moving to a containerized solution.

--

--