Every database offers a limited number of connections because each of them eats resources. If you are using your database in a commercial environment, you configure your database with a maximum number of connections. If you don't do that, the DB will configure some default maximum, it won't offer an unlimited number. So each client application should be written so that it handles a refusal to provide a connection gracefully, and it should close every connection as soon as it has finished with it, otherwise you can run out of connections without good reason. Good practice is to write your application to always close connections as soon as it's finished with them. In the case of Go, the defer mechanism can be used to make this more reliable. However, the app can still hold onto connections, maybe due to programming mistakes. A connection pool enforces a maximum number of connections that a single app can hold, so it stops your app from asking for more than its share. It also watches for idle connections and closes them for you. It's good practice to use a connection pool to iron out the problems that your app fails to handle itself.
Hope this helps.
Simon