Skip to content
Runtime & ops

Databases

Enable a per-app Postgres schema with a scoped role and encrypted connection string — for any system type, not just bots.

Updated

Every FlareX app — a dashboard, customer portal, internal tool, form, API, or Discord bot — can have its own isolated Postgres schema inside a shared cluster. "Isolated" here means a scoped role that has access to exactly one schema — no cross-app reads, no cross-workspace reads.

Workspace-shared schema on paid plans

The per-app schema below is the default on every plan. Paid plans also get a workspace-shared schema (ws_<workspace>_shared) that every app in the workspace can read and write — so a Discord bot and a staff dashboard can share the same tables. Reference shared tables with the ws_<workspace>_shared.<table> qualifier. (Full shared-DB guide is a forthcoming doc.)

Enabling the database

  1. Open your app → Database.
  2. Click Provision database.
  3. FlareX creates a schema, a scoped role, and injects an encrypted DATABASE_URL into your app's secrets.

Provisioning takes about 2 seconds.

How isolation works

The injected DATABASE_URL looks like:

postgresql://bot_<hash>:<password>@pg.flarex.internal:5432/flarex?search_path=bot_<hash>&options=--role%3Dbot_<hash>

The role can only:

  • See objects inside its own schema.
  • Execute queries via SET LOCAL ROLE bot_<hash> (enforced by the API).
  • Read/write within storage limits (enforced by the storage-sweep job).

The role cannot:

  • SELECT from another schema.
  • pg_dump the whole database.
  • Drop or alter the shared cluster.
  • Escape via search_path tricks — role-based ACLs prevent it.

Querying from the panel

The Database tab has a SQL console. Enter any SELECT/INSERT/UPDATE/DELETE statement and hit Run. Queries execute under SET LOCAL ROLE so you can't accidentally touch another app's data from the panel either.

Tip

Panel queries write the full SQL to the audit log. If you're doing exploratory work on production, the trail is there when someone asks "what changed?" three months later.

Migrations

Two options:

The Migrations tab accepts a raw SQL block per migration. FlareX:

  1. Wraps it in a transaction.
  2. Executes under SET LOCAL ROLE.
  3. Records it in bot_migrations with a checksum.

Failures roll back.

Programmatic migrations (from app code)

Your app can run migrations on startup using your framework of choice (Prisma, Drizzle, Kysely, node-postgres, raw SQL, whatever). The schema is ready before your container starts. Just run your migration client against DATABASE_URL at boot.

Migrations happen at deploy time

FlareX doesn't run your migrations for you. If your app is currently running v1 and v2 adds a migration, the migration runs on v2's startup — and if it fails the deploy is marked failed and v1 stays live. You never end up with the wrong schema for the wrong app version.

Storage limits

Your plan includes a storage quota (500 MB free, up to 200 GB enterprise). Writes are hard-blocked when the app is over the limit — the runner returns an error to the app's INSERT calls.

If you hit the limit:

  • Free tier: upgrade your plan or delete older rows.
  • Paid tiers with overage enabled: writes continue and overage is billed at the per-GB-month rate. Enable overage in Settings → Billing.

The storage sweep runs hourly and measures pg_total_relation_size per schema.

Backups

Automatic daily pg_dump of the shared cluster. Per-app restore: open a support ticket with the app ID and a timestamp — we can restore an individual schema from the dump.

Deleting a database

Deleting an app also deletes its schema (after the 30-day tombstone). There's no standalone "delete just the data, keep the app" option — if you need that, drop tables manually via the SQL console.

Limits

  • Max schema size per app: plan-dependent, 200 GB cap on Enterprise.
  • Max concurrent connections per app: 10 (the pool inside your app's container).
  • No extensions beyond pgcrypto, uuid-ossp, citext, unaccent. Ping support if you need others.
Databases · FlareX