# Read-Write Pools

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 |

```typescript
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:

```typescript
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](/configuration): source priority and defaults
- [Raw SQL](/raw-sql): run hand-written SQL on a fixed pool
