Postgres
Managed PostgreSQL with automated backups, connection pooling and, on Team, point-in-time recovery.
Guidal runs managed PostgreSQL. You get a database with credentials, automated backups and a private address reachable from services in the same project.
Create a database
guidal db create --name demo-db --type postgresqlProvisioning takes a minute or two. Watch for it to become ready:
guidal db listConnect a service to it
Linking is the recommended path — it injects the connection string into the service as an environment variable, so credentials are never copied by hand and stay correct if they change:
guidal db link demo-db --service apiTo detach:
guidal db unlink demo-db --service apiConnect from your own machine
Connecting from a laptop takes two things: the Guidal CLI (signed in with guidal login) and a PostgreSQL client, psql 13 or newer. Both commands below require org admin or owner — the same permission as seeing credentials.
1. Install psql
macOS (Homebrew's libpq is keg-only, so it is not on your PATH until you add it):
brew install libpq
export PATH="/opt/homebrew/opt/libpq/bin:$PATH"On an Intel Mac the path is /usr/local/opt/libpq/bin. Add the export line to your shell profile to keep it.
Debian or Ubuntu:
sudo apt install postgresql-clientFedora:
sudo dnf install postgresqlWindows:
winget install PostgreSQL.PostgreSQLThen add C:\Program Files\PostgreSQL\<version>\bin to your PATH. If psql lives somewhere else, pass its path with --psql /path/to/psql.
2. Open psql
guidal db connect demo-dbThis opens a local tunnel on a free port, fetches the credentials for you and starts psql connected through it. The password is never shown — not on screen, not on a command line, not on the clipboard. psql reads it from a private file that is deleted when psql exits. The database can be named by its name or its ID.
Run a single query and exit:
guidal db connect demo-db -- -c "select now()"Everything after -- goes to psql as given, with one exception: the host, port, user and database are set by guidal db connect, so psql's -h, -p, -U and -d (and their long forms) are refused, and so is a bare database or user name. Quote a -c query as one argument — an unquoted query splits into separate words, the first stray word is refused as a bare name, and the error tells you to quote the whole query.
If psql is missing, or older than 13, the command stops before touching the database, prints install steps for your operating system and exits with code 7. Once psql has started, guidal db connect exits with psql's own status — see exit codes.
The connection uses TLS (sslmode=require) with channel binding. It does not verify the server certificate by default; if you keep a ~/.postgresql/root.crt, libpq verifies the server against it, and the connection fails unless that CA signed the database's certificate.
3. GUI tools and other clients
For pgAdmin, DBeaver, pg_dump or anything else, start a tunnel and leave it running:
guidal db proxy demo-db --port 0--port 0 picks a free port. The tunnel prints the ready-made psql command and the settings to enter in a GUI tool:
| Field | Value |
|---|---|
| Host | 127.0.0.1 |
| Port | the port the tunnel printed |
| Maintenance database | the database name the tunnel printed |
| Username | the username the tunnel printed |
| SSL mode | require |
The password comes from:
guidal db credentials demo-db --revealPress Ctrl-C to stop the tunnel.
Connection limits
Through the tunnel, a connection that is idle for 30 minutes is closed, and every connection is closed after 4 hours at most. psql and most GUI tools reconnect on the next statement. The CLI prints why each connection closed — for example connection 1 closed after 31m (idle timeout (30 minutes)), or maximum session length (4 hours).
The tunnel authenticates as you. What you are permitted to do inside the database is governed by the database role you connect with — the tunnel moves bytes, it does not widen your privileges.
Seeing the credentials directly
guidal db credentials demo-db--reveal prints a live password
db credentials masks the password unless you pass --reveal. Avoid --reveal in shared terminals, screen shares and CI logs. Prefer db link for services and db connect for interactive use — neither puts the password on your screen. The old db connect --copy flag, which put the password on the clipboard, has been removed.
Backups
Every database is backed up automatically, on every plan. Retention depends on your plan:
| Plan | Backup retention |
|---|---|
| Starter | 7 days |
| Pro | 14 days |
| Team | 30 days |
List and take backups:
guidal db backups demo-db
guidal db backup demo-dbAn on-demand backup before a risky migration is cheap insurance.
Restore
A restore never touches the database you restore from. It creates a new database from a backup, and the original keeps running, unchanged, the whole time. There is no downtime, and a wrong backup costs nothing: delete the new database and try another.
guidal db backups demo-db
guidal db restore demo-db --backup <backup-name> --as demo-db-restoredThe command waits until the new database is running. Then point your service at it, and delete the old one once you are happy:
guidal db unlink demo-db --service api
guidal db link demo-db-restored --service api
guidal db update demo-db --no-deletion-protection
guidal db delete demo-dbA few things to know:
- The new database counts against your plan's database limit while both exist.
- It starts with deletion protection on, and it is not linked to anything until you link it.
- Inside PostgreSQL it keeps the original's database and user names, so your application's queries work unchanged.
- It inherits the original's size, storage and settings. Pass
--size,--instancesor--storageto change them.
Restoring is also how a database gets more storage: a volume cannot grow in place, so restore into a new database with a larger --storage (at least the current size, at most your plan's limit):
guidal db restore demo-db --backup <backup-name> --as demo-db-big --storage 10GiRestoring from a named backup works on every plan. Restoring to a specific moment instead — just before a bad migration or an accidental delete — needs point-in-time recovery, available on Team:
guidal db restore demo-db --target-time 2026-09-29T10:30:00Z --as demo-db-beforeThe time must include a timezone and fall between the first recoverable point (shown by guidal db backups demo-db) and now. A backup older than that has expired and cannot be restored.
In the console: open the database, go to Backups, and choose Restore on a backup.
Change settings
These can be changed after the database is created, from the console's Settings tab or with guidal db update:
| Setting | Flag | Notes |
|---|---|---|
| Size | --size | Restarts PostgreSQL |
| Instances (1–3) | --instances | More than 1 needs Team; restarts replicas |
| Connection pooling | --pooling / --no-pooling, --pool-size | |
| Backup retention | --backup-retention | Days, up to your plan's retention |
| Backup schedule | --backup-schedule | Five-field cron, at most hourly |
| Extensions | --add-extension | Add only |
| Deletion protection | --deletion-protection / --no-deletion-protection |
guidal db update demo-db --size medium
guidal db update demo-db --add-extension pg_trgmChanging size or instances restarts PostgreSQL
A single-instance database is unavailable for a short time while it restarts. Schedule the change for a quiet moment.
Extensions come from a fixed list of trusted extensions: btree_gin, btree_gist, citext, hstore, pg_trgm, pgcrypto, unaccent and uuid-ossp. Adding one creates it in the database for you. To remove one, run DROP EXTENSION yourself in psql (guidal db connect); the list shown for the database refreshes after the next settings change.
Storage cannot be changed in place. To get more space, restore into a new database with a larger --storage — see Restore.
High availability
Team databases can run with a standby that takes over if the primary fails. On Starter and Pro a database runs as a single instance; a failure means downtime while it restarts, with data recovered from backups.
Monitor
guidal db metrics demo-dbWatch connection count against your pool size, and storage growth against your plan's limit — running out of storage is the most common avoidable database incident.
Plan limits
| Plan | Max databases | Storage |
|---|---|---|
| Starter | 1 | 5 GB |
| Pro | 3 | 25 GB |
| Team | 10 | 100 GB |
Storage is shared across databases, buckets and other stored data. See Plans, billing and limits.
Delete
New databases have deletion protection on, so a delete is refused until you turn it off:
guidal db update demo-db --no-deletion-protection
guidal db delete demo-dbdb delete asks you to type the database's name to confirm. This destroys the database and its data. Take a backup first if there is any chance you want it back.
A project cannot be deleted while any of its databases has deletion protection on.