2

Our current implementation is to open one database connection outside of the Lambda handler. When the backing Lambda container terminates, the connection is then left open/idle.

Can I make the new container close the previous old container's database connection?

Are there any hooks available like an onContainerClose()?

How can we close the previous open connection which cannot be used anymore, when the Lambda cold starts?

4
  • 1
    You close it within your code, it has nothing to do with Lambda. The Lambda "container" will "stop" when your handler returns, so close it wherever you're done with your connection. Commented Feb 26, 2022 at 10:10
  • Thank you for the answer, but what if I want to reuse the DB connection and it is possible if container is reused, however, I want that only when the new container is formed the previous container automatically close the db connection. Could you please suggest some good practice for this? Commented Feb 27, 2022 at 7:29
  • if I mentioned connection string outside the handler function then it will reuse the connection in warm start, however, in cold start case what will happen to the previous open connection, how can we close that? Commented Feb 27, 2022 at 7:57
  • Ah I now understand your question - let me type up an answer as it's too long for a comment Commented Feb 27, 2022 at 14:05

1 Answer 1

2

In the background, AWS Lambda functions execute in a container that isolates them from other functions & provides the resources, such as memory, specified in the function’s configuration.

Any variable outside the handler function will be 'frozen' in between Lambda invocations and possibly reused. Possibly because depending on the volume of executions, the container is almost always reused though this is not guaranteed.

You can personally test this by invoking a Lambda with the below source code multiple times & taking a look at the response:

let counter = 0 exports.handler = async (event) => { counter++ const response = { statusCode: 200, body: JSON.stringify(counter), }; return response; }; 

This also includes database connections that you may want to create outside of the handler, to maximise the chance of reuse between invocations & to avoid creating a new connection every time.

Regardless of if the Lambda function is reused or not, a connection made outside of the handler will eventually be closed when the Lambda container is terminated by AWS. Granted, the issue of "zombie" connections are much less when the connection is reused but it is still there.

When you start to reach a high number of concurrent Lambda executions, the main question is how to end the unused connections leftover by terminated Lambda function containers. AWS Lambda is quite good at reliably terminating connections when the container expires but you may still run into issues getting close to your max_connections limit.

How can we close the previous open connection which cannot be used anymore, when the Lambda cold starts?

There is no native workaround via your application code or Lambda settings to completely getting rid of these zombie connections unless you handle opening and closing them yourself, and take the added duration hit of creating a new connection (still a very small number).

To clear zombie connections (if you must), a workaround would be to trigger a Lambda which would then list, inspect & kill idle leftover connections. You could either trigger this via an EventBridge rule operating on a schedule or trigger it when you are close to maxing out the database connections.

These are also great guidelines to follow:

  1. Ensure your Lambda concurrent executions limit does not exceed your database maximum connections limit: this is to prevent the database from maxing out connections

  2. Reduce database timeouts (if supported): limit the amount of time that connections can be idle & left open, for example in MySQL tweaking the wait_timeout variable from the default 28800s (8 hour) to 900 seconds (15 minutes) can be a great start

  3. Reduce the number of database connections: try your best to reduce the connections you need to make to the database via good application design & caching

  4. If all else fails, look into increasing the max connections limit on the databe

Sign up to request clarification or add additional context in comments.

1 Comment

In addition to all the guidelines given here, I would recommend taking a look into using a database proxy like RDS Proxy. This will simplify your situation significantly, as the number of "client connections" (lambda => db proxy) will only count against your total number of "database connections" (db proxy => db) if they're being actively borrowed

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.