The db pool can contain 0 or more idle database connections. These were links that were made, used, and not closed, that were saved for future use. The number of these elements that we can support is MaxIdleConns .
When you request one of these idle connections, it becomes the open connection available to you. The number of them you can use is MaxOpenConns .
Now it makes no sense to make any more idle connections than the maximum allowed open connections, because if you can instantly capture all allowed open connections, the remaining inactive connections will always remain idle. It looks like a bridge with four lanes, but only ever allowing three vehicles to move along it at once.
Therefore, we would like to make sure that
MaxIdleConns <= MaxOpenConns
Functions are written to preserve this invariant, decreasing MaxIdleConns whenever it exceeds MaxOpenConns . Note that the documentation says that only MaxIdleConns ever reduced to match MaxOpenConns , the latter will never be true.
To answer the question of why the developer might want to configure them separately: consider the case of an application that is usually quiet, but sometimes you need to open a large number of connections. You can specify a large MaxOpenConns , but a very small MaxIdleConns , to ensure that your application can open as many connections as needed when necessary, but quickly frees up these resources, freeing up memory for both itself and the database. Saving an idle connection is not free, and this is usually done because you want to turn it into a useful connection soon.
So, the reason is that there are two numbers here, these are two parameters that may have good reasons for individual change. Of course, API semantics mean that if you don't care about setting both of these values, you can just set the one that interests you, which is probably MaxOpenConns