close database connection after calling callback
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
If a database API uses callbacks, the connection must stay open until the asynchronous work and the callback-driven processing are actually finished. Closing the connection too early is a common bug in Node.js code, because the outer function returns before the query callback runs.
Core Sections
Understand the lifecycle problem
In callback-based code, this pattern is wrong:
connection.end() runs immediately after the query is scheduled, not after the callback completes. Depending on the driver and timing, you may see incomplete work, socket errors, or nondeterministic behavior.
Close the connection inside the final callback path
If you are managing a single connection directly, close it after the query callback has finished whatever follow-up work it needs to do.
That guarantees the connection stays open for the query lifecycle.
Handle nested async work carefully
Sometimes the query callback triggers more asynchronous work. In that case, do not close the connection until the true final callback completes.
The rule is simple: close the connection only after the last async step that still depends on it or on the query result flow.
Prefer pools for real applications
For request-driven servers, opening and closing one raw connection per operation is often not the best design. A connection pool is usually safer and more scalable. With a pool, you typically release the connection back to the pool instead of ending the whole underlying client every time.
This pattern avoids exhausting the database with constantly created and destroyed connections.
Promises and finally are easier to reason about
If your driver supports promises, modernizing the code often makes resource handling clearer.
This does not change the underlying rule. It just makes the cleanup path harder to forget.
Always close on error paths too
One of the easiest ways to leak connections is to close them on success but not on failure. Every branch that exits the operation should either end or release the connection appropriately.
That is why finally, or a single centralized completion callback, is so valuable.
Common Pitfalls
- Calling
end()right after scheduling the query, which closes the connection before the callback work is finished. - Closing the connection after the first callback even though later nested async work still depends on the result flow.
- Opening raw connections for every request in a server application when a pool would be more appropriate.
- Releasing or ending on the success path only and leaking connections when errors occur.
- Mixing callback-style control flow with resource cleanup scattered across branches so the true final close point is hard to see.
Summary
- In callback-based database code, the connection must remain open until the final async step completes.
- Close or release the connection from the last callback path, not immediately after starting the query.
- For multi-request applications, prefer a connection pool over one-off raw connections.
- Promise-based code with
tryandfinallyusually makes cleanup easier to reason about. - Make sure error paths clean up resources just as reliably as success paths.
Related reading
- Cloud SQL connection for Kubernetes using proxy
- Cloud SQL Proxy and Insufficient Permission
- CockroachDB read transactions
- Code-first migration How to set default value for new property?
- Columnar storage Cassandra vs Redshift
- Combination of UUID and integer value as primary key in one database in MySQL
- Combine multiple Rocksdb databases
- command line authentication of mongo fails

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.