# Pools

## Introduction

A pool is a URL you point callers at, with a hard concurrency limit behind it. Each pool
has a hostname (`https://‹subdomain›.nthpool.cloud`), allowed origins, caller
authentication, and concurrency settings.

A pool's **backend** decides what sits behind that limit. The default is an
HTTPS origin, which the pool proxies to. A [database pool](/docs/pools/database)
fronts a PostgreSQL database instead, and answers SQL over HTTP on its own
hostname. Everything else — keys, concurrency, credentials, logs — is the same
either way. The backend is chosen when the pool is created and cannot be changed
afterwards.

Create pools under **Pools** in the dashboard. Each pool has tabs that match
this documentation:

| Tab | What it covers |
|-----|----------------|
| Overview | Live status and how the pool is reached |
| [Concurrency](/docs/pools/concurrency) | Limit, queue, RPM, retries, response cache |
| [Access](/docs/pools/access) | Pool keys, HMAC, JWT, Cloudflare Access, IP policies |
| [Logs](/docs/pools/logs) | Access logs and tags |
| [Settings](/docs/pools/settings) | Origins, custody, name |
| [Database](/docs/pools/database) | Postgres backend: connection, read role, query limits |

## Hostnames

| Host | Role |
|------|------|
| `‹pool›.nthpool.cloud` | Proxy traffic for that pool |
| [Custom domain](/docs/domains) (plan-gated) | Same pool, your DNS name |
| `api.nthpool.cloud` | [Concurrency locks](/docs/api/locks) and [async job poll](/docs/pools/async) |

Reserved labels such as `api`, `edge`, `www`, `to`, and `fallback` cannot be
pool subdomains.

## Calling the pool

Proxy traffic goes to your pool hostname. The path and query string are
forwarded to the selected origin after admission. All inbound `X-Nthpool-*`
headers are stripped before the upstream request.

```bash
curl -sS "https://your-pool.nthpool.cloud/v1/records" \
  -H "X-Nthpool-Key: $POOL_KEY"
```

## Request headers

| Header | Purpose |
|--------|---------|
| `X-Nthpool-Key` | Pool key (required when the pool requires a key) |
| `Authorization` | Managed: may carry `Bearer` / `Nthbouncer` pool key. Pass-through: upstream credential |
| `X-Nthpool-Origin` | Exact origin when the pool has multiple origins |
| `X-Nthpool-Cache-TTL` | Opt-in response cache TTL in seconds (max 300); GET/HEAD only |
| `X-Nthpool-Tags` | Access-log tags (max 64 characters) |
| `X-Nthpool-No-Queue` | Fail fast instead of queuing when set (not `0` / `false`) |
| `X-Nthpool-Queue-Timeout-Ms` | Per-request queue wait budget in milliseconds |

HMAC, JWT, and Cloudflare Access headers are covered in
[Access](/docs/pools/access).

## Response headers

Successful (and many rejected) responses may include:

| Header | Meaning |
|--------|---------|
| `x-nthpool-remaining-slots` | Free concurrency slots after this admission |
| `x-nthpool-queue-depth` | Requests waiting in the pool queue |
| `x-nthpool-queued-ms` | Time spent waiting for a concurrency slot (`0` if admitted immediately). Does not include network round-trip. |
| `x-nthpool-total-ms` | pool + queue wait + upstream |
| `x-nthpool-effective-limit` | Current concurrency limit (fixed or learned) |
| `Retry-After` | Seconds to wait on pool `429` / `504` when applicable |

## Status codes from the pool

These are returned by nthbouncer **before or instead of** the upstream response:

| Status | Typical cause |
|--------|----------------|
| `400` | Invalid or missing origin selection |
| `401` | Missing/invalid key, JWT, HMAC, or nonce replay |
| `403` | IP allowlist miss, or custom-hostname lock |
| `413` | Payload too large |
| `429` | Queue full, fail-fast (`X-Nthpool-No-Queue`), or rate gate overloaded |
| `499` | Client cancelled while waiting or in flight |
| `501` | Pool is not configured yet |
| `502` | Upstream error while proxying |
| `503` | Pool suspended |
| `504` | Queue wait timeout or request/lease timeout |

Upstream status codes are passed through when the request was admitted and
fetched successfully (or failed at the origin).

## Next steps

- [Quickstart](/docs/quickstart)
- [Access](/docs/pools/access) (keys, inbound HMAC, origin verification)
- [Concurrency](/docs/pools/concurrency)
- [Concurrency locks API](/docs/api/locks) (same concurrency limit, no proxying)
- [Credentials](/docs/credentials) (managed upstream secrets)
- [Domains](/docs/domains)
- [Determine a request came from the proxy](/docs/knowledge-base/origin-verification)
- [Admission errors](/docs/knowledge-base/admission-errors)
