Replacing a shared pgx.Conn with pgxpool

For a moment, using one global *pgx.Conn felt fine…

I had moved the database connection into db/connection.go and shared it across the app, but that approach turns out to be dangerous for a web server. The official pgx docs are pretty explicit here: "It is not safe for concurrent usage." That line refers to Conn, which only represents a single PostgreSQL connection, so sharing it across many goroutines is just the wrong tool for this kind of app.

pgx.Conn is not safe for concurrent usage

To make the problem easier to see, I also did a separate fail-first experiment outside of this commit. I created an endpoint that intentionally held a query with pg_sleep(...), then I hit it with parallel requests. The result was not something I could trust… some requests could timeout, some could fail, and the behavior felt inconsistent depending on timing.

That is why I replaced the shared *pgx.Conn with pgxpool.Pool. Instead of relying on one connection for everything, I now use a proper connection pool that is much more suitable for concurrent server workloads.

I also updated the deployment queries to use the pool, added some small pool configuration, and included a Ping() check during initialization. From the outside the app still looks almost the same, but the database layer now matches how the server actually behaves.

The main insight from this one is pretty simple… something can look okay in a small local test and still be the wrong abstraction for a web server. A single connection may work for early experiments, but once concurrency enters the picture, using a real pool makes much more sense.

© 2026 Wahyu Syahputra. All rights reserved.