Use databases across environments
Every environment runs its own databases. A connection variable points at a database by name, within its own environment — so each environment is a self-contained copy of your stack, and the same wiring works in every one.
That name-keying is what makes environments portable: a staging environment with a Postgres named db and a production environment with a Postgres named db both satisfy the same DATABASE_URL declaration, each from its own database.
Clone an environment
Cloning an environment copies its services, wiring, and variables into a new environment — databases included.
The cloned databases start empty. Their size and wiring come along; their data does not — and neither do their credentials, so each clone gets the defaults: the standard username and database name, and a newly generated password. Connection variables re-resolve against the clone's own databases, so consuming services pick up the new credentials on their own.
Sensitive variable values are not copied either — the clone flow lists them so you can re-enter each one. Creation order is handled for you: databases come up before the services that reference them, so nothing starts with a dangling connection.
Promote between environments
Promoting an environment moves a release forward — staging to production, say — by making the target match the source, databases included. A database that exists in both environments keeps its data and its credentials; its size is updated to match the source's.
A database only in the source is created empty in the target, with fresh credentials like a clone's. A database missing from the source is deleted — its data destroyed — and the promote asks you to confirm that deletion first.
The promoted code connects through the same connection variable names, now resolving to the target's own databases.
Seed and migrate data
Run schema migrations from your app at boot. A migration step on startup travels with every deploy and every promote, so each environment's database is upgraded by exactly the code that needs it.
For interactive work, the database's Console tab is the only path — a shell inside the running container. Run Postgres on Koo and Run Redis on Koo cover it.
Your laptop and CI cannot reach a database — its host only resolves inside Koo. Anything that loads data must run inside the environment: your service at boot, or a shell in the Console tab.
What Koo keeps — and doesn't
A database's data lives on its own included disk and survives restarts, redeploys of your other services, and promotes.
Koo keeps no backups or snapshots of databases, and there is no restore. Snapshots exist for web-service volumes — they do not apply to databases.
Deleting a database destroys its data permanently. Recreating one with the same name reconnects the existing wiring — connection variables resolve again — but the data does not return. Export first, for example with pg_dump run from one of your own services, which can reach the database and send the dump onward.
The free allowance across environments
The free allowance belongs to your account, not to each environment: one free-unit Postgres (0.5 vCPU / 1 GiB) and one free-unit Redis across everything your primary account runs. See the free tier.
On a paid plan, the allowance covers only one database of each type — your largest running one — so an additional environment's database bills at its full price. Billing covers how compute is rated.
On the Free plan the question doesn't arise: the plan includes one environment, with one database of each type.