Nodes
A node is one VM in a cluster. Every cluster has exactly one primary; additional nodes are async read replicas.
Add a replica
POST /database/node/add
Authorization: Bearer <token>
Content-Type: application/json
{
"cluster_id": <id>,
"image_id": 1,
"instance_type": "m1a.xlarge",
"subnet_id": 1,
"zone_id": 1,
"allocate_public_ipv4": false,
"security_group_ids": [12]
}Required: cluster_id, image_id, instance_type, subnet_id, zone_id.
The new node is provisioned, joins the cluster as a replica, and starts streaming from the primary. Adding nodes is online — no downtime on the primary.
Replicas can be a different instance type than the primary if you want — pick whatever matches your read workload.
Restart one node
POST /database/node/restart
Authorization: Bearer <token>
Content-Type: application/json
{ "node_id": <id> }Restarting the primary triggers a failover to one of the replicas — clients see a short reconnect window. Restarting a replica is invisible to writers but causes that replica’s connections to drop.
Terminate one node
POST /database/node/terminate
Authorization: Bearer <token>
Content-Type: application/json
{ "node_id": <id> }Removes the node from the cluster. The cluster keeps running with the remaining nodes; the removed node’s storage is released.
You can’t terminate the last node — terminate the cluster itself with cluster/terminate instead.
Read traffic
The cluster hostname resolves to the primary. To read from replicas, use the per-node hostnames returned in database/list, or use a connection pooler like PgBouncer / pgpool-II that knows about streaming replication.
Required permissions
| Action | Permission |
|---|---|
| Add | database:node:add |
| Restart | database:node:restart |
| Terminate | database:node:terminate |
Resource scoping: exc:database:node/<id>. See the
Policies guide.