The data tier is a separate pool from compute workers (app data must survive restarts + gets backups), and is itself split into two host pools — so a noisy Free tenant never shares metal with a paying customer, and each side scales on its own.
Tenant DB hosts · shared Free
node class: data-tenant scale: shard new tenants| Host | Logical DBs (Free) | CPU | RAM | Disk | PgBouncer pool | Status |
|---|---|---|---|---|---|---|
| tenant-db-1 | 96 | 188 / 50038% |
active | |||
| tenant-db-2 | 55 | 90 / 50018% |
active |
Each host runs one shared Postgres; every Free app = a logical database + role on it, injected as DATABASE_URL. Capacity is bounded by connections + storage + RAM (not container count). Free grows → add tenant-db-3 and route new tenants there (shard by host), or scale a host vertically.
Dedicated DB hosts · Paid & Custom
node class: data-dedicated 61 / 90 slots| Host | Containers | CPU | RAM | Disk | Container slots | Status | |
|---|---|---|---|---|---|---|---|
| db-1 | 24 | 24 / 3080% |
active | ||||
| db-2 | 19 | 19 / 3063% |
active | ||||
| db-3 | 18 | 18 / 3060% |
active |
Each Paid/Custom app gets its own isolated Postgres container (standard versioned image, own resources + backups). They bin-pack onto hosts by slot — a host fills → add db-4. ~50–150 MB idle each, so it's a paid-tier feature.
↓
PgBouncer (pooling)
↓
Free → shared Postgres on tenant-db-1
Paid → dedicated container on db-2
safety: per-role CONNECTION LIMIT + statement_timeout
→ one app can't exhaust the pool (old FD incident)
Free → Paid: provision a container in the db-N pool, copy data (pg_dump from tenant-db-X → restore), then a brief read-only cutover repoints DATABASE_URL & redeploys. Old logical DB dropped after backup.
Paid → Free: reverse — move back into a tenant-db with room (gated: must fit the Free quota), drop the container, free the slot.
Dedicated databases · sample
showing 4 of 61| Database | App / owner | Host | Tier | Size | Connections | Status |
|---|---|---|---|---|---|---|
| my-app_db | JD my-app · John Doe |
db-1 | Paid | 0.4 GB | 3 / 2015% |
healthy |
| crm-lite_db | GX crm-lite · Globex |
db-2 | Custom | 6.2 GB | 22 / 5044% |
healthy |
| shop-api_db | AC shop-api · Acme Inc |
db-1 | Custom | 11.8 GB | 41 / 10041% |
busy |
| portal_db | MK portal · M. Kowalski |
db-3 | Paid | 0.9 GB | 5 / 2025% |
healthy |