Skip to Content
CLI ReferenceDatabases

Databases

Create and manage PostgreSQL, MongoDB and Valkey databases.

ghayma db mode, ghayma db logs and --type valkey need CLI v0.13.0 or later.

ghayma db create

Create a new managed database in the current project (reads project_id from .ghayma.json).

# PostgreSQL (default) ghayma db create my-postgres # MongoDB (needs tier m or larger; always a single-node replica set) ghayma db create my-mongo --type mongodb # Choose a compute tier, disk size, and backup schedule up front ghayma db create my-postgres --tier s --disk-gb 20 --backup daily # Connect it to the 'main' site as it is created ghayma db create my-postgres --site main # Valkey (Redis-compatible) ghayma db create cache --type valkey --mode store

MongoDB starts at the m tier. The xs and s tiers are too small to run MongoDB reliably (their 512 MiB ceiling can’t boot a replica set, so multi-document transactions aren’t available there), so new MongoDB databases need tier m or larger. PostgreSQL and Valkey run on every tier. MongoDB databases created on a smaller tier before September 2026 were moved to m. MongoDB always runs as a single-node replica set.

Valkey runs on every tier, xs included. It has no public access yet and its disk cannot shrink. See the Valkey guide.

Options:

FlagDescriptionDefault
--type, -tDatabase type: postgres, mongodb, valkeypostgres
--modeValkey only: cache (evicts the least-recently-used keys when memory is full; snapshots only) or store (never evicts; a snapshot plus an append-only file synced every second). See Cache or store.cache
--tierCompute tier, priced in points (e.g. xs, s, m, l). Interactive picker when omitted; server default if the catalog is unavailable.picker / server default
--disk-gbPersistent disk in GB, priced in points. The volume is created at exactly this size. Server default (from the tier) when omitted.server default
--backupBackup schedule: weekly, daily, sixhourly. Interactive picker when omitted; weekly if the catalog is unavailable.picker / weekly
--siteConnect the new database to this site (slug); repeat for several. See Connecting it to a site.asked on a terminal
--no-connectConnect it to no site, without asking.—

MongoDB always runs as a single-node replica set (rs0), so multi-document transactions work. In CLI v0.14.0 the --replica-set flag is hidden: it is still accepted, and only --replica-set=false on a MongoDB is refused, before anything is sent:

❌ MongoDB always runs as a single-node replica set: a standalone instance cannot give each app its own database user. Leave --replica-set out.

Connecting it to a site

A new database is connected only to the sites you choose — even in a project with a single site. Name them with --site, or pass --no-connect for none; giving both is refused before anything is created, and so is a --site the project doesn’t have (the error lists its sites).

ghayma db create my-postgres --site main --site admin

With neither flag, a terminal asks: one site gets Connect database 'my-postgres' to site 'main'? (default Yes), several sites get one question each (default No), and a project with no site yet is told that ghayma deploy will offer to connect it. Without a terminal nothing is connected, and the CLI prints the command that does it:

ℹ️ Not connected. Connect it with: ghayma connect database my-postgres --site main

After the create, each chosen site gets a line: 🔗 Connected to 'main', or for a new PostgreSQL or Valkey database, which accepts connections a moment after it is created, ⏳ Connecting to 'main' once it is ready to accept connections. A site that could not be connected is named with the reason and a Retry with: command. See How a service gets connected.

Sizing and points

A database reserves points based on its tier, disk size, and backup schedule (see Pricing by Service). Pass --tier, --disk-gb, and --backup to set these non-interactively. If you pass none of them, db create opens interactive pickers, each choice showing its points cost:

Select a database tier ▸ xs — 0.25 vCPU / 256 MB · 2 pts s — 0.5 vCPU / 512 MB · 4 pts m — 1 vCPU / 1024 MB · 8 pts Disk in GB — steps of 1 (blank for server default): 20 Select a backup schedule ▸ weekly — every 168h, keep 4 · +0 pts daily — every 24h, keep 7 · +2 pts sixhourly — every 6h, keep 28 · +6 pts

Before the database is created, the CLI prints the points it will reserve:

This database will reserve 24 pts · 11 remaining after

That line is for xs with 20 GB and daily backups on an otherwise empty Pro project (35 points): 2 (tier) + 20 (disk, 1 point per GB) + 2 (daily backups, two started 10 GB blocks) = 24, and 35 − 24 = 11. The same database on tier s reserves 26.

The · N remaining after tail appears only when your project has a points budget (it’s omitted for pay-as-you-go projects).

The tiers, disk steps, and points above come from the live catalog — the figures shown are only examples.

Interactive pickers: Ctrl-C cancels without creating anything — the CLI prints ❌ Cancelled. and exits.

Output:

✅ Created postgres database 'my-postgres' (linked to project) ID: <uuid> Host: pg-mypostgres-a1b2c3d4-0.databases.svc.cluster.local Port: 5432 Status: provisioning ⏳ Connecting to 'main' once it is ready to accept connections

For MongoDB, the output includes an additional Mode: line, replica set (rs0) — transactions supported. The last line is the connection to the site you chose.

For Valkey, the Mode: line says what the mode does, and a last line names the variables connected apps receive:

✅ Created valkey database 'cache' (linked to project) ID: <uuid> Host: vk-cache-a1b2c3d4.pdb-<project-uuid>.svc.cluster.local Port: 6379 Status: provisioning Mode: store — never evicts; writes fail when memory is full. Snapshot plus append-only file every second. Connected apps receive REDIS_URL and VALKEY_URL at runtime (not during builds). ⏳ Connecting to 'main' once it is ready to accept connections

Without --mode, the line reads cache — evicts the least-recently-used keys when memory is full. Snapshots only. These are refused before anything is sent:

$ ghayma db create r --type redis ❌ Redis is not offered. Create a Valkey database instead (--type valkey): it speaks the Redis protocol, so every Redis client works with it. $ ghayma db create p --mode store ❌ --mode applies to Valkey only $ ghayma db create v --type valkey --mode persist ❌ --mode must be cache or store, not "persist"

A database belongs to one project for its whole life. It is created inside the project in your .ghayma.json and cannot be moved to another one later. Its connection variables — DATABASE_URL for PostgreSQL, MONGODB_URI (alias MONGODB_URL) for MongoDB, REDIS_URL and VALKEY_URL for Valkey — are derived for every site connected to it (see ghayma db sites), so there is no attach step to run afterwards. Connected apps pick them up straight away, and every deploy derives them again — they are never stored env vars. A Valkey’s variables reach the running app only, never a build. See Automatically injected variables.

ghayma db resize

Change a database’s compute tier, disk size, or backup schedule after it’s created. Pass any combination of --tier, --disk-gb, and --backup — only the options you set change.

# Move to a bigger compute tier ghayma db resize my-postgres --tier m # Grow the disk (online — the database stays up) ghayma db resize my-postgres --disk-gb 40 # Shrink the disk (the database stops for about a minute) ghayma db resize my-postgres --disk-gb 10 # Change the backup schedule ghayma db resize my-postgres --backup sixhourly

Options:

FlagDescription
--tierNew compute tier (e.g. xs, s, m, l)
--disk-gbNew disk size in GB, at least 1. Larger grows the disk; smaller shrinks it if the data fits (a Valkey disk cannot shrink yet)
--backupNew backup schedule: weekly, daily, sixhourly
--no-waitReturn as soon as a disk change has started instead of waiting for it

The platform makes a disk change in the background. By default the command waits and shows its progress until the disk has its new size; with --no-wait it returns once the change has started, and ghayma db info shows Status: resizing until it is done. A grow happens online: the database stays up, and the new size applies in about a minute.

Notes:

  • While a database is resizing, nothing else changes it until the resize finishes: db stop, db start, db delete and any other resize are refused with resize_in_progress. Backup restores wait as well.
  • The disk changes only while the database runs. On a stopped database the resize is refused with database_not_running: run ghayma db start first.
  • A size the platform has no storage for right now is refused with storage_capacity: try a smaller size, or later.
  • Passing none of the flags does nothing: ❌ Nothing to change. Pass at least one of --tier, --disk-gb, --backup.
  • A new --tier on a Valkey restarts it with the new memory limit: its maxmemory is 70 % of the tier’s memory. See Memory and disk.
  • A smaller --disk-gb on a Valkey is refused before any change is sent: ❌ A Valkey disk can grow, but it cannot shrink yet. cache keeps its 2 GB disk. If the platform refuses it instead, the line stops after cannot shrink yet.
  • A resize reserves or refunds only the difference in points against your budget — see Points & Plans. The new disk size is billed once the change is done. Check the current reservation any time with ghayma points.

Shrinking, the progress wait and --no-wait need the CLI release that carries them. An older CLI refuses a smaller --disk-gb itself (❌ disk cannot shrink from 40 GB to 20 GB), and after a grow it returns at once and prints the old disk size. If ghayma db resize --help does not list --no-wait, update the CLI, or change the disk from the Dashboard.

Shrinking a disk

A PostgreSQL or MongoDB disk can shrink if what the database holds on disk fits in 75 % of the new size. That counts the data plus the engine’s own files, such as PostgreSQL’s WAL or MongoDB’s journal. The Dashboard shows the current on-disk usage and the smallest size you can shrink to now; in the API they are disk_used_bytes and min_disk_gb. Asking for less changes nothing: the resize is refused with disk_too_small, which names the smallest size that fits — see Disk too small for the data. The minimum disk is 1 GB. A Valkey disk cannot shrink yet.

A shrink stops the database for about a minute on a small database, longer on a large one, while its files are copied to the smaller disk. Apps cannot connect during that time, so pick a quiet moment. Everything else stays exactly as it was: credentials, users, connection strings and data. The smaller disk costs less from the moment the shrink is done.

If a shrink fails before the old disk is released, it is undone automatically and the database comes back on its original disk. If it stops later, the data is kept safe and support finishes the move.

ghayma db mode

Switch a Valkey database between its two modes: cache evicts the least-recently-used keys when memory is full and keeps snapshots only; store never evicts (writes fail when memory is full) and keeps a snapshot plus an append-only file synced every second. See Cache or store.

ghayma db mode <name> cache|store

The cache database created above in store mode moves to cache mode:

ghayma db mode cache cache

Output:

⏳ Switching cache to cache mode. It restarts: a few seconds of downtime... ✅ cache is in cache mode: evicts the least-recently-used keys when memory is full. Snapshots only.

The database restarts into the new mode: a few seconds of downtime. Moving to cache first takes a fresh snapshot. Moving to store first writes the append-only file, which takes longer on a large dataset, and ends with ✅ cache is in store mode: never evicts; writes fail when memory is full. Snapshot plus append-only file every second.

A database already in that mode is left alone:

ℹ️ cache is already in cache mode.

Only a running Valkey can switch. The CLI checks the status first:

❌ cache is stopped, so its mode cannot change. Start it first: ghayma db start cache ❌ cache is provisioning, so its mode cannot change now. Try again once ghayma db info cache shows running.

If the database was down for a moment when the switch reached it and runs again now, run the same command again:

❌ cache was not running a moment ago. Try again: ghayma db mode cache cache

Other refusals:

❌ The mode is cache or store, not "persist". ❌ my-postgres is a postgres database: only Valkey has a mode.

Anything else the platform refuses prints ❌ Mode switch failed: followed by its reason. If the append-only file or the snapshot cannot be written, the database stays in its old mode.

ghayma db list

List all your databases.

ghayma db list

Output:

🗄️ Your databases (3): my-postgres postgres running my-mongo mongodb stopped cache valkey running

Columns are name, type and status. A database in error shows why after its status — for a Valkey that never became ready, what the platform saw:

jobs valkey error · CrashLoopBackOff: back-off restarting failed container exit 1

ghayma db info

Show details about a database.

ghayma db info my-postgres

Output:

🗄️ Database: my-postgres Type: postgres 16 Status: running Host: pg-mypostgres-a1b2c3d4-0.databases.svc.cluster.local Port: 5432 Database: db_mypostgres Storage: 1024 MB CPU: 500m Memory: 512Mi Project: <project-id>

There is no Username: line: a database’s own login is never shown, and each connected app has a credential of its own. For a Valkey, Database: gives way to its mode and its users:

🗄️ Database: cache Type: valkey 9.1 Status: running Host: vk-cache-a1b2c3d4.pdb-<project-uuid>.svc.cluster.local Port: 6379 Mode: store — never evicts; writes fail when memory is full. Snapshot plus append-only file every second. Users: each connected app has its own user (REDIS_URL / VALKEY_URL) Storage: 2048 MB Disk used: 1.2 GB CPU: 500m Memory: 512Mi Project: <project-id>

A Valkey’s Disk used: line never names a smallest disk, because its disk cannot shrink yet. A Valkey in error shows the reason on its status line: Status: error · <reason>.

ghayma db logs

Show the last lines of a database’s engine log. Every engine has one: PostgreSQL, MongoDB and Valkey.

ghayma db logs <name> [-n <lines>] [-f]
# The last 200 lines ghayma db logs cache # The last 500, then keep printing new lines ghayma db logs cache -n 500 -f

Options:

FlagDescriptionDefault
-n, --linesNumber of lines to show, 1-1000200
-f, --followKeep printing new lines until Ctrl-C (up to 10 minutes)—

Output: the log as the platform streams it, each line prefixed with its timestamp:

2026-10-08T09:12:22.108356960Z 1:M 08 Oct 2026 09:12:22.108 * Valkey is starting 2026-10-08T09:12:22.139Z 1:M 08 Oct 2026 09:12:22.139 * Ready to accept connections tcp

A follow ends after 10 minutes, or when the database restarts. Ctrl-C ends it quietly. When the platform ends it, the CLI says so on stderr, so ghayma db logs cache -f > cache.log keeps only log lines. The blank lines a follow uses to keep the connection open are never printed.

ℹ️ The stream ended (the platform ends a follow after 10 minutes, or when the database restarts). Run the command again to keep following.

A database with no running engine has no log to show:

❌ cache is stopped, so it has no running log. Start it with: ghayma db start cache ❌ cache did not start, so it has no log yet. See why: ghayma db info cache ❌ cache is not running yet, so it has no log. Check: ghayma db info cache

The first is a stopped database, the second one in error, the third one still starting. Reading the log needs the project write role. Any other refusal prints ❌ Could not read the log: followed by the platform’s reason.

ghayma db credentials

Show where a database answers and which apps receive its credentials — without any secret.

ghayma db credentials my-postgres

Output:

🔌 Connection details for 'my-postgres' (postgres) Host: pg-mypostgres-a1b2c3d4-0.databases.svc.cluster.local Port: 5432 Database: db_mypostgres Connected sites and the variables they receive: main connect DATABASE_URL, DATABASE_URL_MY_POSTGRES admin read-only DATABASE_URL, DATABASE_URL_MY_POSTGRES No password is shown: each site has its own credential, delivered in these variables. From your laptop: ghayma connect --local From outside Ghayma: ghayma access add database my-postgres --name <principal>

Host is the in-cluster hostname, the one a deployed app uses. Each connected site comes with its level and the exact variable names it receives; the values hold that site’s own credential, and ghayma env pull writes them for one site. A database no site is connected to says so in place of the list:

Not connected to any site. Connect one with: ghayma connect database my-postgres --site <slug>

A database that belongs to no project prints ❌ Database 'my-postgres' belongs to no project.

A database’s own login is never shown, to anyone. Every app connected to it holds a credential of its own (c_ followed by eight characters) in its DATABASE_URL or MONGODB_URI — see Each app gets its own database credential. From your laptop, ghayma connect --local tunnels the site’s databases and writes its own credentials into .env.local. For a tool or person outside Ghayma, add a named principal: its own credential, its own level, its own source allowlist, rotated or revoked on its own.

This output needs CLI v0.14.0 or later. An older CLI asks the platform for the database’s own login, which is refused now: it prints the platform’s sentence, which names the same ways in (on a Valkey, its old note).

A Valkey prints the same layout without a Database: row and without the From outside Ghayma line, since a Valkey has no external principals yet:

🔌 Connection details for 'cache' (valkey) Host: vk-cache-a1b2c3d4.pdb-<project-uuid>.svc.cluster.local Port: 6379 Connected sites and the variables they receive: main connect REDIS_URL, VALKEY_URL, REDIS_URL_CACHE, VALKEY_URL_CACHE No password is shown: each site has its own credential, delivered in these variables. From your laptop: ghayma connect --local

Rotating: a database’s own login is never handed out, and only an operator rotates it. To give one app a new credential, run ghayma connections rotate database <name> --site <slug>.

ghayma db sites

View or choose which of your project’s apps may use a database. What this command lists and edits is a connection: it opens the database’s network policy to that app — its running pods and its builds — and hands it the connection variables. --add connects at the default level, connect — pick read-only instead with ghayma connect. Every database enforces its own policy, so only a connected app can open a connection.

A database is connected only to the sites you choose — at create, when ghayma deploy offers it, or with --add below — and until then it is deny-all. A site marked ⏳ is waiting for a new PostgreSQL or Valkey database to accept connections, and connects once it does. --add and --remove of other sites keep it waiting; --remove naming it cancels it. A Valkey takes no new site until it runs:

❌ cache is stopped. Start it, then run this again: ghayma db start cache ❌ cache is not running yet, so no app can connect to it. Wait until ghayma db info cache shows running, then run this again.

ghayma connect database <name> --site <slug> and ghayma connections are the newer form of the same thing, and the only one that also covers buckets and auth apps.

# Show the current access table ghayma db sites my-postgres # Also let the 'admin' site reach it (keeps existing grants) ghayma db sites my-postgres --add admin # Grant several sites at once ghayma db sites my-postgres --add admin,api # Revoke a site ghayma db sites my-postgres --remove admin # Replace the whole set with exactly these sites ghayma db sites my-postgres --set main,admin

Output:

🗄️ Site access for 'my-postgres': SITE NAME ACCESS main main ⏳ admin admin - ✓ = allowed ⏳ = connecting once the database accepts connections - = blocked

The three flags are mutually exclusive. Adding a site that already has access (or removing one that doesn’t) is reported as a no-op, not an error. Revoking all sites (--remove every granted slug) is allowed and makes the database unreachable from apps entirely — platform backups keep working.

Changes take effect within ~2 minutes (the network policy reconverges in the background) — no redeploy needed.

Connecting an app is only half the story: it must also use the database’s internal hostname (…databases.svc.cluster.local, or vk-<name>-<id8>.pdb-<project-uuid>.svc.cluster.local for a Valkey), not a public *.db.ghayma.tech one — external hostnames are unreachable from deployed apps whatever the connections say. See the Internal Networking guide.

ghayma db stop / db start

Stop or start a database to save resources. Data is preserved while stopped.

ghayma db stop my-mongo ghayma db start my-mongo

ghayma db delete

Permanently delete a database and all its data. Requires typing the database name to confirm:

⚠️ This will permanently delete 'my-postgres' and all its data. Type the database name to confirm:
ghayma db delete my-postgres

This permanently deletes the database and all data. Back up first if you need to preserve anything.