The lambda-warmer-py
package contains a single decorator that makes it easy to minimize the drag of aws lambda cold
starts. Just ...
- wrap your lambdas in the
@lambdawarmer.warmer
decorator and - ping your lambda once every 5 minutes
and you'll cut your cold starts way down.
Configuration options are also available that ...
- allow for keeping many concurrent lambdas warm
- sending CloudWatch metrics tracking the number of cold and warm starts by lambda function name
The warming logic is a python adaption* of the js
package, lambda-warmer
. Read more about the background to this approach on his site here
and some best practices on lambda optimization here.
* In addition to supporting CloudWatch Metrics, there are some small differences in parameterization. See configuration.
pip install lambda-warmer-py
Incorporating the lambda warmer into your existing lambdas only requires adding a single decorator.
import lambdawarmer
@lambdawarmer.warmer
def your_lambda_function(event, context):
pass
If your handler is not a function (for example, if you use Mangum), just wrap its invocation in a function.
from fastapi import FastAPI
from mangum import Mangum
import lambdawarmer
app = FastAPI()
handler = Mangum(app)
@lambdawarmer.warmer
def your_lambda_function(event, context):
return handler(event, context)
To leverage the concurrency options, the package will invoke your lambda multiple times. This means that the deployed lambda will need the following permissions
- Effect: Allow
Action: lambda:InvokeFunction
Resource: [your-lambdas-arn]
In order for the lambda warmer to track cold and warm start metrics, the lambda execution role will need permissions to send metric data to CloudWatch. The required policy action is
- Effect: Allow
Action: cloudwatch:PutMetricData
Create a CloudWatch Rule that periodically invokes your lambda directly and passes the following json as the event
{
"warmer": true,
"concurrency": (int, defaults to 1)
}
It is possible to change the warmer
and concurrency
names by overriding parameters in the warmer
decorator. See
configuration for details.
The lambda warmer is configured via the function parameters for the @warmer
decorator. It takes the following ...
Name of the field used to indicate that it is a warm up event.
Name of the field used to set the number of concurrent lambdas to invoke and keep warm.
Number of millis a concurrent warm up invocation should sleep. This helps avoid under delivering on the concurrency target.
Whether or not CloudWatch Metrics for the number of cold/warm starts will be sent at each invocation. The metrics names
are ColdStart
and WarmStart
, are recorded under LambdaWarmer
namespace, and can be filtered by lambda function name.
Using alternative event and delay configurations is straightforward.
@lambdawarmer.warmer(flag='am_i_a_warmer', concurrency='how_many_lambdas', delay=150)
def your_lambda_function(event, context):
pass
This implementation will expect events of the form
{"am_i_a_warmer": true, "how_many_lambdas": (int)}
and all concurrent executions will delay for 150 milliseconds.
If you want to track metrics on number of warm/cold starts activate that functionality in the decorator.
@lambdawarmer.warmer(send_metric=True)
def your_lambda_function(event, context):
pass
Note: Configuration options that are excluded from this implementation but can be found in the js
version are
test
: Testing is handled in the unittests using mocks/fakes instead of flagged invocationslog
: Logging levels of imported python packages should be handled via the stdliblogging
module.correlationId
. This has been made into the snake casedcorrelation_id
since we're in python and is always set to the current lambda'saws_request_id
field as is recommended in the originallambda-warmer
package.