1

Background

I am building an API using AWS Lambda and API Gateway. Rather than splitting each API endpoint into individual lambda functions I am wrapping them into a single library and using the aws-serverless-express library.

Question

Given that only a portion of the entire API might be used in a single Lambda execution— from a memory utilization standpoint (to cut down on cost) is there a difference between:

var myModule = require("mymodule");

...

function handleSomething1()
{
    myModule.doSomething();
}

function handleSomething2()
{
    ...
}

or

function handleSomething()
{
    require("mymodule").doSomething();
}

function handleSomething2()
{
    ...
}

So for example, a single API request might result in only handleSomething2 being called before the Lambda function is powered down. In that case are we effectively wasting memory by calling var myModule = require("mymodule"); up top?

I suppose the more direct question is, when I var myModule = require("mymodule") does the node.js runtime actually allocate memory for myModule at that moment? Or is it effectively a no-op until I actually do something with myModule?

Jim Heising
  • 4,260
  • 2
  • 16
  • 16

2 Answers2

1

You should always use asynchronous methods and function calls in Node. However Node.js always runs require synchronously and module being required can require other needed modules which is an expensive process.

Even for the context of Lambda this remains the same since if you define 'require' outside of the function, it will be initiated upon Cold start of Lambda and not re-run for subsequent Hot start calls.

More information on Lambda container reuse reference.

Ashan
  • 18,898
  • 4
  • 47
  • 67
  • What do you mean with: `it will be initiated upon Cold start of Lambda and not re-run for subsequent Hot start calls`? Node caches the require, but Lambda is stateless. Every execution (cold or hot) runs without previous knowledge, so the require will be initiated on cold *and* hot run. – Zanon Jul 21 '17 at 00:42
  • When a lambda function invoked, it loads to a container and the code outside the handler will be initiated followed by trigering the handler. The Lambda function will be keep running for about 5 more minutes after handling the initial request waiting for further requests. If a new request comes within tha time, it will only run the code inside the handler function. – Ashan Jul 21 '17 at 01:14
  • Where do you see the 5 minutes part? It's my understanding that the Lambda function will cease as soon as it can. I believe the 5 minutes is the maximum time that a single handler will be allowed to run, but that in most cases it will cease as soon as there is nothing left for it to do. – Jim Heising Jul 21 '17 at 03:08
  • The billing for Lambda function will cease as soon as the callback is called, but the Lambda function will be running behind (HOT) so that it can handle another request. Check the following Stackoverflow Q/A for more info https://stackoverflow.com/questions/34216248/aws-lambda-hot-and-cold-start – Ashan Jul 21 '17 at 04:59
  • Interesting. He does say "...it could be as long as 5 minutes". But in my experience it's usually much much shorter. I wonder if it may have to do with the amount of RAM you allocate for it. – Jim Heising Jul 21 '17 at 05:37
  • That I'm not quite sure, however my experience is, it goes around 5 minutes, since I use a schedule Lambda to keep it HOT. – Ashan Jul 21 '17 at 06:16
0

require() is a synchronous operation that happens in the moment that it is executed. In your example, if the function is not executed, then the module will not be added to the memory.

You may reduce the memory usage with your strategy, but will it be significant? Be careful to not worry too much with micro-optimizations because the best practice (or at least, the standard practice) in Node is to require modules at the beginning and not in the middle of the code.

Zanon
  • 29,231
  • 20
  • 113
  • 126
  • By "In your example" I assume you mean the second one? I understand that the best practice is for modules to be required at the beginning, but that best practice was developed before serverless architectures were commonplace. I guess the follow-up question might be: do the best practices need to be updated when thinking about running node.js on Lambda? – Jim Heising Jul 21 '17 at 03:16
  • Yes, I mean the second example; Yes, many things changes in a serverless context, including what can be considered as best practices. However, I still expect to read a Node.js code with the requires at the top of the file so I know where all sync requests are done and know that the rest of the file will execute only async requests. Like I've said, you can use this strategy to avoid loading unnecessary code, but confirm if it will really make any difference and it's not a bad case of micro-optimization. – Zanon Jul 21 '17 at 04:34