aws-lambdaamazon-rdsamazon-rds-proxy

Should I close an RDS Proxy connection inside an AWS Lambda function?


I'm using Lambda with RDS Proxy to be able to reuse DB connections to a MySQL database.

Should I close the connection after executing my queries or leave it open for the RDS Proxy to handle?

And if I should close the connection, then what's the point of using an RDS Proxy in the first place?

Here's an example of my lambda function:

const mysql = require("mysql2/promise")

const config = {
  host: process.env.RDS_HOST, // RDS Proxy endpoint here
  user: process.env.RDS_USER,
  database: process.env.RDS_DATABASE,
  password: process.env.RDS_PASSWORD,
  ssl: "Amazon RDS"
}

exports.handler = async (event) => {
  let connection

  try {
    connection = await mysql.createConnection(config)
    console.log(`Connected to db. ConnectionId: ${connection.threadId}`)

    // Do some queries
  } catch (err) {
    return handleError(err)
  } finally {
    if (connection) await connection.end() // Should I close the connection here?
  }

  return response(200, "Success")
}

EDIT: Beware that initializing the connection outside the handler (global scope) will make the lambda function retain the value of the connection variable between invocations in the same execution environment which will result in the following error Can't add new command when connection is in closed state when calling the lambda function multiple times in a short period of time because the connection is already closed in the first invocation, so I'd better suggest defining the connection inside the handler not outside.


Solution

  • TDLR: always close database connections

    The RDS proxy sits between your application and the database & should not result in any application change other than using the proxy endpoint.


    Should I close the connection after executing my queries or leave it open for the RDS Proxy to handle?

    You should not leave database connections open regardless of if you use or don't use a database proxy.

    Connections are a limited and relatively expensive resource.

    The rule of thumb is to open connections as late as possible & close DB connections as soon as possible. Connections that are not explicitly closed might not be added or returned to the pool. Closing database connections is being a good database client.

    Keep DB resources tied up with many open connections & you'll find yourself needing more vCPUs for your DB instance which then results in a higher RDS proxy price tag.


    And if I should close the connection, then what's the point of using an RDS Proxy in the first place?

    The point is that your Amazon RDS Proxy instance maintains a pool of established connections to your RDS database instances for you - it sits between your application and your RDS database.

    The proxy is not responsible for closing local connections that you make nor should it be.

    It is responsible for helping by managing connection multiplexing/pooling & sharing automatically for applications that need it.

    An example of an application that needs it is clearly mentioned in the AWS docs:

    Many applications, including those built on modern serverless architectures, can have a large number of open connections to the database server, and may open and close database connections at a high rate, exhausting database memory and compute resources.


    To prevent any doubt, also feel free to check out an AWS-provided example that closes connections here (linked to from docs), or another one in the AWS Compute Blog here.