Building Efficient AWS Lambda Functions: Tips and Tricks

Building Efficient AWS Lambda Functions: Tips and Tricks

In today's serverless world, AWS Lambda has become a widely used solution for building scalable and cost-effective applications. By leveraging the power of AWS Lambda, developers can focus on writing code without worrying about infrastructure management. To maximize the potential of AWS Lambda, it's important to build efficient functions that deliver optimal performance. In this article, we will see how to create lambda functions using Python and some valuable tips and tricks to help you make efficient AWS Lambda functions.

A step-by-step guide to creating Efficient AWS Lambda Functions using Python

In today's era, AWS Lambda functions become the preferred choice for organizations to develop microservice architectures. Python is preferably used for rapid development. However, when utilizing Python, it is essential to be cautious whenever you build your application. This precaution is crucial as there may arise scenarios where the code fails to function with the latest deployment where you might have mentioned installing some latest Python packages instead of fixed versions.

You can refer to Best way to create python project link to create an efficient Python project.

  • Let's create a project with the name send_sms whose functionality is to send sms to the customers with the following structure

  • send_sms/services/send_sms_service.py

      import requests
    
      def send_sms_to_customer(customer_phone_number, message):
          url = 'https://xyz.com'
          #requests.post(url, data={'phone_number': customer_phone_number, 'message': message})
          return { 'status': 'success'}
    
  • lambda_function.py

      from send_sms.services.send_sms_service import send_sms_to_customer
    
      def lambda_handler(args, event):
          return send_sms_to_customer(args['phone_number'], args['message'])
    
  • requirements.txt

      requests==2.31.0
    
  • Install virtualenv using command pip install virtualenv.

  • Goto send_sms project folder and create virtualenv and activate virtualenv using the below commands.

      virtualenv virtualenv
      source virtualenv/bin/activate
    
  • Now install your requirements.txt packages using the below command which will install the requests package with version 2.31.0.

      pip install -r requirements.txt
    
  • Create folder name send_sms_deployment inside send_sms folder.

  • Copy your lambda_function.py, send_sms package and all folders inside virtualenv/lib/python3.10/site-packages into send_sms_deployment folder

  • zip all files and folder inside send_sms_deployment folder with name send_sms.zip

  • Login to your AWS console and navigate to Lambda. Click on Create function

    Provide the function name as send_sms and select Python version which you required. Click on create function which will create function for you with name send_sms.

  • Inside code tab click on upload from and select .zip file. Select the zip file which we have just created with name send_sms.zip inside send_sms_deployment folder.

  • Click on save.

  • Go to the Test section beside code section and provide the below json from the screenshot

  • Click on Test. If you get { "status": "success" } response then congratulation!!. You are able to create your Lambda function successfully.

Important things you should know?

  • While running Python application on AWS Lambda, AWS doesn't consider virtualenv. It checks whether modules or packages are in the relative path or not. That is the reason we copied entire site packages to the root-level folder.

  • If any package is not found in the relative path then AWS try to search in the AWS Lambda layer (I will cover this in the next article). The lambda layer is the place where you can place your packages and modules.

  • If any package is not found in the AWS Lambda layer then it tries to find out in AWS predefined packages. AWS provides a list of predefined packages which you can directly import without putting them inside your zip file. eg. boto3, datetime etc.

  • If you are performing some IO operation then you have write access to only /tmp folder where you can perform write operations.

  • Whenever your Lambda function gets triggered AWS keeps your lambda function warm for the next 2 hours. It means AWS keeps your function in a running state. If any request comes within 2hrs then there won't be any lag to start your execution but if it's beyond 2hrs then again AWS will take time to make your function warm.

  • Handler: It is the entry point from where application execution starts. You can find it inside the code section under Runtime settings. lambda_function is your module name that has to be at the root level and lambda_handler is the method inside it which accepts two arguments args and event. args contained input request and the event will contain an event through which lambda gets triggered

  • General configuration: This one is an important setting in terms of execution where you can set a timeout, RAM and disk space

  • Permissions: Here you can set permissions for Lambda to access other services from AWS

Pricing

There is a common misconception regarding the pricing model of AWS Lambda, assuming that it is solely based on a pay-per-request structure. However, it's important to understand that while AWS Lambda does follow a pay-per-request approach, the pricing is also influenced by the runtime usage, specifically the duration for which your Lambda function runs.

  • Pay per request

    • The first 1,000,000 requests are free

    • $0.20 per 1 million requests thereafter ($0.0000002 per request)

  • Pay per duration

    • 400,000 seconds if the function is 1GB RAM per month free

    • 3,200,000 seconds if the function is 128 MB RAM per month free

    • After that $1.00 for 600,000 GB-seconds

Limitation

  • The deployment zip file should not exceed 50MB

  • The uncompressed zip file should not exceed 250MB

  • You can use /tmp folder for any write operation

  • Max RAM you can set up to 10GB

  • Max execution time is 15 mins after that your execution will get timeout.

Tips and Tricks

  • How to choose the Right execution Configuration:

    • Before creating your Lambda function first check whether your function is going to use too much memory or is it going to take more time to execute it

    • Experiment and benchmark different memory sizes to find the spot that provides the best balance between performance and cost.

  • How to tackle deployment size limitation

    • Nowadays libraries, packages and application size is getting bigger and bigger hence it is very important to select the type of deployment for AWS Lambda.

    • AWS Lambda also supports Docker Image deployment having a size limitation of 10GB. You can go for a Docker image by specifying the entry point. (Will cover AWS Lambda with Docker image in upcoming articles).

  • How to Optimize Cold Start Times

    • Cold starts occur when a Lambda function is invoked for the first time or after a period of inactivity. They can impact the overall performance of your application.

    • Reduce the deployment package size by removing unnecessary packages.

    • Provisioned concurrency keeps a set number of instances warm, reducing cold start times. It ensures that there are always available instances ready to handle requests, But it adds additional cost.

  • Which coding language to be used

    • AWS supports a list of languages. Selection is based on your specific use case, your requirements and development preferences.

    • Try to avoid heavy frameworks such as spring boot which takes time to start your application and increases your cold start time

  • Use environment variables

    • AWS provides support to set env variables from the console itself. It is recommended to keep your env-based variable like bucket name, database url, third party integration urls etc in this section.
  • How to secure lambda function

    • Always try to keep your lambda function in your private subnet

    • Enhance the security and access control of your Lambda function by implementing a role-based policy. Rather than explicitly specifying AWS access and secret keys within your function, it is advisable to attach an appropriate S3 policy to the role associated with your Lambda function. This way, when your function requires access to the specific S3 bucket, the necessary permissions can be granted seamlessly through the role, ensuring a more robust and manageable security configuration.

  • Integrations

    • AWS Lambda supports a lot of trigger and destination endpoints. Before writing any custom code always check whether integration is already available or not.

    • Few examples like triggering lambda after uploading a file on s3 to perform some Excel file analysis, and triggering lambda after putting data inside SQS or kinesis. After execution of lambda put a response inside SNS topic to send an email.

  • Monitor and Fine-Tune

    • Every function call log is recorded inside the Cloudwatch log. Most of the time while creating a lambda function policy gets directly attached to the role to write to cloud watch logs and then we forgot to check the size of cloud watch logs which causes high cost. Always keep expiry to your cloud watch logs.

    • You can configure failure and success events by configuring add destination.

Conclusion

Building efficient AWS Lambda functions is crucial for maximizing performance, minimizing costs, and delivering a seamless user experience. By following the tips and tricks mentioned in this article, you can optimize your functions for speed, scalability, and cost-effectiveness. Experiment, monitor, and iterate to continuously refine your Lambda functions and unlock the true potential of serverless architecture.

Remember, efficiency is a journey, and each improvement brings you closer to building high-performing serverless applications with AWS Lambda.