-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aws_lambda_nodejs: Using Lambda Provided SDK by default in NodejsFunction leads to higher cold starts #25492
Comments
Nice callout and thanks for the detailed report. Maybe we should allow users to opt in with an optional property but I am not sure. But yes, the cold start is a pain we can't ignore. |
Users can pass empty array in The feature request is whether CDK should bundle SDK dependencies by default, as it has lower cold starts. |
…ode asset (#29207) ### Issue # (if applicable) #25492. Closes #<issue number here>. #25492. ### Reason for this change The BundlingOptions in NodejsFunction construct removes AWS SDK dependencies by default. This uses Lambda Provided SDK in the resulting function. This has higher cold start than a bundled function with AWS SDK dependencies included. This happens, because the Node.js runtime has to do module resolution and go through multiple files while reading dependency code in the bundled function which uses Lambda Provided SDK. When SDK in bundled with the function code, the cold starts are lower as the as Node.js runtime has to read single file without any module resolution. Result from reproduction: { 'NodejsFunction default (uses Lambda Provided SDK)': 1227.1435, 'NodejsFunction custom (uses Customer Deployed SDK)': 929.441 } related to this issue: #25492 ### Description of changes While maintaining backward compatibility, an new option `useAwsSDK` was introduced to include the sdk in the code asset yes kindly refer to the above ### Description of how you validated changes Added both unit and integration test yes ``` Running integration tests for failed tests... Running in parallel across regions: us-east-1, us-east-2, us-west-2 Running test /Users/jonife/Documents/dev/lambda-tooling/cdk/aws-cdk/packages/@aws-cdk-testing/framework-integ/test/aws-lambda-nodejs/test/integ.dependencies.js in us-east-1 SUCCESS aws-lambda-nodejs/test/integ.dependencies-LambdaDependencies/DefaultTest 329.553s AssertionResultsLambdaInvoke5050b1f640cc49956b59f2a71febe95c - success AssertionResultsLambdaInvokee35a5227846e334cb95a90bacfbfb877 - success AssertionResultsLambdaInvoke7d0602e4b9f40ae057f935d874b5f971 - success Test Results: Tests: 1 passed, 1 total ✨ Done in 337.42s. ``` ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
yes we can close this issue |
|
@jonife I am not sure if this should have been closed. The new variable Mentioned docs:
Comparing it with the current code: aws-cdk/packages/aws-cdk-lib/aws-lambda-nodejs/lib/bundling.ts Lines 131 to 136 in 247aa35
Following (failing) test confirms that behaviour: test('esbuild bundling includes aws-sdk by default', () => {
Bundling.bundle(stack, {
entry,
projectRoot,
depsLockFilePath,
runtime: Runtime.NODEJS_18_X,
architecture: Architecture.X86_64,
});
// Correctly bundles with esbuild
expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), {
assetHashType: AssetHashType.OUTPUT,
bundling: expect.objectContaining({
command: [
'bash', '-c',
`esbuild --bundle "/asset-input/lib/handler.ts" --target=${STANDARD_TARGET} --platform=node --outfile="/asset-output/index.js"`,
],
}),
});
}); - "esbuild --bundle \"/asset-input/lib/handler.ts\" --target=node18 --platform=node --outfile=\"/asset-output/index.js\"",
+ "esbuild --bundle \"/asset-input/lib/handler.ts\" --target=node18 --platform=node --outfile=\"/asset-output/index.js\" --external:@aws-sdk/*", |
Describe the feature
The BundlingOptions in NodejsFunction construct removes AWS SDK dependencies by default.
This uses Lambda Provided SDK in the resulting function. This has higher cold start than a bundled function with AWS SDK dependencies included.
This happens, because the Node.js runtime has to do module resolution and go through multiple files while reading dependency code in the bundled function which uses Lambda Provided SDK. When SDK in bundled with the function code, the cold starts are lower as the as Node.js runtime has to read single file without any module resolution.
Use Case
The default NodeJsFunction created by CDK Lambda should have low cold starts.
Lambda customers are usually sensitive to cold starts. The bundling of the source code already reduces the function size, which is way below the Lambda Quotas limit of 50 MB.
For repro, refer README of https://github.com/trivikr/aws-cdk-lambda-nodejs-function-cold-start-latency
Here are the benchmark numbers in ms:
Notes:
Proposed Solution
The default NodeJsFunction created by CDK Lambda should not exclude AWS SDK dependencies.
Other Information
No response
Acknowledgements
CDK version used
2.76.0
Environment details (OS name and version, etc.)
N/A
The text was updated successfully, but these errors were encountered: