Databases

Closed Alpha

Managed databases are enabled for a limited group. Contact support to request access.

This page covers creating a database, connecting it to a service, and running it day to day. For what a managed database is and how to pick a tier, see Databases.

How managed databases work

A database belongs to a Project. Every Service in that Project can connect to it; services in other projects can't. Separate environments are separate projects, so each environment gets its own isolated database.

On the shared tier your database runs on a cluster Forte operates. The storage is yours alone. The compute is shared with other databases on the same cluster.

Your code reaches the database over a TLS-encrypted endpoint using sslmode=require. Most drivers handle this on their own when the connection string asks for it.

Create a database

Use the console or the CLI. The SDKs don't support database management yet.

From the console:

  1. Open the Databases tab in your project.
  2. Choose New database.
  3. Pick PostgreSQL as the engine and Shared as the tier.
  4. Name the database. Names take letters, numbers, hyphens, and underscores, and run 3 to 30 characters.
  5. Choose a storage size.
  6. Create it. The database is ready in under 30 seconds.

From the CLI:

bash
forte databases create --name orders-db --storage 25

Omit any argument and the CLI prompts for it. forte databases list and forte databases get show status and storage; forte databases update --storage 50 resizes.

Choose a storage size

Storage is the only size you pick on the shared tier. Compute is shared across the cluster, so there's no CPU or memory setting.

PresetStorageSuits
Hobby10 GBPrototyping and side projects
Standard25 GBProduction apps with steady load
Performance100 GBHigh-throughput workloads

You can set any custom size from 10 GB to 250 GB instead.

Resizing is online. Pick a new size in the database's settings and it applies right away: no downtime, no restart. You can shrink a database as well as grow it, as long as the new size still exceeds the data it already holds.

Creating a database larger than 10 GB requires a verified billing method. Storage bills at the same rate whichever size you choose: see Pricing and quotas.

Connect a database to a service

Open the database, choose Connect to a service, and pick the service. You then choose the environment variable names your code already reads: either a single connection string (DATABASE_URL by default) or discrete values for host, port, database, username and password. Forte suggests the names your framework expects.

The CLI does the same thing:

bash
# Prompts for the variable name, pre-filled with DATABASE_URL
forte databases connections add
 
# Or name the variables outright
forte databases connections add --service <serviceId> \
  --host-var PGHOST --port-var PGPORT --database-var PGDATABASE \
  --username-var PGUSER --password-var PGPASSWORD

On confirm, Forte:

  1. Creates a Postgres role dedicated to that service, with access to this database only.
  2. Sets the variables you mapped on the service.
  3. Redeploys the service so they reach the running container.

The password is generated by Forte and never shown: not in the console, not in the API response, and not in the service's own environment variable list. Your code reads it from the environment like any other variable:

ts
import { Pool } from "pg";
 
const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 2 });

Changing the mapped names redeploys with the new names. Disconnecting reverses everything: the role is dropped, the variables are removed, and the service redeploys without them.

A service's own environment variables and secrets can't use a name a connected database owns, and vice versa: whichever you try second is rejected rather than silently overriding the other.

For a complete working app, see the Next.js + Node example, which stores per-user records in a connected Postgres database.

Manage database users

Connecting a service creates its role for you. Create a database user yourself when something outside Forte needs access: a migration tool, a SQL client, or an analytics job.

On the Users tab you can:

  • Create a user. Forte generates the password and shows it once. Copy it before closing the dialog; Forte can't show it again.
  • Rotate a password. The old password stops working immediately, so anything still using it fails until you update it. The new password is shown once.
  • Delete a user. Existing connections for that user are closed.

Each database holds up to 25 users.

Connect a SQL client

The database's overview page shows the host, port, and database name. Take the password from the user you created on the Users tab: it's shown once, when you create the user or rotate its password.

Point any Postgres client at those values:

postgresql://USER:PASSWORD@HOST:PORT/DATABASE?sslmode=require

Three things to get right:

  • Use the port shown in the console, not 5432. Connections arrive at a pooler, not at Postgres directly.
  • TLS is required. Set SSL mode to require (or stricter). A plaintext connection is refused.
  • Turn off server-side prepared statements. The endpoint pools per transaction, so prepared statements don't survive between queries. In DBeaver and DataGrip this is a driver property: prepareThreshold=0 on the JDBC URL does it. psql needs nothing.

Session state doesn't carry across queries either, so a client that sets a search path on connect won't keep it. Qualify your table names, or set the search path on the role itself with ALTER ROLE ... SET search_path.

Connection limits

Each database user gets 5 concurrent connections. That budget covers every client using that user at once, including every running instance of a service, since all instances share one role.

Size your connection pool accordingly. A service on 2 provisioned instances should cap its pool at 2 connections per instance, not 5.

Connections pass through a transaction-mode pooler, which reuses a server connection per transaction rather than per session. Session-scoped features don't survive that: avoid LISTEN/NOTIFY, session-level advisory locks, SET statements meant to persist across queries, and server-side prepared statements. Most drivers have a flag to turn off prepared statements: set it if your queries fail with prepared-statement errors.

Query limits

Forte applies limits to every database user so one query can't take the cluster down.

SettingValueWhat it does
statement_timeout30 secondsCancels a single query that runs longer.
transaction_timeout5 minutesCancels a transaction open longer than this.
idle_in_transaction_session_timeout60 secondsCancels a transaction left idle, releasing its locks.
work_mem16 MBMemory per sort or hash step before it spills to disk.
temp_file_limit256 MBThe most temporary file space one query can use.
Parallel queryOffQueries run on a single worker.

Batch jobs and large migrations need to work within these. Split long-running work into smaller transactions.

Monitor a database

The Monitoring tab charts queries, average query time, rows read and written, connections, and active time, over the last hour, 24 hours, or 7 days. The connections chart draws the 5-connection limit as a reference line.

The slow-query list shows the queries taking the longest, so you can find the missing index before it costs you a timeout.

When storage runs out

Forte tracks how much of your provisioned storage the database uses and warns you before it fills:

  • 80% full: Forte emails you.
  • 95% full: Forte emails you again.
  • 100% full: the database goes read-only. Queries still read; writes are rejected.

Resizing is the fastest fix and applies immediately. Because deleting data needs writes, a full database can't clean itself up: contact support for a temporary write window if you'd rather delete data than grow the database.

Database states

StateWhat it means
CreatingForte is provisioning the database.
ActiveThe database accepts reads and writes.
Read onlyWrites are rejected, reads still work. Storage is full, or support set it.
SuspendedConnections are closed and refused.
DeletingForte is removing the database.
FailedProvisioning failed. Contact support.

Backups

Forte backs up every database once a day. To restore from a backup, contact support.

Delete a database

Disconnect every service first: Forte blocks the delete while any connection remains. Then open the database's settings, choose Delete, and type the database name to confirm.

Deleting a database destroys its data.

Limits

LimitValue
Databases per account5 (1 without a verified billing method)
Storage per database10 GB to 250 GB
Users per database25
Services connected per database20
Concurrent connections per user5

To raise a limit, email support@forteplatforms.com.

Next steps

Search

Search documentation and console pages