- This package contains backend code which performs create, delete, get, list and update operations on DynamoDB.
- It uses webpack to build single minimized bundle for each operation, and AWS CDK to deploy those bundles.
Ensure that you've followed pre-requisites from main README.
yarn build:backend
to build the package (runs ESLint and TypeScript).yarn cdk deploy
to deploy your application (this operation might take time based on the state of your Cloudformation stack).
- Open the GatewayUrl link from CDK output from the console.
- Append
notes
in the URL. - The contents of the notes DynamoDB table would be returned as JSON.
- If you don't see anything, that's because your table is likely empty! Add data manually or wait until you run the frontend.
- Note: Clean resources after you're done with all activities below, and you want to delete your cloudformation stack.
yarn cdk destroy
to delete your CloudFormation stack.
In this section, we're going to update the code to import DynamoDB Client in different ways and compare the bundle sizes of the resulting lambda functions.
-
Login to AWS Lambda Console.
-
The size of each lambda functions will be ~820 kB.
-
This happens because entire aws-sdk is bundled in the lambda in file
dynamoDB.ts
.import AWS from "aws-sdk"; export default new AWS.DynamoDB();
-
In v2, you can reduce the bundle size by doing dead-code elimination using tree shaking with a bundler like webpack.
-
Just import the
"aws-sdk/clients/dynamodb"
indynamoDB.ts
, as shown in the diff below:-import AWS from "aws-sdk"; +import DynamoDB from "aws-sdk/clients/dynamodb"; -export default new AWS.DynamoDB(); +export default new DynamoDB();
-
Run
yarn build:backend
andyarn cdk deploy
to build+deploy new code, and the size of lambda functions will reduce to ~90 kB!
-
Uninstall v2 by running the following command:
yarn remove aws-sdk
-
Install dynamodb in v3 by running the following command:
yarn add @aws-sdk/client-dynamodb
.
-
Make the following change in
dynamoDB.ts
to import DynamoDB from v3.-import DynamoDB from "aws-sdk/clients/dynamodb"; +import { DynamoDB } from "@aws-sdk/client-dynamodb"; -export default new DynamoDB(); +export default new DynamoDB({});
-
The function calls v3 client return promises by default, so you've to remove
.promise()
from individual functions. -
For example, here's a diff for
createNote.ts
.try { + // @ts-ignore - await dynamoDB.putItem(params).promise(); + await dynamoDB.putItem(params); return success(params.Item); } catch (e) { return failure({ status: false });
-
Run
yarn build:backend
andyarn cdk deploy
to build+deploy new code, and the size of lambda functions will reduce to ~42 kB!
-
AWS JS SDK v3 has an option to import specific commands, thus reducing bundle size further!
-
Make the following change in
dynamoDB.ts
to import DynamoDBClient from v3.-import { DynamoDB } from "@aws-sdk/client-dynamodb"; +import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; -export default new DynamoDB({}); +export default new DynamoDBClient({});
-
Import and call just the
PutCommand
increateNote.ts
for example:import crypto from "crypto"; -import dynamoDB from "./libs/dynamoDB"; +import dynamoDBClient from "./libs/dynamoDB"; +import { PutItemCommand } from "@aws-sdk/client-dynamodb"; import { success, failure } from "./libs/response";
try { - await dynamoDB.putItem(params); + await dynamoDBClient.send(new PutItemCommand(params)); return success(params.Item); } catch (e) { return failure({ status: false });
-
Run
yarn build:backend
andyarn cdk deploy
to build+deploy new code, and the size of lambda functions will reduce to ~23 kB!
Here's how we find out correlation between lambda size and execution time:
- We get metrics by enabling Active tracing under AWS X-Ray for ListNotes lambda.
- The comparison is between original bundle which imports entire v2 with final bundle which imports specific command in v3.
- For testing, two fresh endpoints are created using Cloudformation and we visit
<ENDPOINT>/Prod/notes
in the browser. - The cold start is the first hit post endpoint creation, and warm start is the second hit after ~3 seconds.
-
A Cloudwatch event was written to trigger both lambdas every 20 mins and 18 values (in ms) for Duration of
AWS::Lambda::Function
were analyzed over 6 hours.Average Min Max Median 90th percentile entire v2 1171.5 1013 1431 1093.5 1193.39 v3 command+client 735.22 693 786 738 775.6 -
Another Cloudwatch event was written to trigger both lambdas every minute and 50 values (in ms) for Duration of
AWS::Lambda::Function
were analyzed.Average Min Max Median 90th percentile entire v2 117.82 85 178 116 139 v3 command+client 116.22 83 176 115.5 136