DEV Community

Cover image for 100 millions Lambda execution and guess our AWS $$$ Bill - GoLang
Rakesh Sanghvi
Rakesh Sanghvi

Posted on • Originally published at awsmantra.com

100 millions Lambda execution and guess our AWS $$$ Bill - GoLang

Little Background:-

in 2019 we started moving from server to serverless and started adopting AWS Lambda + GoLang for any new development. My chief architect and current CTO Ben Pyle(Blog) came up with the GoLang pattern which we used in all our Microservices. It was one of the best architectural decisions we have made in recent times.

As of now, we have more than 300+ lambdas deployed in each of our environments. 99% of those lambdas are written in GoLang and the rest 1% in either Node, Python or Java. Most of us had a Java background in my organization when we started in 2019. A couple of GoLang training sessions have helped us in a smooth transition.

This post will help you to understand and implement AWS Lambda written in GoLang.

AWS Bill:-

Here is a screenshot of our recent month's bill. You can see we had 98+ million lambda requests and our total AWS bill for lambda was $108 after our compute savings plan.

AWS Bill

  • Keep 3 things in mind when you write Lambda.

    1) Runtime
    2) Package Size
    3) Startup logic.

  • The majority of the Go Lambda that we have in my organization is configured with 128 MB memory (that's the minimum memory we can configure for AWS Lambda).

  • Go executable binary size is approx 8 MB for most of our Lambda. Fewer footprints for runtime.

  • Here are a couple of runtime examples. You can see the COLD START time in this example is 210.65 ms and it used 45 MB of memory. As GoLang compiles code to native code and executes pretty fast, most of the time cold start duration will be a few milliseconds to 1 second.

 Duration: 3.93 ms Billed Duration: 4 ms Memory Size: 
 128 MB Max Memory Used: 44 MB Init Duration: 210.65 ms 

 Duration: 1.36 ms Billed Duration: 2 ms Memory Size: 
 128 MB Max Memory Used: 45 MB 

 Duration: 16.44 ms Billed Duration: 17 ms Memory Size: 
 128 MB Max Memory Used: 45 MB
Enter fullscreen mode Exit fullscreen mode

Examples:-

We follow industry best practices for implementing AWS Lambda.

1. Optimizing static initialization:-
This is the "INIT" code that happens outside of the handler. Initialized your variable or connection to other services.

2. Single-purpose lambdas:-
each lambda has a single responsibility. For any CRUD operation, we implement 4 lambdas (Create, Update, Delete and Get)

This example is implemented using AWS CDK and AWS SAM, whichever is your preferred way, clone the repo from GitHub and try it...

You can download the source code from here

AWS SAM Deployment Instructions:-

1) change the region name in the template.yaml file if you are deploying other than us-west-2

  Region:
    Type: String
    Description: AWS Region Name
    Default: us-west-2
Enter fullscreen mode Exit fullscreen mode

2) Changed directory to pattern directory sam

cd sam
Enter fullscreen mode Exit fullscreen mode

3) From the command line, use the AWS SAM CLI command to deploy the app.

sam deploy --stack-name employee-functions --capabilities CAPABILITY_NAMED_IAM --guided --profile <your profile name>
Enter fullscreen mode Exit fullscreen mode

4) Once the stack deploys successfully, grab the following API Gateway URL. We will use this URL to execute our API.

Key            APIEndpoint
Description    endpoint of EmployeeApi
Value          https://fy6fpson09.execute-api.us-west-2.amazonaws.com/
Enter fullscreen mode Exit fullscreen mode

AWS CDK Deployment Instructions:-

1) change the region name in the config.ts file if you are deploying other than us-west-2.

 export const getConfig = (): Options => {
    return {
        defaultRegion: "us-west-2",
        apiStageName: "main",
    }
}
Enter fullscreen mode Exit fullscreen mode

2) Changed directory to pattern directory cdk

cd cdk
Enter fullscreen mode Exit fullscreen mode

3) From the command line, use the AWS CDK CLI command to deploy the app.

cdk deploy --all -a "npx ts-node bin/app.ts" --profile <your profile name>
Enter fullscreen mode Exit fullscreen mode

4) Once the stack deploys successfully, run the following AWS CLI command to get the API URL. it's using JQ.

aws cloudformation list-exports --query "Exports[?Name=='employee-api-url'].Value" --output text --profile <your profile name>
Enter fullscreen mode Exit fullscreen mode

API Execution:-

1) Add Employee:-

curl -X POST -H 'Content-type: application/json'
https://fy6fpson09.execute-api.us-west-2.amazonaws.com/main/employee \
--data '{
    "Age": 30,
    "FirstName": "Kyle",
    "LastName" : "Gray"  
}'
Enter fullscreen mode Exit fullscreen mode

You will see the following record in DynamoDB.

DynamoDB

2) Get Employee:-

curl -X GET -H 'Content-type: application/json' https://fy6fpson09.execute-api.us-west-2.amazonaws.com/main/employee/2414 | jq

Response:-
{
  "Id": 2414,
  "firstName": "Kyle",
  "lastName": "Gray",
  "age": 30,
  "createdDatetime": "2023-03-06T05:23:59.471574185Z",
  "modifiedDatetime": "0001-01-01T00:00:00Z"
}
Enter fullscreen mode Exit fullscreen mode

3) Update Employee:-

curl -X PUT -H 'Content-type: application/json' https://fy6fpson09.execute-api.us-west-2.amazonaws.com/main/employee/2414
--data '{
    "Age": 31,
    "FirstName": "Kyle",
    "LastName" : "Gray"
}'
Enter fullscreen mode Exit fullscreen mode

4) Delete Employee:-

curl -X DELETE -H 'Content-type: application/json' https://fy6fpson09.execute-api.us-west-2.amazonaws.com/main/employee/2414
Enter fullscreen mode Exit fullscreen mode

Cleanup:-

sam delete --stack-name employee-functions --profile <your profile name>
                               OR
cdk destroy --profile <your profile name>
Enter fullscreen mode Exit fullscreen mode

Wrap-Up:-

As you can see how it's easy to understand, implement and deploy GoLang lambda in an AWS environment. I would highly recommend trying it yourself and for your organization. We have a couple of legacy applications where we use an ECS container with 1 CPU and 2 GB RAM, this cost us around $32 per month. Even though the traffic pattern is not consistent, we end up paying $32 per month per task. In the case of serverless, we pay per use and don't pay anything when there is no traffic. In the next post, I will implement the same example with low code or less code using Step Function + universal target.

Top comments (0)