How can I detect cold starts in AWS Lambda?
Asked Answered
R

3

23

Is there a clear way to identify "cold starts", either in runtime in the Lambda itself, or via the logs? I know that cold starts are characterized by longer runtimes, which I can actually see, but I'm looking for a clear cut way.

I'm using Node.js if that matters.

Update: There are two good answers below, for two use cases:

  • Identifying the cold start as the lambda runs.
  • Identifying the cold start from the CloudWatch log.
Rhizocarpous answered 1/11, 2017 at 18:9 Comment(0)
B
27

If you add some initialization code to the top of your NodeJS script, you will be able to tell in the code that it is a cold start, and you will then be able to log that if you want to see it in the logs. For example:

var coldStart = true;
console.log("This line of code exists outside the handler, and only executes on a cold start");


exports.myHandler = function(event, context, callback) {
  if (coldStart) {
    console.log("First time the handler was called since this function was deployed in this container");
  }
  coldStart = false;

   ...
   
  callback(...);
}

Update:

If you only care about seeing cold starts in the logs, Lambda now logs an extra "Init Duration" value in CloudWatch Logs for cold starts.

Brigid answered 1/11, 2017 at 18:45 Comment(5)
While this is good info, I STRONGLY suggest firing CloudWatch Custom Metrics so that you can easily measure and graph this information.Gully
@Mark B, how to check the cold start in case of python scripts?Cavalla
@Manoranjan there is no difference in the behavior of a Python Lambda function. You would use a value defined outside of the handler function in Python, just like this JavaScript example.Brigid
@SpiritualOverflow, that's almost identical. Set a variable in the Python script for your Lambda function outside the handler function: cold_start = True. That code line will run during instance initialization. Then inside a handler function, check whether that variable is set and reset it afterwards: if cold_start: print("cold_start happened"); cold_start = False. (Multiple statements on one line aren't really allowed in Python, so make a proper block after the if condition.)Pierro
@SpiritualOverflow, or make a counter for the number of invocations from an instance. Outside the handler functions: invocation_count = 0, and inside the/any handler: invocation_count += 1. Then you can test on invocation_count in the/any handler: if it's zero, your instance was just initialized. If it isn't zero, the instance handled events prior. This is even better than my earlier comment ^ as it'll tell you how many events were handled by an individual instance. I used that trick for this experiment: xebia.com/blog/….Pierro
S
33

As an update, AWS now provide visible info on cold starts in the form of "Init Duration" , inside the Report section of a Cloudwatch Log. The calls that do not suffer from a cold start will not contains this information in the log

Duration: 1866.19 ms Billed Duration: 1900 ms Memory Size: 512 MB Max Memory Used: 163 MB Init Duration: 2172.14 ms

Symmetrical answered 10/12, 2019 at 7:3 Comment(3)
Great addition - using that field in CloudWatch logs no longer requires scripts to store global variables (initialized during an instance start) to recognize a cold start from a handler function.Pierro
Init Duration seems to be more about time to initialize lambda, but does not include time spent by program initialization, until request if started to be really processed. This is visible from LOGs, where for example Init Duration: 1010.66 ms and INFO lambdainternal.AWSLambda - Started AWSLambda in 28.575 seconds (JVM running for 30.442) (Spring Boot lambda)Unscratched
I do not have this column. How do I add it? Also, can I make it appear in the response?Jannjanna
B
27

If you add some initialization code to the top of your NodeJS script, you will be able to tell in the code that it is a cold start, and you will then be able to log that if you want to see it in the logs. For example:

var coldStart = true;
console.log("This line of code exists outside the handler, and only executes on a cold start");


exports.myHandler = function(event, context, callback) {
  if (coldStart) {
    console.log("First time the handler was called since this function was deployed in this container");
  }
  coldStart = false;

   ...
   
  callback(...);
}

Update:

If you only care about seeing cold starts in the logs, Lambda now logs an extra "Init Duration" value in CloudWatch Logs for cold starts.

Brigid answered 1/11, 2017 at 18:45 Comment(5)
While this is good info, I STRONGLY suggest firing CloudWatch Custom Metrics so that you can easily measure and graph this information.Gully
@Mark B, how to check the cold start in case of python scripts?Cavalla
@Manoranjan there is no difference in the behavior of a Python Lambda function. You would use a value defined outside of the handler function in Python, just like this JavaScript example.Brigid
@SpiritualOverflow, that's almost identical. Set a variable in the Python script for your Lambda function outside the handler function: cold_start = True. That code line will run during instance initialization. Then inside a handler function, check whether that variable is set and reset it afterwards: if cold_start: print("cold_start happened"); cold_start = False. (Multiple statements on one line aren't really allowed in Python, so make a proper block after the if condition.)Pierro
@SpiritualOverflow, or make a counter for the number of invocations from an instance. Outside the handler functions: invocation_count = 0, and inside the/any handler: invocation_count += 1. Then you can test on invocation_count in the/any handler: if it's zero, your instance was just initialized. If it isn't zero, the instance handled events prior. This is even better than my earlier comment ^ as it'll tell you how many events were handled by an individual instance. I used that trick for this experiment: xebia.com/blog/….Pierro
C
13

If you're looking at CloudWatch logs, each LogGroup for your Lambda function represents a separate container and therefore the first invocation for that LogGroup is your cold start.

Cyndie answered 2/11, 2017 at 6:15 Comment(5)
This statement is very interesting and might be useful. Would you please point me to the documentation where it is written so?Maitilde
@Maitilde I asked the same question to Yan Cui here and I got this response. It seems like it is undocumented but confirmed by someone from Amazon. I can confirm it though from experience that logging something during a cold start will be seen at the beginning of the CloudWatch LogGroup.Cyndie
Thanks, I think my experience and intuition confirm this way of working too.Maitilde
I wrote some test code to check this (used let coldStart = true outside Lambda handler function, and coldStart = false inside function) and can confirm that a cold start always starts a new LogGroup in CloudWatch.Chaudoin
@Chaudoin Thanks for confirming that.Cyndie

© 2022 - 2024 — McMap. All rights reserved.