PostgreSQL
Versions
| Version | Status | Notes |
|---|---|---|
| 18 | Available | Latest |
| 17 | Available | Recommended |
| 16 | Available | |
| 15 | Available | |
| 14 | Available |
Connecting
| Parameter | Value |
|---|---|
| Host | {name}.db.foundrydb.com |
| Port | 5432 |
| Default database | defaultdb |
| TLS | Required, sslmode=verify-full |
PGPASSWORD=pass psql \
"host=HOST user=USER dbname=defaultdb sslmode=verify-full"
Full connection string examples for all languages: Connection Strings →
Connection Pooling (PgBouncer)
Each PostgreSQL backend connection costs memory and a process, so opening one per
client does not scale. PgBouncer sits in front of PostgreSQL and multiplexes many
client connections onto a small pool of server connections, which is what lets
serverless and high-concurrency apps stay within max_connections.
PgBouncer is available on port 5433. Enable it:
curl -u admin:password -X POST \
https://api.foundrydb.com/managed-services/{id}/pooler \
-H "Content-Type: application/json" \
-d '{"pool_size": 25, "pool_mode": "transaction"}'
| Mode | Use case |
|---|---|
transaction | Web apps, short queries (recommended) |
session | Apps that use session-level features (advisory locks, SET, temp tables) |
In transaction mode a server connection is handed back to the pool at the end
of each transaction, which gives the highest reuse but is incompatible with
session-scoped state (named prepared statements, session SET, advisory locks,
LISTEN/NOTIFY). Use session mode for those workloads.
Disable it:
curl -u admin:password -X DELETE \
https://api.foundrydb.com/managed-services/{id}/pooler
High Availability & Replication
FoundryDB runs PostgreSQL as a primary with one or more streaming read replicas. The primary accepts writes; replicas stay in sync by replaying the primary's write-ahead log (WAL) and serve read-only queries. A single stable DNS endpoint fronts the cluster: writes always reach the current primary, and the name never changes even when the underlying primary does.
How the pieces fit together:
- Streaming replication. The primary ships WAL records to each replica over
a replication connection (
max_wal_sendersbounds how many such connections the primary will accept). Replicas run in hot-standby mode, so they answer read queries while they replay. - Synchronous vs. asynchronous. Replicas are asynchronous by default: the primary commits without waiting for a replica to acknowledge, which keeps write latency low. Asynchronous replicas can briefly trail the primary, so a read issued immediately after a write may not yet see it. Synchronous commit trades a little write latency for the guarantee that an acknowledged write is also on a standby.
- Read scaling. Send read-only traffic (reports, dashboards, search) to replicas to take load off the primary. Each replica gets its own hostname, so applications that want to pin reads can target a replica directly.
- Standby for failover. The same replicas double as failover targets. If the primary is lost, a replica is promoted and the endpoint re-points writes to it (see Failover).
- Continuous WAL archiving. Independently of replication, the primary streams its WAL to backup storage with pgBackRest, which is what powers point-in-time recovery (see Point-in-Time Recovery).
Read Replicas
Add a replica for read scaling or standby failover:
curl -u admin:password -X POST \
https://api.foundrydb.com/managed-services/{id}/nodes \
-H "Content-Type: application/json" \
-d '{"role": "replica"}'
Each replica gets its own hostname. List nodes to get the replica hostname:
curl -u admin:password \
https://api.foundrydb.com/managed-services/{id}/nodes
Remove a replica:
curl -u admin:password -X DELETE \
https://api.foundrydb.com/managed-services/{id}/nodes/{node_id}
Failover
Promote a replica to primary (manual failover):
curl -u admin:password -X POST \
https://api.foundrydb.com/managed-services/{id}/nodes/{node_id}/failover
Automatic failover triggers when the primary becomes unreachable for more than 30 seconds (requires at least one replica). During failover:
- A healthy replica is selected and promoted to primary (it stops being read-only and becomes read-write).
- The stable DNS endpoint re-points writes to the new primary. The endpoint name and connection string your application uses do not change.
- Remaining replicas re-attach to the new primary and continue streaming WAL.
- WAL archiving to pgBackRest resumes from the new primary, so PITR coverage continues unbroken.
- The lost node is replaced automatically: a fresh VM is provisioned, seeded from the new primary with a base backup, and added back as a replica, so the cluster self-heals to its original node count rather than running degraded.
- If the old primary later comes back online, it is reattached as a replica of
the new primary (fast-synced with
pg_rewind, falling back to a full base backup) instead of being discarded.
Failover and node replacement are automatic and need no operator action. The one case that pages for a human is losing the primary with no healthy replica left to promote (for example a single-node service): there is no quorum to fail over to, so the service alerts instead of self-healing.
Because replication is asynchronous by default, a failover can lose transactions that were committed on the old primary but had not yet reached the promoted replica. Run with synchronous commit if your workload cannot tolerate that window.
Point-in-Time Recovery
Backups are managed with pgBackRest. On top of the periodic base backups, the primary archives every WAL segment to backup storage continuously, so you can restore not just to a backup boundary but to any moment in the retention window. The retention window is 7 days by default.
Restore to a specific timestamp:
curl -u admin:password -X POST \
https://api.foundrydb.com/managed-services/{id}/backups/restore \
-H "Content-Type: application/json" \
-d '{
"restore_point": "2026-03-15T14:30:00Z",
"target_service_name": "my-pg-restored"
}'
This creates a new service, it does not overwrite the existing one.
Extensions
Extensions add capabilities to PostgreSQL without a separate service: vector
similarity search for AI and ML, geospatial types, time-series, trigram and
fuzzy text search, and more. The list below is pre-installed and ready to enable
with CREATE EXTENSION.
Pre-installed extensions:
| Extension | Version | Use case |
|---|---|---|
pgcrypto | - | Encryption functions |
uuid-ossp | - | UUID generation |
pg_stat_statements | - | Query performance tracking |
postgis | 3.x | Geospatial data |
timescaledb | 2.x | Time-series data |
vector | 0.7+ | Vector embeddings (AI/ML) |
pg_trgm | - | Trigram-based similarity search |
hstore | - | Key-value storage in a column |
ltree | - | Hierarchical tree structures |
unaccent | - | Text search without accents |
Enable an extension:
CREATE EXTENSION IF NOT EXISTS vector;
Configuration
Tune PostgreSQL server parameters:
curl -u admin:password -X PATCH \
https://api.foundrydb.com/managed-services/{id}/configuration \
-H "Content-Type: application/json" \
-d '{
"parameters": {
"shared_buffers": "2GB",
"max_connections": "200",
"work_mem": "64MB",
"wal_level": "logical"
}
}'
Common tuning parameters:
| Parameter | Default | Description |
|---|---|---|
shared_buffers | 128MB | Main memory cache, set to 25% of RAM |
work_mem | 4MB | Per-sort/hash memory, tune for complex queries |
max_connections | 100 | Max simultaneous connections |
effective_cache_size | 4GB | Planner hint for available OS cache |
wal_level | replica | Set to logical for logical replication slots |
max_wal_senders | 10 | Max streaming replication connections |
Logical Replication
Enable logical replication slots for CDC (Change Data Capture) with tools like Debezium:
# Requires wal_level=logical
curl -u admin:password -X POST \
https://api.foundrydb.com/managed-services/{id}/logical-replication/slots \
-H "Content-Type: application/json" \
-d '{"slot_name": "debezium_slot", "plugin": "pgoutput"}'
Metrics
Key metrics available in the dashboard and API:
| Metric | Description |
|---|---|
pg_stat_database_tup_fetched | Rows fetched |
pg_stat_database_xact_commit | Transactions per second |
pg_replication_slots_lag_bytes | Replication slot lag |
pg_stat_bgwriter_buffers_clean | Buffer cache hit rate |
pg_locks_count | Active locks |
curl -u admin:password \
"https://api.foundrydb.com/managed-services/{id}/metrics?metric=connections&period=1h"
Backups
Automated backups run daily. WAL archiving provides continuous PITR on top.
# List backups
curl -u admin:password \
https://api.foundrydb.com/managed-services/{id}/backups
# Trigger a manual backup
curl -u admin:password -X POST \
https://api.foundrydb.com/managed-services/{id}/backups \
-H "Content-Type: application/json" \
-d '{"backup_type": "manual"}'