1. Create the database
- Sign up, verify your email and add a card.
- Choose Create a database.
- Pick a region (EU; US and Asia are coming soon). Your database, its standby and its backups stay there. Not sure which is closest? Enter your server's public IP address and our servers in each region ping it. See Regions and data residency.
- Pick a plan. High-availability plans run on two servers in different sites; single-node plans on one; Dev is a small single-node plan for development and testing. See Plans, resizing and storage limits.
- Give it a name and, optionally, an environment label. A database labelled production starts with deletion protection on.
While the database is being set up, its page shows the setup phases and anything it is retrying. It is ready when its status is live: the servers are running, the hostname resolves and the first backup is done.
2. Copy the connection string
The database page shows one connection string:
postgresql://u_k7m2q9:YOUR_PASSWORD@k7m2q9.db.electradb.com:20017/app?sslmode=verify-full- The user is the database's owner role,
u_<id>, and the database isapp. - The hostname stays the same for the life of the database, including after a failover or a plan change.
- The password is shown once, right after the database is created. Store it in your secrets manager. If you lose it, reset it on the database page: a new password is generated and the old one stops working immediately.
High-availability plans also show a read replica connection string on a second port. It reads from the standby, which can be slightly behind the primary, and rejects writes.
3. Connect
The examples read the connection string from the DATABASE_URL environment variable, so the password stays out of your code. TLS is verified against the public certificate authorities your system already trusts.
.env
DATABASE_URL=postgresql://u_k7m2q9:YOUR_PASSWORD@k7m2q9.db.electradb.com:20017/app?sslmode=verify-full
# for drivers that take the password separately (JDBC)
DATABASE_PASSWORD=YOUR_PASSWORDpsql
psql needs libpq 16 or later for sslrootcert=system:
psql "postgresql://u_k7m2q9:YOUR_PASSWORD@k7m2q9.db.electradb.com:20017/app?sslmode=verify-full&sslrootcert=system"Python (psycopg 3)
# pip install "psycopg[binary]"
import os
import psycopg
# sslrootcert="system": verify the server against your system's certificate authorities
# connect_timeout: a failed server does not refuse, it stops answering
with psycopg.connect(os.environ["DATABASE_URL"], sslrootcert="system", connect_timeout=10) as conn:
print(conn.execute("select version()").fetchone()[0])Node.js (pg)
// npm install pg
import pg from "pg";
const client = new pg.Client({ connectionString: process.env.DATABASE_URL, connectionTimeoutMillis: 10000 });
await client.connect();
const { rows } = await client.query("select version()");
console.log(rows[0].version);
await client.end();Go (pgx)
// go get github.com/jackc/pgx/v5
package main
import (
"context"
"fmt"
"os"
"github.com/jackc/pgx/v5"
)
func main() {
ctx := context.Background()
conn, err := pgx.Connect(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
panic(err)
}
defer conn.Close(ctx)
var v string
conn.QueryRow(ctx, "select version()").Scan(&v)
fmt.Println(v)
}Java (JDBC)
JDBC takes the password separately. DefaultJavaSSLFactory verifies the certificate against the JVM's trusted authorities:
// org.postgresql:postgresql
import java.sql.*;
public class Main {
public static void main(String[] args) throws SQLException {
String url = "jdbc:postgresql://k7m2q9.db.electradb.com:20017/app?sslmode=verify-full&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory&connectTimeout=10";
try (Connection c = DriverManager.getConnection(url, "u_k7m2q9", System.getenv("DATABASE_PASSWORD"))) {
ResultSet r = c.createStatement().executeQuery("select version()");
r.next();
System.out.println(r.getString(1));
}
}
}4. Timeouts and failover
Set a connect timeout of 5 to 10 seconds, on every plan. A server that has failed does not refuse connections, it stops answering. Without a timeout, a new connection waits until your operating system gives up, about two minutes on Linux, before your driver or pool tries again.
| Driver | Setting |
|---|---|
| libpq (psql, psycopg, Ruby pg, PHP) | connect_timeout=10 |
| Go (pgx) | connect_timeout=10 |
| Python (asyncpg) | timeout=10 |
| Node.js (pg) | connectionTimeoutMillis: 10000 |
| Java (JDBC) | connectTimeout=10 |
| .NET (Npgsql) | Timeout=10 |
The libpq, pgx and JDBC settings go in the connection string (&connect_timeout=10); the others are options when you create the connection or pool.
Single-node and Dev plans: the timeout is all you need. If the server fails, the database is restored on another server with the same hostname, and new connections reach it as soon as it is back.
High-availability plans: your hostname has one address per server. If the primary's server fails, the standby is promoted within about 30 seconds and both addresses keep routing to whichever server is the primary. The failed server's address is removed from your hostname about two minutes after it stops answering. Until then, drivers that try every address of a name (libpq, pgx, asyncpg, Npgsql) skip it after the connect timeout.
High-availability databases also have two names with one server each: <id>-primary.db.electradb.com follows the server running the primary, and <id>-fallback.db.electradb.com points at the other one. The database page shows a multi-host connection string that lists both and the main hostname. The driver tries them in order, so it also works with drivers that use only the first address of a name, such as JDBC:
postgresql://u_k7m2q9@k7m2q9-primary.db.electradb.com:20017,k7m2q9-fallback.db.electradb.com:20017,k7m2q9.db.electradb.com:20017/app?sslmode=verify-fullAdd your driver's connect timeout from the table above: each name is tried for that long before the next.
Use a DNS resolver that keeps our 60-second TTL. Our names are served by Cloudflare, and each answer may be cached for 60 seconds. Some ISP and hosting resolvers keep answers longer, so your servers would keep trying an address we already removed. Cloudflare's public resolver keeps the TTL and runs on the same network as our name servers, so your servers see a change within a minute. Set it as your servers' resolver: 1.1.1.1 and 1.0.0.1 (IPv6 2606:4700:4700::1111 and 2606:4700:4700::1001). In Java, also keep the JVM's own DNS cache short: networkaddress.cache.ttl=30 or less.
Open connections to a failed primary are closed in any case: use a driver or pool that reconnects on errors.
5. Next steps
- Limit who can connect with the IP allowlist.
- Learn how to restore to a point in time.
- Choose a replication mode on high-availability plans.
- Automate all of this with the API: create an API key under API keys and send it as
Authorization: Bearer dbk_…to/api/v1.
More guides
- Backups and point-in-time restoreHow ElectraDB backs up PostgreSQL continuously, and how to restore a database to any second of the last 7 days, even after deleting it.
- High availability and replication modesHow ElectraDB keeps PostgreSQL online with a standby in a second site, automatic failover, and sync, write or async replication.
- Security: TLS, passwords, IP allowlist and encryptionHow ElectraDB secures managed PostgreSQL: verified TLS, one-time passwords, IP allowlists, encrypted backups, API keys and two-factor sign-in.
- Plans, resizing and storage limitsChoose an ElectraDB PostgreSQL plan, change plans without downtime, and learn what happens when a database reaches its storage limit.
- When your database is fullA database that reaches its plan's storage becomes read-only. How to free space and get writes working again.
- Regions and data residencyChoose where your ElectraDB PostgreSQL database lives: the EU today, the US and Asia soon. Your database, its standby and its backups stay in that region.
- Frequently asked questionsAnswers about ElectraDB managed PostgreSQL: high availability, backups, point-in-time restore, regions, security, plans and billing.