The 30 second answer
Opening a database connection is slow, so I reuse connections from a pool like HikariCP, which is the Spring Boot default. The pool should be small and sized for the database, not for the number of threads, because too many active connections compete for the same CPU and disk. PgBouncer helps when many application instances together would open too many connections.
Opening a database connection is slow, and a pool reuses connections. HikariCP's pool-sizing wiki says a smaller pool is usually faster, and gives a starting formula: connections = (core_count * 2) + effective_spindle_count. PgBouncer pools on the database side. In transaction mode a server connection is shared between clients per transaction, so session features like prepared statements need care.