# Neon pooled vs direct: the master rule

## The trap
Neon gives you two connection strings per branch and the Console defaults to pooled. Agents copy whichever they see first into every slot: app, migrations, scripts, BI tools. Half of Neon's connection failure modes are just this choice made wrong.

## The rule
- **Pooled** (hostname contains `-pooler`): application request traffic, serverless functions, anything with high concurrency and short transactions. PgBouncer multiplexes up to 10,000 client connections.
- **Direct** (no `-pooler`): migrations, schema changes, seeds, admin scripts, `LISTEN`/`NOTIFY`, `SET` session vars, prepared statements, logical replication subscribers, `pg_dump`.

Neon's pooling docs list exactly what transaction-mode pooling does not support: SET/RESET, LISTEN/NOTIFY, WITH HOLD cursors, PREPARE/DEALLOCATE, qualifying temp tables, LOAD, session-level advisory locks.

## How to tell which one you have
Look at the hostname: `ep-xyz-pooler.us-east-2.aws.neon.tech` is pooled; without `-pooler` it is direct. If a query works from `psql` (direct) and fails from your app, compare the two strings before debugging anything else.

## Checklist
- App runtime env vars: pooled. CI migrate jobs: direct.
- Framework adapters (Prisma adapter, Drizzle, Kysely): pooled for the client, direct for the migration runner.
- Logical replication and `pg_dump`/`pg_restore`: always direct.
- When in doubt, `SELECT` from a fresh `psql` on each string and compare behavior.