Matias Cicero
Matias Cicero

Reputation: 26281

AWS Lambda Function lifetime

Consider the following AWS Lambda function:

var i = 0;
exports.handler = function (event, context) {
    context.succeed(++i);
};

Executing this function multiple times, I end up with an output similar like the following:

> 0
> 1
> 2
> 0
> 1
> 0
> 3
> 2
> 4
> 1
> 2

As you can see, it seems like there are 3 singletons of the script, and I am randomly ending up in one of them when I execute the function.

Is this an expected behaviour? I couldn't find any related information on the documentation.

I'm asking this because I intend to connect to MySQL and keep a connection pool:

var MySQL = require('mysql');
var connectionPool = MySQL.createPool({
   connectionLimit: 10,
   host: '*****',
   user: '*****',
   pass: '*****',
   database: '*****'
});

function logError (err, callback) {
    console.error(err);
    callback('Unable to perform operation');
}

exports.handler = function (event, context) {
    connectionPool.getConnection(function (err, connection) {
        err && logError(err, context.fail);
        connection.query('CALL someSP(?)', [event.user_id], function (err, data) {
            err && logError(err, context.fail);
            context.succeed(data[0]);
            connection.release();
        });
    });
};

The connection pool needs to be disposed using connectionPool.end() but where shall I execute this?

If I add it at the end of the script (after the handler), then the connection pool will be closed immediately when the lambda function first executes.

If I dispose the connection pool inside the handler, then the connection pool will be closed for future requests.

Furthermore, should I dispose it? If I don't dispose it, the connections will be kepts in the pool and in memory, but as you have seen in the first code sample, AWS keeps ~ 3 singletons of my module, that would mean that I'd end up with 3 different connection pools, with 10 connections each.

Upvotes: 3

Views: 7048

Answers (1)

Jonathan Henson
Jonathan Henson

Reputation: 8206

Unless I am badly misunderstanding your question, this is well documented and expected behavior for lambda. See here: https://aws.amazon.com/lambda/faqs/

Lambda spins up instances of your container to match the usage patterns of your lambda function. If it is not being used at the moment, then it will spin it down, if it is being used heavily, then more containers will be created. You should never depend on persistent state in a lambda function. It is ok to use state if it is for the lifecycle of your function, or you are optimizing something.

As far as I know, you can not control the number of function instances in memory at any given time, so if you are worried about using up your mysql connections, you should design accordingly.

From the documentation:

"AWS Lambda can start as many copies of your function as needed without lengthy deployment and configuration delays. There are no fundamental limits to scaling a function. AWS Lambda will dynamically allocate capacity to match the rate of incoming events."

As applies directly to your mysql question, I would always return your connection to the pool when you are finished using it. Then I would do some calculations on how many concurrent requests you expect to have and plan accordingly with your mysql server configuration.

Upvotes: 6

Related Questions