Read-Write Pools
Last updated
This page explains when each of the two MySQLPool pools is used and what happens when one side is not configured.
Two Pools
init() creates up to two mysql2/promise pools (src/MySQLPool.ts:74-91):
| Pool | Created when | Typical target |
|---|---|---|
Read pool readPool |
The read config has a non-empty database |
A read replica |
Write pool writePool |
The write config has a non-empty database |
The primary |
Both pools use waitForConnections: true: when every connection is busy, requests queue instead of failing immediately.
Which Pool Each Method Uses
| Method | Pool |
|---|---|
get() |
Second argument to table(), default "read" |
insert(), update(), upsert() |
Always the write pool |
read() |
Always the read pool |
write() |
Always the write pool |
query(sql, params, target) |
target; when omitted, the target from the most recent table() call |
import MySQLPool from "@pardnchiu/mysql-pool";
// Read from the replica
const list = await MySQLPool.table("orders").where("user_id", 1).get();
// Read from the primary right after a write to avoid replication lag
const fresh = await MySQLPool.table("orders", "write").where("user_id", 1).get();
table(name, "write") only affects get() and later query() calls without a target; write methods use the write pool anyway.
Only One Side Configured
| Setup | Result |
|---|---|
| Read side only | With a config object, the write side falls back to config.read; with environment variables, no write pool is created and write methods throw write connection is not available. |
| Write side only | No read pool; table("x").get() throws read connection is not available., so use table("x", "write").get() |
| Neither side | No pools are created and init() still resolves |
read() and write() check the pool before calling query() and throw Read pool connection is not available. / Write pool connection is not available. (src/MySQLPool.ts:395-404).
Single Database
When you do not need read-write splitting, use the config key so both pools share one config:
await MySQLPool.init({
config: { host: "127.0.0.1", user: "app", password: "secret", database: "app" },
});
This still creates two independent pools, each with its own connectionLimit, so the total connection cap against that database is the sum of both.
Related Pages
- Configuration: source priority and defaults
- Raw SQL: run hand-written SQL on a fixed pool