Contact Us
Azure vs AWS comparison: Which Works Best for Serverless Architecture
R&D

Azure vs AWS comparison: Which Works Best for Serverless Architecture?

An increasing number of modern companies are striving to optimise the cost of their IT infrastructure, including those who’ve already adopted cloud-based services. So cloud vendors are adapting to the challenge by changing their services to offer flexibility and more options for human involvement.

The result of this is serverless architecture, and I’ve taken it upon myself to find out which cloud service is the best option for building serverless architecture. Here’s my Azure vs AWS comparison.

Why it's worth going serverless

There are a few key benefits to going serverless:

  • no server management required
  • flexibility to scale
  • you pay as you use
  • automation is highly available

I’m going to analyse two cloud platforms used in the serverless architecture here: Azure vs AWS. I’ll offer a comparison of the services provided by each vendor, the price for the end user and their performance – especially in terms of execution speed etc.

​Azure vs AWS comparison: cost, performance and speed​

One scenario we’ll consider here is building a communication engine for messaging. As you’ll know, a serverless approach doesn’t guarantee end-to-end message delivery, and we’d need to take this into account when building our application. The cheapest way to facilitate continuous messaging on the Azure platform is by using Azure Service Bus, with a solution architecture that looks a little something like this:

If we’re thinking about using a similar application in AWS, we can use Kinesis Stream instead of Service Bus, with the following solution architecture:

​Our next step is to generate simple code and input it into Azure Functions or Lambda. Here are a few examples:

 

AWS Lambda code

console.log('Loading function'); 

exports.handler = function myFunc(event, context) { 
    //console.log(JSON.stringify(event, null, 2)); 

    event.Records.forEach(function(record) { 
        // Kinesis data is base64 encoded so decode here 

        var payload = new Buffer(record.kinesis.data, 'base64').toString('ascii'); 

        console.log('Decoded payload:', payload); 
    }); 
}; 

function myFunc() { 
  console.log('Data was processed');; 
} 

setTimeout(myFunc, 3000);​

Code for Azure Functions

using System; 

using System.Threading.Tasks; 

public static void Run(string myQueueItem, ILogger log) { 
    var result = myQueueItem + " new message via azure function"; 

    System.Threading.Thread.Sleep(3000); 

    log.LogInformation($"C# ServiceBus queue trigger function processed message: {result}"); 
} 

We’d also need to develop code for generating messages. Both examples are based on Net core 2.2 C# language. Here are some examples:

 

For Azure Service Bus queue

using System; 

using System.Collections.Generic; 

using System.Text; 

using System.Threading.Tasks; 

using Microsoft.Azure.ServiceBus; 

using Microsoft.Azure.ServiceBus.Management; 

namespace azure { 
    class Program { 
        private static readonly string _queueName = "myqueue"; 

        private static IQueueClient _queue; 

        private static readonly int _messagesToSend = 10000; 

        static void Main(string[] args) { 
            MainAsync().GetAwaiter().GetResult(); 
        } 

        static async Task MainAsync() { 
            Console.ForegroundColor = ConsoleColor.Cyan; 

            Console.WriteLine($"Producer ({Configs.PID})"); 

            await Bootstrap.Lab01Async(_queueName); 

            _queue = new QueueClient(Configs.SbFailoverConnectionString, _queueName); 

            var tasks = new List(); 

            for (var i = 0; i < _messagesToSend; i++) { 
                var messageBody = $"pid {Configs.PID} message {i}"; 

                var message = new Message(Encoding.UTF8.GetBytes(messageBody)); 

                Console.WriteLine($"Sending message: {messageBody}"); 

                tasks.Add(_queue.SendAsync(message)); 
            } 
            Task.WaitAll(tasks.ToArray()); 

            await _queue.CloseAsync(); 

            Console.WriteLine("Done!"); 

            Console.ResetColor(); 
        } 
    } 
} 

For AWS Kinesis Stream​

using System; 

using System.Collections.Generic; 

using System.Diagnostics; 

using System.IO; 

using System.Text; 

using System.Threading.Tasks; 

using Amazon.Kinesis; 

using Amazon.Kinesis.Model; 

using Amazon.Runtime; 

using Amazon.SQS; 

using Amazon.SQS.Model; 

namespace AWS { 
    class Program { 
        private static readonly int _messagesToSend = 10000; 

        private static readonly string QueueUrl = "https://..."; 

        static async System.Threading.Tasks.Task Main(string[] args) { 
            Console.WriteLine("Starting pushing ..."); 

            var awsCreds = new BasicAWSCredentials("….", "…"); 

            AmazonKinesisClient kinesisClient = new AmazonKinesisClient(awsCreds, Amazon.RegionEndpoint.USEast2); 

            var tasks = new List(); 

            for (var i = 0; i < _messagesToSend; i++) { 
                var messageBody = $"pid {Process.GetCurrentProcess().Id} message {i}"; 

                var message = Encoding.UTF8.GetBytes(messageBody); 

                using (MemoryStream memoryStream = new MemoryStream(message)) { 
                    PutRecordRequest requestRecord = new PutRecordRequest(); 

                    requestRecord.StreamName = "servicebus"; 

                    requestRecord.PartitionKey = "url-response-times"; 

                    requestRecord.Data = memoryStream; 

                    Console.WriteLine($"Sending message: {messageBody}"); 

                    tasks.Add(kinesisClient.PutRecordAsync(requestRecord)); 
                } 
            } 
            Task.WaitAll(tasks.ToArray()); 

            Console.WriteLine("Messages successfully sent"); 
        } 
    } 
} 

Now it’s time to run an application and measure the outcomes, to determine which cloud platform is the best for building a serverless solution. The test results are summarised in the table below.

 

​​Type​ ​​Azure​ ​​AWS​
​​Components for testing​ ​​Azure function, Application insights, ServiceBus​ ​​Kinesis, Lambda, Cloud Watch
​​Number of messages​ ​​10000​ ​​10000​
​​Execution duration​ ​​4 min​ ​​6 min​
​​Errors during the execution​ ​​0%​ ​​4%​
​​Average execution time​ ​​3.2 sec​ ​​1.95 sec​
​​The Price of solution​ ​​0.4 $ per 10k messages executed ​​2.10 $ per 10k messages executed​
​​Cold start timeout​ ​​At least one pre-warmed instance (Premium plan)​ ​​Any​
​​Message delivery guarantee​ ​​100%​ ​​100%​
​​Size​ ​​Automatically depends on the load ​​On-demand​
​​Tools (languages)​ ​​JavaScript, C#, Python, PHP​ ​​NodeJS, Python, Java, C#​
​​Monitor (Logs)​ ​​Yes​ ​​Yes​
​​Real-time logs​ ​​Yes​ ​​No​
​​Supporting VNET​ ​​Yes​ ​​No​
​​Max number of functions​ ​​No limit​ ​​No limit​
​​Concurrent execution​ ​​No limit​ ​​1000 parallel execution​
​​Orchestration​ ​​Logic apps + Durable functions​ ​​AWS step functions​
​​Idle time​ ​​No limit​ ​​27 minutes (active time)​
​​Debugging​ ​​Support Visual Studio​ ​​SAM CLI tool which allows you to run/test Lambda but does not support C# listener​
​​Hosting​ ​​Cloud or On-premises​ ​​Cloud​
Timeout Up to 10 min 5 min

Conclusion

Both AWS Lambda and Azure Functions provide a mechanism to execute code (functions) without setting up a server.  They both support creating/editing functions, purely from their portals, or you can develop functions in Visual Studio and deploy to the cloud.  Both offer numerous triggers to kick off the function, for example, document creation, queue messages and cloud events etc. Both support the use of environment variables for configuration management. Basic monitoring of functions is also included in both.

So, as you can see, Azure Functions and AWS Lambda both have pretty good results. But our experiment did demonstrate additional benefits to using Azure Functions, such as:

  1. ​It didn’t produce any errors during execution and message processing.
  2. It has a rich set of tools for real-time monitoring and debugging when using native tools like Visual Studio.
  3. Azure Functions has more opportunities to bind different sources and create a pipeline.
  4. The execution period in Azure Functions can be up to 10 min.
  5. Azure Functions has less cold-starting timeout because the premium plan offers a pre-warmed setup.

What I’ve tried to do here is describe my experience of using similar services from different vendors, to give the best possible Azure vs AWS comparison. From my point of view, either option is perfectly valid, but I’d strongly recommend analysing the services and their potential gaps, to find the best fit for your specific needs.

From my perspective, I’d use the Azure platform if you’re looking for rich debugging tools or you prefer to use Visual Studio for developing. In these instances, Azure is probably the best bet for your serverless application.

On the other hand, if you’re looking for a serverless application that can be scaled up or down on demand, AWS might offer better control and scale-manageability.

I’d love to hear your experiences of using both tools. Which one produced the best results for your cloud project? Feel free to leave your thoughts in the comments section.

By Sergii Bielskyi, Cloud Architect at ELEKS.

Do yo want to optimise the cost and performance of your cloud infrastructure?
Contact an expert
Application development
We’ll help you bring your most complex software vision to life with our leading full-cycle custom application development service. So you can focus on delivering an incredible user experience that sets you apart from the competition.
View service
Cloud migration
Optimise the cost, agility and scalability of your IT ecosystem, by taking the best of your current infrastructure and integrating it with the cloud.
View expertise
Have a question?
Speak to an expert
app development
Explore our application development services
Contact Us
  • We need your name to know how to address you
  • We need your phone number to reach you with response to your request
  • We need your country of business to know from what office to contact you
  • We need your company name to know your background and how we can use our experience to help you
  • Accepted file types: jpg, gif, png, pdf, doc, docx, xls, xlsx, ppt, pptx, Max. file size: 10 MB.
(jpg, gif, png, pdf, doc, docx, xls, xlsx, ppt, pptx, PNG)

We will add your info to our CRM for contacting you regarding your request. For more info please consult our privacy policy
  • This field is for validation purposes and should be left unchanged.

The breadth of knowledge and understanding that ELEKS has within its walls allows us to leverage that expertise to make superior deliverables for our customers. When you work with ELEKS, you are working with the top 1% of the aptitude and engineering excellence of the whole country.

sam fleming
Sam Fleming
President, Fleming-AOD

Right from the start, we really liked ELEKS’ commitment and engagement. They came to us with their best people to try to understand our context, our business idea, and developed the first prototype with us. They were very professional and very customer oriented. I think, without ELEKS it probably would not have been possible to have such a successful product in such a short period of time.

Caroline Aumeran
Caroline Aumeran
Head of Product Development, appygas

ELEKS has been involved in the development of a number of our consumer-facing websites and mobile applications that allow our customers to easily track their shipments, get the information they need as well as stay in touch with us. We’ve appreciated the level of ELEKS’ expertise, responsiveness and attention to details.

Samer Awajan
Samer Awajan
CTO, Aramex