database.sa-saopaulo-1.basaltic.sh. A cluster
lives in one region, on one of your subnets.
Create a cluster
Engine, flavor, storage and placement — and what a create refuses before
it provisions anything.
Connect
The endpoint you are given, where its password lives, and why you connect
by name.
High availability
Converting a single node in place, adding replicas, and what a failover
actually does.
Backups and restore
The schedule, the retention window, and restoring in place versus into a
new cluster.
Parameter groups
What you may tune, and when a change actually reaches the engine.
Access control
Actions, CRNs, and the tag condition that will not do what you expect.
Engines and versions
GET /v1/engines is the catalogue. You choose a major version only — minor
and patch releases inside that major are applied for you.
Omit
engine_version on create and you get the engine’s default_version from
that catalogue. Read it from the API rather than assuming — the default moves
as majors are added.
What each engine supports
The two engines are not the same product with a different port. Most of the day-2 surface is postgres-only, because it is what the topology underneath can actually do.A valkey cluster is either a single node or a three-member quorum. Two
members cannot hold a stable quorum, so
instance_count: 2 is refused rather
than provisioned into something that cannot fail over.Creating a cluster
name, engine_type, flavor_id, storage_gb and networks are required.
The response is 202 with the cluster in pending; poll
GET /v1/clusters/{cluster_id} until status is active.
1
Pick a database-family flavor
Cluster members book flavors reserved for this product:A
general or loadbalancer flavor is refused with a 400 naming the
family it found. The check runs before anything is reserved, so a wrong
flavor costs you a round trip and nothing else.2
Size the storage
storage_gb is the disk given to each member, so a three-node cluster
of storage_gb: 100 consumes three 100 GB volumes.3
Place it on a subnet
networks takes at least one interface, each naming a subnet_id and
optionally security_group_ids. Every member lands on the same subnets,
and a replica added later inherits that placement. See
Networking for subnets and security groups.4
Choose the exposure
assign_public_ip defaults to true: each endpoint gets a floating IP
and is reachable from the internet. false allocates no floating IP —
endpoints resolve to member addresses inside the VPC, which is how you
place a cluster on a private subnet.The setting governs IPv4 only. IPv6 reachability follows the subnet’s
::/0 route either way, exactly as it does for any other resource.5
Wait for active
Members report their own readiness once the engine is up, and the cluster
flips
building to active when the whole set has reported. First boot
installs and initialises the engine, so allow minutes, not seconds.Naming, quota, and where the members show up
unique per account
Matches
^[a-zA-Z0-9](?:[a-zA-Z0-9_.\-]{0,126}[a-zA-Z0-9])?$. It becomes the
first label of the cluster’s endpoint hostname, so a DNS-friendly name gives
you a DNS-friendly endpoint.database / instances, per region
Quota counts members, not clusters — a three-node cluster consumes three.
Adding a replica reserves one more before the VM is created.
visible in compute, read-only
Each member is an instance in your account and appears in
GET /v1/instances with managed_by: "database". It is there to be seen,
not driven: start, stop, reboot and delete against a managed instance all
404. Manage the cluster through this API.key_names is refused on a database cluster. The members run the platform’s
own software and there is no SSH path to them — the endpoint is the whole
tenant-facing surface.Connecting
A cluster publishes its connection points inendpoints:
Each entry carries
dns_name, port, and ip_address — the address the name
currently answers with.
The name itself is deterministic — the cluster’s name and your account handle
inside a per-region database zone, with the reader carrying a -ro suffix on
the cluster label:
endpoints[].dns_name rather than assembling it yourself.
Credentials
The cluster is created with a bootstrap admin role named byadmin_user
(default admin) and, on postgres, a database named by default_database
(default default).
Its password is not returned by the API. It is stored in the secrets service,
and the cluster reports the id: read admin_secret_id from the cluster, then
fetch that secret. The same holds for every database user you create —
password_secret_id points at the secret that holds it.
Password authentication is SCRAM-SHA-256 for postgres.
High availability
A cluster is HA when it runs more than one member. Postgres starts HA at two members and grows to ten; valkey is HA only at three. You do not have to decide on day one. A single postgres node is the cheap first choice, and there is a path from it to HA that keeps the endpoint and the data.Converting a single node
202 and the cluster reports converting. It returns to
active when the member reports the outcome, and is marked HA-capable
(patroni_managed: true) only on success — a conversion that fails leaves
the node serving exactly as it was. A conversion that is never reported is
abandoned after 30 minutes rather than holding the cluster in converting
forever.
It is refused with 409 if the cluster is already HA-capable, a conversion is
already in flight, the cluster is not active, or it does not have exactly one
member.
Replicas
Adding a replica requires the cluster to be HA-capable, which is not the
same question as its node count. A cluster created single-node has nothing
for a replica to join and is refused with a pointer to
convert-to-ha; a
converted cluster has one member and accepts replicas immediately. The flag
to read is patroni_managed, not instance_count.-ro hostname as one that was born HA.
Removing a replica requires the cluster to be active, and the primary can
never be removed — fail over first, which demotes it, then remove it. Valkey
refuses removals that would leave it at two members.
Failover
target_member out and the engine picks a candidate. Supply one — the
member_name of any member from the cluster’s instances array — and that
member is promoted. Naming a member that is not in the cluster, or the current
primary, is a 400.
What moves:
- The writer endpoint follows the new primary. On a public cluster the floating IP is rebound, so the address does not even change. On a VPC-only cluster the record is republished at the new primary’s address — which is why you connect by name.
- The reader endpoint is re-pinned off the newly promoted member onto another live replica.
failing-over while the switchover is pending, and returns
to active when the transition is reported. A pending switchover that is not
executed within 10 minutes is cleared and the cluster rolls back to
active — retry it.
The cluster must be active and HA. A single-node cluster has nothing to
switch to and is refused.
Users and databases
This whole section is postgres-only. Valkey has no logical databases and no
per-user management —
engine "valkey" has no logical databases or db users
is the refusal. Connect to a valkey cluster with its admin_user and the
admin secret.202. The API records what you asked for and the cluster
converges on it moments later, so a role or database is not necessarily usable
the instant the call returns — check for it on the cluster before pointing an
application at it.
permissions is an engine-specific grant map carried through to the cluster.
Reserved names
Names must be postgres-safe identifiers — a letter or underscore, then letters, digits and underscores, up to 64 characters. On top of that:
The platform-managed principals are excluded because the cluster’s own
replication, bootstrap and coordination depend on them; renaming or dropping
one from underneath would break the cluster rather than the application.
Rotating a password
admin_user cannot be rotated through this path — its secret
belongs to the bootstrap path.
Backups and restore
Every cluster gets a backup repository at create. Postgres additionally archives its write-ahead log continuously, which is what makes point-in-time recovery possible between full backups.The schedule
With a weekly full and two kept, the recoverable window reaches back roughly
two weekly cycles.
Taking one yourself
kind is base (the default — a full copy, needing no earlier backup to build
on) or incremental (only what changed since the last one). full and incr
are accepted as aliases on both the request and the list filter, but the backup
is stored and returned as base or incremental.
The cluster must be active or building. A backup that never reports within
six hours is marked failed.
Valkey takes full backups only — its backup path is a complete dump every
time, so
incremental is refused for that engine.Restoring in place
202 and the cluster reports restoring, which is neither
active nor building: while it holds, the cluster must not be read as
serving current data. An HA cluster is restored as a whole — the leader is
restored and the replicas are rebuilt from it. A restore that fails leaves the
cluster serving, with a fault recorded and the pre-restore backup still
available.
recovery_target_time (RFC 3339) replays the log forward from the backup to
that instant and stops there. Omit it to recover to the latest archived point.
A target earlier than the backup’s earliest_restore_at is refused.
The source backup may belong to this cluster or to another cluster in the
same account; a cross-cluster restore grants this cluster read on that
repository for the duration and revokes it afterwards.
Postgres only. The cluster must be active, and a second restore while one is
in flight is a 409.
Restoring into a new cluster
Passrestore_from on create to bootstrap a new cluster from a backup
instead of an empty database:
succeeded. Valkey
does not support it.
Choosing a backup
GET /v1/clusters/{cluster_id}/backups lists what ran. Two fields decide
whether a given row can be restored:
must be succeeded
running and failed rows are not restore targets.boolean
true means the backup can be selected by name. false means it predates
the platform recording backup labels, so it can only be restored while it is
the source cluster’s most recent succeeded backup — honouring it otherwise
would silently restore a different backup than the one you picked.Parameter groups
A parameter group is a named set of engine settings that clusters bind to. Bound clusters converge on the group’s settings, so editing the group reaches every cluster using it.parameter_group_id, or later with
PATCH /v1/clusters/{cluster_id}. An empty string on the patch clears the
binding and returns the cluster to engine defaults.
A group must match the cluster’s engine type and major version exactly. A
postgres 17 group on a postgres 18 cluster is not a near miss — settings are
version-specific, and binding across versions would apply parameters the
engine may not have.
What you can tune
400s — a group naming an unlisted setting
is rejected outright, not quietly dropped.
Settings the platform owns are absent and refused, and the reasons are worth
knowing:
wal_level,archive_mode,archive_command,max_wal_senders— backups and replication are built on these.listen_addresses,port,data_directory,unix_socket_directories— provisioning assumes them.hot_standby,primary_conninfo,synchronous_standby_names,recovery_target*— owned by the HA supervisor.shared_preload_libraries— a bad value stops the server booting at all.
bind, port and tls-* (the listener),
requirepass, aclfile and user (how the managed user model authenticates),
and dir, dbfilename and appendfilename (where the backup path looks).
Values are validated against the grammar and bounds: 256MB and 30s are
accepted with units, and bounds are compared in the base unit, so 1GB and
1024MB are the same value. A rejection names the offending key.
When a change takes effect
Each parameter reports anapply value:
Editing and deleting
PATCH /v1/parameter-groups/{parameter_group_id} with params replaces the
whole set, and republishes it to every bound cluster.
A group that is still bound to a cluster cannot be deleted; the 409 names the
clusters holding it. Move them off first.
Access control
Every operation checks an IAM policy. Cluster and backup actions authorize against the cluster’s CRN, parameter-group actions against the group’s:These CRNs are keyed by id, not by name, so you cannot fence a naming
convention the way you can for a name-based resource. Fence with tags
instead — see below and Policies.
Requesting a backup needs
database:CreateBackup, even though the
operation is requestBackup and the audit trail records it as
database:RequestBackup. Grant the action, not the verb in the path.basalt:ResourceTag/<key> conditions work on them, and
basalt:RequestTag/<key> fences what a create or update may label a resource
as.
Reads of the whole collection — ListClusters, ListParameterGroups — are
authorized against the account-wide CRN (cluster/*), so a policy can grant
listing in one account or region and not another.
Cluster statuses
Troubleshooting
The cluster is stuck in building
The cluster is stuck in building
A cluster reaches
active only when every member reports readiness, and
first boot installs and initialises the engine from scratch. Minutes are
normal. If it has not moved much longer than that, read fault on the
cluster and check instances[].status — a member that never reached
running is a provisioning problem, not a database one.Add-replica is refused on a cluster that looks fine
Add-replica is refused on a cluster that looks fine
Read
patroni_managed, not instance_count. A cluster created
single-node has no HA machinery for a replica to join and is refused until
you run POST /v1/clusters/{cluster_id}/convert-to-ha. After a successful
conversion the same request works unchanged — even though the cluster
still has exactly one member.The failover went back to active without switching
The failover went back to active without switching
A pending switchover has to be picked up and executed by the current
leader. One that is not executed within 10 minutes is cleared and the
cluster is rolled back to
active so it is not stuck in failing-over.
Retry it. If it keeps expiring, check that the current primary is healthy
in instances.A parameter group edit changed nothing
A parameter group edit changed nothing
Check the parameter’s
apply in
GET /v1/engines/{engine_type}/parameters. A restart parameter is stored
immediately and takes effect only at the engine’s next restart — the
platform does not restart a cluster to apply a config edit.Also confirm the cluster is actually bound: parameter_group_id on the
cluster has to name the group you edited.A restore is refused
A restore is refused
Three checks, in order.
confirm must equal the cluster’s name exactly.
The cluster must be active — a cluster in restoring, converting or
error will not accept one. And the source backup must be succeeded
with restorable: true, or else be the source cluster’s most recent
succeeded backup.Nothing can reach the database
Nothing can reach the database
Work outward. Confirm you are connecting to
endpoints[].dns_name and the
endpoint’s port — 5432 for postgres, 6379 for valkey. Confirm the
exposure matches where you are calling from: assign_public_ip: false
means the endpoint only answers inside the VPC. Then check that a security
group admitting your source is attached to the members’ interfaces —
rules that exist but are not on the interface do nothing. See
Networking.A user or database I created is not there yet
A user or database I created is not there yet
Both calls answer
202. They record intent, and the cluster converges on
it a moment later. Poll the cluster’s users or databases before pointing an
application at one.Next
Networking
Subnets, security groups and the internet gateway a public cluster needs.
Policies
Writing the conditions that fence who may touch which cluster.
API reference
Every cluster, user, backup and parameter-group operation, with schemas.
Support
When a cluster is in
error and fault does not explain it.