Skip to content

Commit a99aef8

Browse files
committed
Docs: modify guides section, add initialConnections with explanation
1 parent 6f17cc6 commit a99aef8

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

docs/guides/add-ebean-postgres-database-config.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ with Ebean's `DataSourceBuilder`. Follow every step in order. This is Step 2 of
2222
| `db_user` | Database username |
2323
| `db_pass` | Database password |
2424
| `db_master_min_connections` | Minimum pool size (default: 1) |
25+
| `db_master_initial_connections` | Initial pool size at startup — set high to pre-warm on pod start (see K8s note below) |
2526
| `db_master_max_connections` | Maximum pool size (default: 200) |
2627

2728
---
@@ -65,6 +66,7 @@ Database database() {
6566
.schema("myschema") // set to your target schema
6667
.applicationName("my-app") // visible in pg_stat_activity
6768
.minConnections(Config.getInt("db_master_min_connections", 1))
69+
.initialConnections(Config.getInt("db_master_initial_connections", 10))
6870
.maxConnections(Config.getInt("db_master_max_connections", 200));
6971

7072
return Database.builder()
@@ -82,6 +84,35 @@ Database database() {
8284
| `schema` | The Postgres schema Ebean should use (omit if using `public`) |
8385
| `applicationName` | Shown in `pg_stat_activity.application_name`; helps with DB-side diagnostics |
8486
| `name("db")` | Logical Ebean database name; relevant if multiple Database instances exist |
87+
| `minConnections` | Connections kept open at all times; pool will not shrink below this |
88+
| `initialConnections` | Connections opened at startup; see K8s warm-up note below |
89+
| `maxConnections` | Hard upper limit on concurrent connections |
90+
91+
### Connection pool sizing for Kubernetes (and similar orchestrated environments)
92+
93+
When a pod starts in Kubernetes it will receive live traffic as soon as it passes
94+
readiness checks — often before the connection pool has had a chance to grow to handle
95+
the load. This can cause latency spikes on the first wave of requests while the pool
96+
expands one connection at a time.
97+
98+
Use `initialConnections` to **pre-warm the pool at startup** so it is already sized
99+
for peak load when the pod goes live:
100+
101+
```
102+
minConnections: 2 ← floor; pool will shrink back here when idle
103+
initialConnections: 20 ← opened at pod start, before first request arrives
104+
maxConnections: 50 ← hard ceiling
105+
```
106+
107+
The lifecycle is:
108+
1. **Pod starts** — pool opens `initialConnections` connections immediately.
109+
2. **Pod receives traffic** — pool is already at capacity; no growth latency.
110+
3. **Traffic drops** — idle connections are closed; pool trims back toward `minConnections`.
111+
4. **Next traffic spike** — pool grows again up to `maxConnections` on demand.
112+
113+
Set `initialConnections` to a value high enough that the pool does not need to grow
114+
during the first minute of live traffic. A common starting point is 50–75% of
115+
`maxConnections`.
85116

86117
---
87118

@@ -98,6 +129,7 @@ Database database(Configuration config) {
98129
String user = config.get("db_user");
99130
String pass = config.get("db_pass");
100131
int min = config.getInt("db_master_min_connections", 1);
132+
int init = config.getInt("db_master_initial_connections", 10);
101133
int max = config.getInt("db_master_max_connections", 200);
102134

103135
var dataSource = DataSourceBuilder.create()
@@ -108,6 +140,7 @@ Database database(Configuration config) {
108140
.schema("myschema")
109141
.applicationName("my-app")
110142
.minConnections(min)
143+
.initialConnections(init)
111144
.maxConnections(max);
112145

113146
return Database.builder()
@@ -144,6 +177,7 @@ Database database(Configuration config) {
144177
var masterDataSource = buildDataSource(user, pass)
145178
.url(masterUrl)
146179
.minConnections(config.getInt("db_master_min_connections", 1))
180+
.initialConnections(config.getInt("db_master_initial_connections", 10))
147181
.maxConnections(config.getInt("db_master_max_connections", 50));
148182

149183
var readOnlyDataSource = buildDataSource(user, pass)
@@ -179,6 +213,7 @@ private static DataSourceBuilder buildDataSource(String user, String pass) {
179213
| Key | Description | Default |
180214
|-----|-------------|---------|
181215
| `db_url_readonly` | JDBC URL for the read replica ||
216+
| `db_master_initial_connections` | Initial master pool size at startup | 10 |
182217
| `db_readonly_min_connections` | Minimum pool size | 2 |
183218
| `db_readonly_initial_connections` | Initial pool size at startup | same as min |
184219
| `db_readonly_max_connections` | Maximum pool size | 20 |

0 commit comments

Comments
 (0)