The Surprising Cold Start Penalty in the AWS SDK for .NET

bjorg

Steve Bjorg

Posted on September 9, 2022

The Surprising Cold Start Penalty in the AWS SDK for .NET

This post is about raising awareness of a performance penalty when initializing the AWS SDK for .NET.

This is a startup tax incurred by all AWS Lambda functions using .NET. Fortunately, it's trivial to make it happen during the INIT phase where it's free. However, there is no way of avoiding it during a cold start. I can't help but think the initialization overhead should be much lower.

For this benchmark, our code is almost identical with the baseline function, except that we initialize an S3 client in the constructor.

using System.IO;
using System.Threading.Tasks;
using Amazon.S3;

namespace Benchmark.AwsSdk {

    public sealed class Function {

        //--- Fields ---
        private IAmazonS3? _s3Client;

        //--- Constructors ---
        public Function() {

            // initialize S3 client
            _s3Client = new AmazonS3Client();
        }

        //--- Methods ---
        public async Task<Stream> ProcessAsync(Stream request) {
            return Stream.Null;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Cold Start Durations

The following table shows the new measurements using .NET 6, Tiered Compilation, and ReadyToRun with 3 different memory configurations: 1,024 MB, 1,769 MB, and 5,120 MB.

Initializing the AWS SDK for .NET adds a 120+ ms penalty to the cold start duration. The impact remains the same, no matter the memory configuration since the initialization is happening during the INIT phase.

Architecture Memory Size Tiered Ready2Run PreJIT Init Cold Used Total Cold Start Penalty
arm64 1024MB yes yes no 380.461 41.773 422.234 147.21
arm64 1769MB yes yes no 377.036 29.365 406.401 141.856
arm64 5120MB yes yes no 349.227 28.428 377.655 136.467
x86_64 1024MB yes yes no 344.643 29.678 374.321 128.797
x86_64 1769MB yes yes no 339.3 23.058 362.358 122.975
x86_64 5120MB yes yes no 325.178 22.468 347.646 124.422

Potential Cause

Looking at the code for the AWS SDK for .NET, I suspect the culprit of the slow initialization is the endpoints.js file. This 700+ KB megalodon JSON file is parsed every time the AWS SDK is initialized. Since this happens in the AWS Core assembly, this penalty is incurred by all AWS service clients.

I hope this is something the AWS team fixes in the future. As a clueless layman, I would expect the endpoint definitions to belong to their respective packages. This would also produce a smaller Lambda deployment package as the current AWSSDK.Core.dll assembly size is an eyewatering 1.5 MB!

What's Next

In the next post, I'm benchmarking the impact of using top-level statements with Lambda functions. This new way of writing Lambda code is aesthetically pleasing, but does it have a hidden cost?

💖 💪 🙅 🚩
bjorg
Steve Bjorg

Posted on September 9, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related