Databases
The db topic covers working with a Flui database building
block from your own machine: with psql or pgAdmin for
Postgres, mariadb or DBeaver for MariaDB, redis-cli for
Valkey/Redis, or your application’s ORM. A Flui database is an
application running in the cluster, so it is identified the
same way as any other.
Flui databases are not exposed outside the cluster network, so there is no public endpoint to point a client at. The commands on this page work around that, and fall into three jobs:
- Connect.
flui db credentialsprints the in-cluster address and credentials, which another app running on Flui uses.flui db tunnelopens a temporary local tunnel so a client on your machine can connect. - Copy the data out, and back.
flui db dumpstreams a dump to a file or to a backup destination;flui db restoreruns one back into the live database. - Check it is still healthy.
flui db diskshows how full the storage is,flui db backup-statusshows how far back you can recover, andflui db pitr-restorerebuilds a Postgres database as of a moment in time. - See who is connected to a managed PostgreSQL.
flui db poolershows its connection pooler and the two addresses applications use;flui db sessionslists the sessions and stops one.
If you would rather not install a local client, the dashboard has an in-browser console for the same databases; see The database console. For the steps rather than the flags, read Open a database from your machine.
Two shapes of command
The db commands are not all addressed the same way, and
knowing which is which saves you a confusing error.
credentials and tunnel resolve the database by name, slug or
id, and take -c, --cluster <name|id> to say where to look
(auto-detected when the active profile has only one cluster).
Both read the password straight from the cluster over SSH, never
from the API.
dump, restore, disk, backup-status and pitr-restore
go straight to the API with the application’s id, which
flui app list prints. They have no -c, --cluster flag,
because the id already says which cluster the database is on
(pitr-restore has a --cluster of its own, for where the
copy goes).
pooler and sessions sit in between. They take the database’s
name or id, find it, and then ask the API. Neither reads a
password. pooler looks a name up on every cluster unless you
pass -c, --cluster. sessions looks it up on one cluster: the
one you pass with -c, --cluster, or the only one your profile
has.
Every one of them checks access first. Owning the database is not enough by itself: you need a grant that reaches it, and an agent key is held to its own limits before the database is even looked up. See Who is allowed to open one.
flui db credentials <app>
Shows how to connect to a Flui database: the in-cluster service
address and its credentials, plus a ready-to-copy
DATABASE_URL. This is the connection information for another
app running on Flui in the same cluster. The host is the
in-cluster address, not a public one.
The password is read from the cluster over SSH and is hidden by
default. Pass --show to print it in plaintext.
flui db credentials postgresql-051f58flui db credentials postgresql-051f58 --showflui db credentials postgresql-051f58 --show --hide-after 30| Flag | Default | Effect |
|---|---|---|
-c, --cluster <name|id> | auto-detect | Cluster to resolve the database in. |
--show | off | Print the password in plaintext (hidden otherwise). |
--hide-after <seconds> | 0 | Opt-in optical wipe: hold the terminal for N seconds with a countdown, then erase the password from the screen. Only takes effect together with --show on a TTY; 0 returns immediately. |
To connect a native client from your own machine, use
flui db tunnel instead. The in-cluster host shown here is not
reachable from outside the cluster.
flui db tunnel <app>
Opens a local tunnel to a Flui database so you can connect a native client. Because Flui databases are not exposed outside the cluster, the command forwards the connection through the control plane over SSH, and no public endpoint is opened. It stays in the foreground; press CTRL-C to close the tunnel.
Once the tunnel is up, the command prints the loopback
host/port, the credentials, a connection string, and a one-line
client invocation for the engine (for example a psql or
mariadb command).
flui db tunnel postgresql-051f58flui db tunnel postgresql-051f58 --local-port 5544flui db tunnel postgresql-051f58 --no-retry| Flag | Default | Effect |
|---|---|---|
-c, --cluster <name|id> | auto-detect | Cluster to resolve the database in. |
--local-port <n> | engine default | Local port to bind on 127.0.0.1. Defaults are engine-specific: 55432 for Postgres, 53306 for MariaDB, 56379 for Valkey/Redis, 57017 for FerretDB. |
--[no-]retry | on | Reconnect automatically if the SSH session drops. Disable with --no-retry. |
With the tunnel running, point any client at 127.0.0.1 on the
local port. For example:
flui db tunnel postgresql-051f58 # leaves the tunnel open in this terminal
# in another terminalpsql -h 127.0.0.1 -p 55432 -U <user> -d <database>The two reserved names
Two names are not applications. flui db tunnel answers
platform-postgres and identity-provider itself, and they
open Flui’s own database and the identity provider’s tables.
They are the only names on this page that are typed verbatim
rather than looked up, the browser console never opens them,
and they need authority over the whole installation.
The rules for them have their own page: Reach the platform’s own database.
flui db dump <app>
Takes a dump of the database and streams it to your machine. The dump is produced inside the cluster by the engine’s own tool, so the tool and its version always match the database.
What you get depends on the engine:
- Postgres and MariaDB: a plain SQL dump.
- Redis and Valkey: a snapshot file (
.rdb). - Any other engine answers that a logical dump is not supported for it and suggests a volume snapshot instead. Nothing is written.
By default the dump lands in the current directory under a name
Flui suggests: the database name and the date, with the right
extension. -o picks your own.
--s3-destination sends the dump to a backup destination
instead of downloading it, which suits anything large or
scheduled. The ids come from flui backup destination list; see
Backups.
flui db dump 4f0b2c1e-…flui db dump 4f0b2c1e-… -o backup.sqlflui db dump 4f0b2c1e-… --s3-destination 9a71…| Flag | Default | Effect |
|---|---|---|
-o, --output <file> | <database>-<date>.<ext> | Write the dump to this file. This is a filename, not the -o table|json used in the rest of the CLI. |
--s3-destination <id> | off | Store the dump in this backup destination instead of downloading it. Prints the bucket and key it wrote. |
flui db restore <app> <file>
Runs a dump file back into the live database. This is the destructive half of the pair: the statements in the file run against the database as it stands, so existing data is overwritten. Flui cannot undo it.
The command asks before it starts, and the default answer is no.
--yes skips the prompt for scripts.
Restore is available for Postgres and MariaDB. A Redis or Valkey snapshot cannot be replayed into a running instance this way; that recovery goes through a volume snapshot, and the command tells you so instead of doing half the job.
flui db restore 4f0b2c1e-… backup.sqlflui db restore 4f0b2c1e-… backup.sql --yes| Flag | Default | Effect |
|---|---|---|
--yes | off | Skip the confirmation prompt. |
flui db disk <app>
Shows how full the storage under a database is. A database that runs out of room stops writing, and for the first ten minutes that failure looks like an application bug, so check this before you start debugging.
The number reported is the fullness of the filesystem hosting
the database’s storage, because that is where writing stops. It
prints used, total, free, the mount point, and a status of
none, warning or critical, with a line telling you to free
space or grow the disk when the status is not none.
When the reading is not available (the database is not running, or its storage cannot be read), it says so instead of reporting zero.
flui db disk 4f0b2c1e-…The command takes no flags.
flui db backup-status <app>
Tells you how far back you can recover a Postgres database. It prints whether continuous backup is on, the schedule of its base backups, the recoverable window from oldest to newest, how many base backups exist, and when the last one was taken.
The newest end of the window is roughly now, because the database keeps shipping its write log continuously between base backups. That is what makes a restore to an arbitrary moment possible.
If the database cannot be reached, the window is reported as unavailable, which is different from empty.
You do not switch continuous backup on from here. It comes from
flui backup enable database <app> -D <dest-id>, from protecting
the whole cluster with flui backup enable cluster, or from the
same choices in the dashboard. See Backups.
It also needs an image that can ship its changes. Flui’s own
Postgres and MariaDB images can. A database whose image cannot,
such as a postgres container inside another application’s
bundle, gets scheduled dumps instead, which restore to the
moment of each dump rather than to any moment.
flui db backup-status 4f0b2c1e-…flui db backup-status 4f0b2c1e-… --json| Flag | Default | Effect |
|---|---|---|
--json | off | Machine-readable output. |
flui db pitr-restore [<app>]
Rebuilds a Postgres database as of a moment in time.
It never touches the source. Instead of rewinding the database you are looking at, Flui creates a new install and recovers it from the continuous backup up to the instant you name. You end up with two databases, the live one untouched and yesterday’s running beside it, and you decide what to do next.
That is the difference from flui db restore: restore
overwrites, pitr-restore copies.
--name is required, because the result is a real application
that needs its own name. Leave --at out to recover to the
latest recoverable point, or give it an ISO-8601 instant to pick
a moment. --cluster here means the target cluster for the new
install, and defaults to the cluster the source is on. So you can
also use this command to bring a database up somewhere else.
The command returns as soon as the restore job is created. The
new install boots in recovery mode; watch for it with
flui app list. It comes up with its own Flui-managed
credentials, not the source’s.
For a database that has been deleted, there is no id to give.
Pass --artifact with one of its backups, from
flui backup list, instead.
flui db pitr-restore 4f0b2c1e-… --name pg-restoredflui db pitr-restore 4f0b2c1e-… --name pg-asof --at "2026-07-03T12:00:00Z"flui db pitr-restore 4f0b2c1e-… --name pg-dr --cluster <cluster-id>flui db pitr-restore --artifact <backup-id> --name pg-back| Flag | Default | Effect |
|---|---|---|
--name <name> | required | Display name for the restored install. |
--at <instant> | latest | ISO-8601 instant to recover to, for example 2026-07-03T12:00:00Z. |
--artifact <id> | none | Restore from this backup instead of naming the database. Works when the database has been deleted. |
--cluster <id> | source’s cluster | Cluster to build the restored install on. |
--yes | off | Skip the confirmation prompt. |
There is nothing to recover from until continuous backup has been running. With no backup for the application, the restore is refused.
flui db pooler <app>
Shows the connection pooler of a managed PostgreSQL: its mode,
whether FLUI_CONNECTION_URL goes through it, and the two
in-cluster addresses, pooled for applications and direct for
migrations, LISTEN and admin tools.
It prints four lines: the mode with how many instances of the
pooler are ready, the image it runs, the pooled address
(FLUI_CONNECTION_URL) and the direct one (FLUI_DIRECT_URL).
While the pooler is not carrying FLUI_CONNECTION_URL yet, both
variables point at the direct address and the last line says why.
A database with no pooler prints one direct address, which both
variables use.
flui db pooler postgresql-051f58flui db pooler postgresql-051f58 --json| Flag | Default | Effect |
|---|---|---|
-c, --cluster <name|id> | every cluster | Cluster to look the database up in. |
--json | off | Machine-readable output. |
The pooler is chosen at install, with
flui catalog install postgresql --option pooler=false to go
without one; this command only reads. What the two addresses and
the two modes mean is in
Connect an application to a managed PostgreSQL.
flui db sessions <db>
Shows who is connected to a managed PostgreSQL and what each session is doing: its state, how long it has run, what it waits for, which sessions block which, and the statement with its values masked.
The first line counts the sessions connected out of the
database’s maximum, and how many are running, idle in a
transaction, blocked, and waiting in the pooler. A blocked
session is printed under the session it waits for. When the
database has a pooler, a Pooler: section follows with each pool
and the clients the pooler holds, each with the client id that
close-client takes.
flui db sessions my-postgresflui db sessions my-postgres --allflui db sessions my-postgres --watch 2| Flag | Default | Effect |
|---|---|---|
-c, --cluster <name|id> | the only cluster | Cluster the database runs on. |
--all | off | Include idle sessions. |
--watch <n> | off | Refresh every n seconds until interrupted. |
--json | off | Machine-readable output. |
Reading sessions needs access to the database’s data, as for the console. The three commands below change something: each asks you to confirm, needs the right to change the application, and is recorded in the activity log. A session or client that has ended in the meantime is reported, and nothing is stopped.
flui db sessions cancel <db> <pid>
Cancels the statement a session is running. The statement fails
with an error in the application that sent it; the connection
stays open. Take the pid from flui db sessions.
flui db sessions cancel my-postgres 4242flui db sessions cancel my-postgres 4242 --yesflui db sessions terminate <db> <pid>
Closes a session. Its open transaction, if any, is rolled back and
the application has to reconnect. Prefer cancel when stopping
the statement is enough.
flui db sessions terminate my-postgres 4242flui db sessions terminate my-postgres 4242 --yesBoth take the same flags:
| Flag | Default | Effect |
|---|---|---|
-c, --cluster <name|id> | the only cluster | Cluster the database runs on. |
-y, --yes | off | Do not ask for confirmation. |
flui db sessions close-client <db> <client>
Closes a connection held by the pooler. The database connection it
holds is closed too, its open transaction is rolled back, and the
application has to reconnect. Take the client id from the pooler
part of flui db sessions.
flui db sessions close-client my-postgres 17| Flag | Default | Effect |
|---|---|---|
-c, --cluster <name|id> | the only cluster | Cluster the database runs on. |
--pod <name> | none | The pooler instance holding the client, when the pooler runs more than one. The name is in the last column of the pooled-client list. |
-y, --yes | off | Do not ask for confirmation. |
How it relates to the dashboard console
These commands are the native-client path: they put a real database endpoint on your loopback interface so any local tool or ORM can talk to it, and they move dumps in and out. The dashboard’s database console is the in-browser path: run a query or browse keys without installing anything, with a helper that never sees your data. The console also has panels for the backup, disk and point-in-time work above.
Both work on the same Flui database building blocks; use whichever fits the task.