In this lesson, you will learn how to properly open and close database connections to ensure your Node.js application remains stable and avoids "socket leaks."
Understanding the Socket Lifecycle
Every time your application talks to a database, it uses a network socket. If you open a new connection for every single query and forget to close it, your database will eventually run out of available sockets—this is known as a socket leak. Once the limit is hit, your application will crash or stop responding to database requests entirely.
To manage this, we follow a simple "Lifecycle Management" pattern: Acquire, Use, Release.
The Pattern in Practice
Instead of manually creating a connection for every task, we treat the database connection as a finite resource that must be returned to the system. If you are using a database driver, it usually manages a "Pool" of connections for you. Your job is to check out a connection, perform your work, and ensure it is returned, regardless of whether the operation succeeds or fails.
async function fetchUserById(userId) {
// 1. Acquire: Get a connection from the pool
const client = await pool.connect();
try {
// 2. Use: Perform the database operation
const result = await client.query('SELECT * FROM users WHERE id = $1', [userId]);
return result.rows[0];
} catch (error) {
console.error('Database query failed', error);
throw error;
} finally {
// 3. Release: ALWAYS return the connection to the pool
// This prevents socket leaks even if an error occurs!
client.release();
}
}
Why the finally Block is Vital
The finally block is your best friend in Connection Lifecycle Management. Because it executes regardless of whether the code inside the try block succeeded or failed, it guarantees that your connection is released back to the pool. Without this, an error could leave the connection "hanging," slowly eating away at your available resources until the application halts. Always ensure that every connection you open has a corresponding release path that is guaranteed to run.
Key Takeaway: Prevent socket leaks by always using a finally block to release database connections back to the pool, ensuring that every acquired resource is returned even if an error occurs.