COST 1: How do you optimize your Serverless application’s costs?
Design, implement, and optimize your application to maximize value. Asynchronous design patterns and performance practices ensure efficient resource use and directly impact the value per business transaction.
Resources
AWS Lambda Best Practices
re:Invent 2019 - Serverless architectural patterns and best practices
re:Invent 2019 - Optimizing your Serverless applications
Best Practices:
-
Minimize external calls and function code initialization: Functions may call other managed services and third-party APIs to operate as intended. Functions may also use application dependencies that may not be suitable for ephemeral environments. Reviewing and optimizing both can directly impact on value provided per invocation.
-
Optimize logging output and its retention: Review logging level, logging output, and log retention to ensure that they meet your operational needs. This helps prevent unnecessary logging and data retention while ensuring that you have the minimum levels necessary for workload operation.
-
Use cost-aware usage patterns in code: Reduce the time consumed by running functions by eliminating job-polling or task coordination.
-
Optimize function configuration to reduce cost: Functions unit of scale is memory where CPU, Network and I/O are proportionately allocated. Consider benchmarking and reviewing whether you are under/overutilising what your function is allocated to. Benchmark your Lambda function execution with various memory settings as under some conditions the added Memory/CPU may lower the duration and with this new combination reduce the cost of each invocation.
Improvement Plan
Minimize external calls and function code initialization
- AWS Lambda reports the time it takes to initialize application code in Amazon CloudWatch Logs. Consider reviewing application code and its dependencies to improve overall execution to maximise on value.
- AWS Lambda reuses execution contexts, meaning that you can take advantage of making external calls to resources where their results might be used more than once over a period of time.
- Use TTL mechanisms inside your function handler to ensure you can prevent additional
external calls that incur additional execution time while preemptively fetching non-stale
data.
AWS Lambda Execution Context
- When using AWS Lambda Layers or Serverless Applications provisioned by AWS Serverless Applications Repository, be sure to understand any associated charges that these may incur.
- Ensure that your Lambda function only has access to what its application code needs, and regularly review if your function has a predicted usage pattern (i.e Amazon S3, Amazon DynamoDB tables).
Optimize logging output and its retention
- With AWS Lambda, any standard output statements are ingested into Amazon CloudWatch Logs.
- Capture and emit business and operational events that are necessary to help you understand your function, its integration, and its interactions.
- Use a logging framework and environment variables to dynamically set logging level, and when applicable, sample debugging logs for a percentage of invocations.
- With Amazon API Gateway, enable access logs, and selectively review its output format and request fields that might be necessary.
- With AWS AppSync, enable access logs for debugging purposes.
Setting up Access Logs in AWS AppSync
Setting up Access Logs in Amazon API Gateway
- Set log expiration for each Amazon CloudWatch Log Group as they are kept indefinitely by default. For log archival, CloudWatch Logs can be exported to Amazon S3 and stored in Amazon S3 Glacier for more cost-effective retention. Alternatively, you can use CloudWatch Log Subscriptions to filter, pre-process, or ship log entries to trusted third-party providers.
- Archive and export CloudWatch Logs to Amazon S3, and store in Amazon S3 Glacier for more cost-effective retention where applicable.
- Alternatively, you can use CloudWatch Log Subscriptions to filter, pre-process, or ship log entries to trusted third-party
providers.
Real-time Processing of Log Data with Subscriptions
Working with Log Groups and Log Streams
Example: Automatically setting Amazon CloudWatch Logs retention
Exporting Amazon CloudWatch Logs to Amazon S3
Use cost-aware usage patterns in code
- Refrain from introducing idleness where your AWS Lambda functions might be waiting for external activities to complete.
- With AWS Step Functions, you can poll for the status of tasks more efficiently. Long polling or waiting has the effect of increasing the costs of Lambda functions as they are waiting idle and at the same time reducing overall account concurrency, potentially impacting the ability of other functions to run.
- With Amazon CloudWatch, create custom metrics asynchronously when possible by using CloudWatch Embedded Metric Format.
- Alternatively, use canonical log lines and a log subscription to convert canonical lines into metrics. Creating metrics synchronously within your AWS Lambda function impact on overall execution time, and has a direct correlation with costs.
- AWS Lambda functions can be triggered based on events ingested into Amazon SQS queues, Amazon S3 buckets, Amazon Kinesis streams, where AWS manages the polling infrastructure on your behalf with no additional cost.
- Use EventBridge to integrate with SaaS as opposed to polling for third-party software as a service (SaaS) providers.
- Carefully consider and review recursion, and establish timeouts to prevent run away
functions.
Ten Things Serverless Architects should know
Optimize function configuration to reduce cost
- AWS Lambda proportionally allocates CPU, Network, and I/O to the memory allocated. Benchmark your AWS Lambda functions with differing amounts of memory allocated, and review and compare memory settings that reduce your overall execution to ensure you have the most cost-effective invocation.