aws / aws-dotnet-extensions-configuration

This repository hosts various libraries that help developers configure .NET applications using AWS services.
https://aws.amazon.com/developer/language/net/
Apache License 2.0
179 stars 56 forks source link

Performance issue: Slow retrieval times from Parameter Store in .NET 8 Lambda functions #196

Open mcamacho97 opened 3 days ago

mcamacho97 commented 3 days ago

Describe the bug

Hello,

We have observed that Lambda functions using the .NET 8 runtime experience delays when fetching parameters from AWS Systems Manager Parameter Store. The delay ranges from 4 to 15 seconds, depending on the allocated memory size. This behavior is inconsistent and seems to be more pronounced during cold starts.

Regression Issue

Expected Behavior

We expect a consistent and faster response when fetching parameters from the Parameter Store, regardless of the memory configuration or cold/warm start scenarios.

Current Behavior

Below are the observed results during cold and warm starts for both multiple Parameter Stores and a single Parameter Store:

Cold Start (Full Path Parameter Store):

Warm Start (Full Path Parameter Store):

Cold Start (Specific Path Parameter Store):

Warm Start (Specific Path Parameter Store):

Performance

Reproduction Steps

  1. To reproduce the issue with the slow retrieval times from AWS Systems Manager Parameter Store, follow these steps:
  2. Set up an AWS Lambda function with the .NET 8 runtime.
  3. Use the following code for the Lambda function:
using Amazon.Lambda.Core;
using Microsoft.Extensions.Configuration;
using System.Diagnostics;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetSSM.LambdaFunction
{
    public class Function
    {
        public string FunctionHandler(object input, ILambdaContext context)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            var configuration = GetConfiguration();

            stopWatch.Stop();
            var elapsedTime = stopWatch.ElapsedMilliseconds;

            context.Logger.LogInformation($"Get Parameter Store: {elapsedTime} milliseconds");
            context.Logger.LogInformation($"Get Parameter Store: {elapsedTime / 1000.0} seconds");
            return "Hello World";
        }

        public static IConfiguration GetConfiguration()
        {
            var cb = new ConfigurationBuilder().AddSystemsManager(c =>
                {
                    c.Path = "/my/full/path/";
                });

            return cb.Build();
        }
    }
}
  1. Deploy the function and configure an appropriate IAM role with permission to access Parameter Store.

  2. Use AWS Systems Manager Parameter Store to create parameters under both:

    • A specific path (e.g., /my/full/path/parameter).
    • A full path structure with multiple parameters.
  3. Test the Lambda function with different memory configurations (e.g., 128MB, 512MB, 1GB, 2GB) and log the results for both:

    • Cold starts: Ensure the function is invoked after an idle period or by deploying a new version.
    • Warm starts: Invoke the function repeatedly within a short time span.
    • Collect the execution times for each scenario and compare the results.

Possible Solution

No response

Additional Information/Context

We’ve also attached a graph visualizing the above results to provide more clarity. This issue seems closely tied to the allocated memory size and the runtime's handling of cold starts.

Key Questions:

  1. Is this behavior expected due to some inherent limitation or design of the library?
  2. Are there any recommendations to mitigate these cold start delays when fetching parameters?
  3. Considering that the function only performs a single GetParameter operation, is it appropriate to scale the memory so significantly to improve performance? Or is there an alternative approach to address this latency without increasing the allocated memory?

Thank you for your assistance! Let us know if further details or tests are required.

AWS .NET SDK and/or Package version used

Amazon.Extensions.Configuration.SystemsManager 6.2.2 Amazon.Lambda.Core 2.2.0 Amazon.Lambda.Serialization.SystemTextJson v

Targeted .NET Platform

.NET 8

Operating System and version

.NET8 Lambda Runtime

ashishdhingra commented 2 days ago

@mcamacho97 Good morning. Lambda cold starts are expected for .NET runtime. One of the ways to reduce cold start time is to use Native AOT compilation.

You may also try to leverage new SnapStart Lambda feature (however, please check pricing considerations).

Increasing memory size could help a bit, but cold start would still be an issue due to container initialization upon first request.

CC @normj for any additional inputs.

Thanks, Ashish