Repository navigation
Reduce allocations in Amazon.Lambda.RuntimeSupport - #2601
Open
martincostello wants to merge 10 commits into
Open
martincostello wants to merge 10 commits into
martincostello wants to merge 10 commits into
Conversation
Do not format the messages for the internal logger when the LAMBDA_RUNTIMESUPPORT_DEBUG environment variable is not set, which allocated strings that were discarded multiple times for every invocation. Assisted-by: Claude Code <noreply@anthropic.com>
Use the static HttpMethod instances and add the Accept and Content-Type headers to requests to the Runtime API without parsing them for every request. Assisted-by: Claude Code <noreply@anthropic.com>
Look up the headers for the next invocation ignoring case without copying them into a new case-insensitive dictionary for every invocation. Assisted-by: Claude Code <noreply@anthropic.com>
Create the ClientContext, Identity and W3C values of LambdaContext when they are first used, without allocating Lazy<T> instances and delegates for every invocation. Assisted-by: Claude Code <noreply@anthropic.com>
Do not copy the headers of a successful response to an invocation into a dictionary, as they are not used. Assisted-by: Claude Code <noreply@anthropic.com>
Cache the URI used to get the next invocation instead of building and parsing it for every invocation. Assisted-by: Claude Code <noreply@anthropic.com>
Create the dictionary for the headers of the next invocation with the required capacity to avoid resizing it for every invocation. Assisted-by: Claude Code <noreply@anthropic.com>
Add a change file for the performance improvements to Amazon.Lambda.RuntimeSupport. Assisted-by: Claude Code <noreply@anthropic.com>
martincostello
marked this pull request as ready for review
October 26, 2026 18:22
martincostello
requested review from
dscpinheiro and
normj
and
a balanced review from Copilot
October 26, 2026 18:22
Contributor
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
5 open issues
_nextUriis used as nullable (checked againstnull) but is declared non-nullable and is not… · NewGetNextUriis intended to be safe under concurrent access (per the comment onNextUri), but… · Newvaluesis declared as non-nullable (out IEnumerable<string> values) but is assignednullon… · New These fields are treated as nullable (implicitly defaultnulland used with… · NewCapturedRequestis non-nullable but is not initialized in the constructor, which will typically… · New
Review effort: Lite
Read and write `NextUri` with `Volatile.Read` and `Volatile.Write` so that the instance is explicitly safely published to the concurrent processing tasks that share the client.
normj
approved these changes
Oct 27, 2026
normj
left a comment
Member
There was a problem hiding this comment.
Changes look good, thanks the perf improvements.
…orTests The RuntimeSupport changes in this PR shifted line positions in InternalClientAdapted.cs, moving the expected CS0117 diagnostics that the Annotations source-generator tests anchor to that file. Remap the hardcoded WithSpan line numbers to their new positions (columns unchanged). Verified 593/593 tests pass on net8.0 and net10.0.
Member
|
I pushed a commit back to your branch to fix some tests that started failing in CI after your change. |
Contributor
Author
|
Thanks Norm - sorry I missed that. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Issue #, if available:
Description of changes:
Reduce the memory allocated and CPU time used by
Amazon.Lambda.RuntimeSupportto process each invocation. Each change is in its own commit:LAMBDA_RUNTIMESUPPORT_DEBUG) is disabled, which allocated strings that were discarded multiple times for every invocation.HttpMethodinstances and add theAcceptandContent-Typeheaders to requests to the Runtime API without parsing them for every request.ClientContext,IdentityandW3Cvalues ofLambdaContextwhen they are first used, without allocatingLazy<T>instances and delegates for every invocation.202 Accepted) response to an invocation into a dictionary, as they are not used.Tests were added for the requests sent to the Runtime API, reading the Runtime API headers ignoring case and the values of
LambdaContext. They were run against the existing code before changing it to verify that the behaviour is unchanged.Two minor differences in behaviour:
ClientContext,IdentityorW3Care first read concurrently, the JSON may be parsed more than once, but all callers get the same instance. An exception from parsing invalid JSON is thrown each time the value is read, rather than being cached byLazy<T>.RuntimeApiHeaderscontaining two keys that differ only by case no longer throws an exception. This cannot happen for the headers of an HTTP response.Benchmarks
The benchmark invokes
LambdaBootstrap.InvokeOnceAsync()against an in-memory implementation of the Runtime API (anHttpMessageHandler) that returns an invocation for/nextand accepts the/response, so it measures the overhead of RuntimeSupport itself. The allocations of the in-memory Runtime API are included in the results, and are the same for both.Each comparison is a single BenchmarkDotNet run with
master(de88d8b) as the baseline job, with each job building the benchmark against a different copy of the repository. The benchmarks were run with three launches per job, pinned to the performance cores of the CPU (--affinity 0xFFF).master)master)Note
The allocations were also measured on Linux (.NET 10) in a container for each change in turn:
masterFull results
.NET 10
.NET 8
Benchmark code
RsBench.csprojProgram.csThe comparisons were run with:
Tests
All the unit tests in
Amazon.Lambda.RuntimeSupport.UnitTestspass for each commit.Note
This pull request description and the benchmark results were generated with Claude Code.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.