How to Create a PostgreSQL Vector Database Cluster

Last verified 13 Jul 2026

DigitalOcean Managed PostgreSQL for vector search uses the same managed PostgreSQL engine available under Managed Databases, with the pgvector and pgvectorscale extensions for storing and querying vector embeddings alongside relational data.

PostgreSQL vector database clusters use the same managed PostgreSQL engine as DigitalOcean Managed Databases. PostgreSQL vector databases use the pgvector extension to store embeddings in vector columns and run similarity searches against them.

After the cluster is active, enable the vector extension, create a table with a vector column, insert embeddings, create vector indexes, and run similarity queries.

Note

PostgreSQL doesn’t generate embeddings. Generate embeddings in your application and store them as parameter-bound values.

Create a Database Cluster Using Automation

You can create a vector database cluster using the DigitalOcean CLI (doctl) or the API.

Create a Database Cluster via CLI

To create a vector database cluster using doctl, you need to provide values for the --engine, --region, and --size flags. Use the doctl databases options engines, doctl databases options regions, and doctl databases options slugs commands, respectively, to get a list of available values.

How to Create a Database Using the DigitalOcean CLI
  1. Install doctl, the official DigitalOcean CLI.
  2. Create a personal access token and save it for use with doctl.
  3. Use the token to grant doctl access to your DigitalOcean account.
    doctl auth init
  4. Finally, run doctl databases create. Basic usage looks like this, but you can read the usage docs for more details:
    doctl databases create <name> [flags]

The following example creates a database cluster named example-database in the nyc1 region with a single 1 GB node:

doctl databases create example-database --region nyc1 --size db-s-1vcpu-1gb --num-nodes 1

The --wait flag waits until the cluster is online and prints the connection string.

After the cluster is online, add a trusted source so clients can connect to it:

How to Add a Database Firewall Rule to a Given Database Using the DigitalOcean CLI
  1. Install doctl, the official DigitalOcean CLI.
  2. Create a personal access token and save it for use with doctl.
  3. Use the token to grant doctl access to your DigitalOcean account.
    doctl auth init
  4. Finally, run doctl databases firewalls append. Basic usage looks like this, but you can read the usage docs for more details:
    doctl databases firewalls append <database-cluster-id> --rule <type>:<value> [flags]

The following example appends a firewall rule to a database cluster with the ID ca9f591d-f38h-5555-a0ef-1c02d1d1e35 that allows any resources with the example-tag to access the database:

doctl databases firewalls append ca9f591d-f38h-5555-a0ef-1c02d1d1e35 --rule tag:example-tag

To view the cluster’s connection details, use:

How to Retrieve Connection Details for a Database Cluster Using the DigitalOcean CLI
  1. Install doctl, the official DigitalOcean CLI.
  2. Create a personal access token and save it for use with doctl.
  3. Use the token to grant doctl access to your DigitalOcean account.
    doctl auth init
  4. Finally, run doctl databases connection. Basic usage looks like this, but you can read the usage docs for more details:
    doctl databases connection <database-cluster-id> [flags]

The following example retrieves the connection details for a database cluster with the ID f81d4fae-7dec-11d0-a765-00a0c91e6bf6:

doctl databases connection f81d4fae-7dec-11d0-a765-00a0c91e6bf6

For the full command reference, see doctl databases.

Create a Database Cluster via API

To create a vector database cluster using the API, you need to provide values for the engine, region, and size fields, which specify the database’s engine, its datacenter, and its configuration, including the number of CPUs, amount of RAM, and disk size. Use the /v2/databases/options endpoint to get a list of available values.

How to Create a Database Using the DigitalOcean API

Create a personal access token and save it for use with the API.

cURL

Send a POST request to https://api.digitalocean.com/v2/databases.

Using cURL:

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"name": "backend", "engine": "pg", "version": "14", "region": "nyc3", "size": "db-s-2vcpu-4gb", "num_nodes": 2, "storage_size_mib": 61440, "tags": ["production"], "do_settings": {"service_cnames": ["db.example.com", "database.myapp.io"]}}' \
  "https://api.digitalocean.com/v2/databases"

Go

Using Godo, the official DigitalOcean API client for Go:

import (
    "context"
    "os"

    "github.com/digitalocean/godo"
)

func main() {
    token := os.Getenv("DIGITALOCEAN_TOKEN")

    client := godo.NewFromToken(token)
    ctx := context.TODO()

    createRequest := &godo.DatabaseCreateRequest{
        Name:       "backend",
        EngineSlug: "pg",
        Version:    "14",
        Region:     "nyc3",
        SizeSlug:   "db-s-2vcpu-4gb",
        NumNodes:   2,
        StorageSizeMiB : 61440,
        DOSettings: &godo.DOSettings{
            ServiceCnames: []string{"db.example.com", "database.myapp.io"},
        },
    }

    cluster, _, err := client.Databases.Create(ctx, createRequest)
}

Python

Using PyDo, the official DigitalOcean API client for Python:

import os
from pydo import Client

client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN"))

create_req = {
  "name": "backend",
  "engine": "pg",
  "version": "14",
  "region": "nyc3",
  "size": "db-s-2vcpu-4gb",
  "num_nodes": 2,
  "storage_size_mib": 61440,
  "tags": [
    "production"
  ],
  "do_settings": {
    "service_cnames": [
      "db.example.com",
      "database.myapp.io"
    ]
  }
}

create_resp = client.databases.create_cluster(body=create_req)

The response includes the cluster ID, connection details, and a status field. Send a GET request to check the cluster status until it changes from creating to online.

After the cluster is online, add a trusted source so clients can connect to the cluster.

To add a trusted source, use the database firewall endpoint and provide the cluster ID and the trusted source type, such as an IP address, Droplet, Kubernetes cluster, App Platform app, or tag:

How to Update Firewall Rules (Trusted Sources) for a Database Using the DigitalOcean API

Create a personal access token and save it for use with the API.

cURL

Send a PUT request to https://api.digitalocean.com/v2/databases/{database_cluster_uuid}/firewall.

Using cURL:

curl -X PUT \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"rules": [{"type": "ip_addr","value": "192.168.1.1"},{"type": "droplet","value": "163973392"},{"type": "k8s","value": "ff2a6c52-5a44-4b63-b99c-0e98e7a63d61"},{"type": "tag","value": "backend"}]}' \
  "https://api.digitalocean.com/v2/databases/9cc10173-e9ea-4176-9dbc-a4cee4c4ff30/firewall"

Go

Using Godo, the official DigitalOcean API client for Go:

import (
    "context"
    "os"

    "github.com/digitalocean/godo"
)

func main() {
    token := os.Getenv("DIGITALOCEAN_TOKEN")

    client := godo.NewFromToken(token)
    ctx := context.TODO()

    req := godo.DatabaseUpdateFirewallRulesRequest{
      Rules: []*godo.DatabaseFirewallRule{
        {
         Type:  "ip_addr",
         Value: "192.168.1.1",
         Description: "a development IP address",
       },
        {
         Type:  "droplet",
         Value: "163973392",
       },
        {
         Type:  "k8s",
         Value: "ff2a6c52-5a44-4b63-b99c-0e98e7a63d61",
        },
      },
    }
    _, err := client.Databases.UpdateFirewallRules(ctx, dbID, &req)
}

Python

Using PyDo, the official DigitalOcean API client for Python:

import os
from pydo import Client

client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN"))

req = {
  "rules": [
    {
      "type": "ip_addr",
      "value": "192.168.1.1",
      "description": "a development IP address",
    },
    {
      "type": "k8s",
      "value": "ff2a6c52-5a44-4b63-b99c-0e98e7a63d61"
    },
    {
      "type": "droplet",
      "value": "163973392"
    },
    {
      "type": "tag",
      "value": "backend"
    }
  ]
}
update_resp = client.databases.update_firewall_rules(database_cluster_uuid="a7a8bas", body=req)

To retrieve the cluster’s connection details, send a GET request:

How to Retrieve an Existing Database Cluster Using the DigitalOcean API

Create a personal access token and save it for use with the API.

cURL

Send a GET request to https://api.digitalocean.com/v2/databases/{database_cluster_uuid}.

Using cURL:

curl -X GET \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  "https://api.digitalocean.com/v2/databases/9cc10173-e9ea-4176-9dbc-a4cee4c4ff30"

Go

Using Godo, the official DigitalOcean API client for Go:

import (
    "context"
    "os"

    "github.com/digitalocean/godo"
)

func main() {
    token := os.Getenv("DIGITALOCEAN_TOKEN")

    client := godo.NewFromToken(token)
    ctx := context.TODO()

    cluster, _, err := client.Databases.Get(ctx, "9cc10173-e9ea-4176-9dbc-a4cee4c4ff30")
}

Python

Using PyDo, the official DigitalOcean API client for Python:

import os
from pydo import Client

client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN"))

get_resp = client.databases.get_cluster(database_cluster_uuid="a7a89a")

The response includes connection information such as the host, port, username, and password.

For all supported parameters, see the Databases API reference.

Create a Vector Database Cluster Using the Control Panel

To create a vector database cluster, go to the Vector Databases page, and then click Create Vector Database. Or click Create at the top of any page and choose Vector Database from the Data Services section of the menu.

Choose a Database Engine

On the Create Database Cluster page, in Choose a database engine, select PostgreSQL. The database engine and version can’t be changed after creation.

Choose a database engine section with PostgreSQL selected and OpenSearch available.

Choose an Edition

In the Choose an Edition section, select an edition for the cluster.

Choose an edition section with Standard Edition selected and Advanced Edition available.

Edition selection is permanent after the database cluster is created, so choose the edition that fits your workload requirements:

  • Standard Edition: Use for development, testing, and simple production workloads. Standard Edition supports lower-cost basic plans, standard insights, failover in minutes, and essential extensions.

  • Advanced Edition: Use for production workloads that need higher availability, faster failover, advanced insights and troubleshooting, expanded configurability, and larger data sizes.

    Note

    Basic - Shared CPU plans aren’t available for Advanced Edition.

Edition selection affects which configuration, availability, scaling, and extension options you can choose later in your database setup.

Choose a Database Configuration

In the Choose a Database Configuration section, select a database configuration for the cluster.

PostgreSQL uses memory for query execution, indexes, table cache, and active connections. Vector indexes such as HNSW can use significant memory, especially with high-dimensional embeddings or large datasets.

Choose a database configuration section for PostgreSQL with Basic shared CPU selected.

Choose a configuration based on your expected vector count, vector dimensions, metadata size, and query load:

  • Basic - Shared CPU: Use for development, testing, and small vector workloads that don’t need consistent CPU performance.
  • General Purpose - Dedicated CPU: Use for small-to-medium vector workloads that need predictable CPU performance, such as staging or production workloads with moderate query volume.
  • Storage-Optimized - Dedicated CPU: Use for larger vector datasets, higher-dimensional vectors, or high-query-volume workloads where vector indexes need more storage.

You can change the database configuration after creating the cluster, but downsizing isn’t supported.

Choose CPU Options

In the CPU options sub-section, select a CPU type. Available CPU options depend on the selected configuration and region:

  • Regular (Disk: SSD): Use for standard workloads that don’t require NVMe-backed disk performance.

  • Premium AMD (Disk: NVMe): Use for workloads that benefit from faster local disk performance.

    Note

    This option is only available for Standard Edition’s Basic - Shared CPU plan.

  • Premium Intel (Disk: NVMe): Use for workloads that benefit from faster local disk performance and predictable CPU performance.

CPU options sub-section with Regular SSD selected and Premium AMD and Premium Intel NVMe options available.

Premium CPUs use NVMe disks and can provide better performance for workloads with heavier indexing or query activity.

Select a Plan

In the Select a plan sub-section, choose the plan size for the cluster.

Select a plan section with the $13.00/month plan selected and larger plan options listed.

The plan determines the cluster’s vCPUs, RAM, and minimum storage. For vector workloads, choose a plan with enough RAM for vector indexes, table cache, active connections, query execution, and workload growth.

Vector workloads are often memory-bound, so choose a plan with enough RAM for the vector index and its overhead.

If you expect your vector dataset to grow significantly, choose a larger plan before indexing large volumes of data. Resizing later may require reindexing or additional migration work, depending on your index design and workload.

Configure High Availability

In the Maximize uptime for critical workloads sub-section, optionally choose whether to add standby nodes.

Note

Standby nodes are available for PostgreSQL clusters on most editions and configurations, but some of the smallest 1 vCPU Shared CPU plans do not support standby nodes.

High availability sub-section with standby node upgrade options and no standby node selected.

Standby nodes provide higher availability by replacing the primary node if it fails. Clusters with at least one standby node have a 99.95% monthly uptime SLA, while clusters without standby nodes have a 99.5% monthly uptime SLA. For more information, see the Managed Databases SLA.

Choose one of the following options:

  • No standby node: Use for development, testing, and workloads that don’t require higher availability.
  • Add one standby node: Use for production workloads that need higher availability.
  • Add two standby nodes: Use for critical production workloads that need additional failover capacity.

Adding standby nodes increases the cluster’s monthly cost.

Choose a Datacenter Region

In the Choose a Datacenter region section, select a region for the cluster.

Choose a datacenter region section with San Francisco SFO3 selected and additional regions collapsed.

Choose the same region as the application that sends queries to the cluster. Cross-region latency can increase vector query time. For available regions, see Regional Availability.

The cluster uses the default VPC network for the selected datacenter region. Resources in the same VPC network can communicate securely over private IP addresses.

Note

Each region has one or more datacenters, each with its own VPC network. Keeping resources in the same datacenter ensures they share the private networking interface, which reduces latency and prevents traffic from being routed over the public internet.

Finalize and Create

In the Finalize and create section, configure the cluster name and project.

Finalize and create section with database cluster name field and project selector.

In the Choose a unique database cluster name field, either use the generated name or enter a unique name. Names must be lowercase, between 3 and 63 characters long, and can contain dashes.

From the Select a project dropdown menu, choose the project for the cluster.

Optionally, add tags to organize your cluster for billing and reporting.

Review Cost

In the Total monthly cost section, review the estimated monthly and hourly cost for the cluster, including compute, storage, autoscale increment, and autoscale threshold.

Total monthly cost section showing primary node, storage, and total cost.

When finished, click Create Vector Database.

Provisioning can take several minutes depending on the cluster size.

Add a Trusted Source Using Automation

You can add trusted sources using the DigitalOcean CLI (doctl) or the API.

Add a Trusted Source via CLI

To add a trusted source using doctl, use doctl databases firewalls append with the database cluster ID and the trusted source type and value.

How to Add a Trusted Source Using the DigitalOcean CLI
  1. Install doctl, the official DigitalOcean CLI.
  2. Create a personal access token and save it for use with doctl.
  3. Use the token to grant doctl access to your DigitalOcean account.
    doctl auth init
  4. Finally, run doctl databases firewalls append. Basic usage looks like this, but you can read the usage docs for more details:
    doctl databases firewalls append <database-cluster-id> --rule <type>:<value> [flags]

The following example appends a firewall rule to a database cluster with the ID ca9f591d-f38h-5555-a0ef-1c02d1d1e35 that allows any resources with the example-tag to access the database:

doctl databases firewalls append ca9f591d-f38h-5555-a0ef-1c02d1d1e35 --rule tag:example-tag

For list, remove, and other firewall commands, see doctl databases firewalls.

Add a Trusted Source via API

To add a trusted source using the API, send a PUT request to the database firewall endpoint with the cluster ID and the trusted source type and value.

How to Add or Remove a Trusted Source Using the DigitalOcean API

Create a personal access token and save it for use with the API.

cURL

Send a PUT request to https://api.digitalocean.com/v2/databases/{database_cluster_uuid}/firewall.

Using cURL:

curl -X PUT \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"rules": [{"type": "ip_addr","value": "192.168.1.1"},{"type": "droplet","value": "163973392"},{"type": "k8s","value": "ff2a6c52-5a44-4b63-b99c-0e98e7a63d61"},{"type": "tag","value": "backend"}]}' \
  "https://api.digitalocean.com/v2/databases/9cc10173-e9ea-4176-9dbc-a4cee4c4ff30/firewall"

Go

Using Godo, the official DigitalOcean API client for Go:

import (
    "context"
    "os"

    "github.com/digitalocean/godo"
)

func main() {
    token := os.Getenv("DIGITALOCEAN_TOKEN")

    client := godo.NewFromToken(token)
    ctx := context.TODO()

    req := godo.DatabaseUpdateFirewallRulesRequest{
      Rules: []*godo.DatabaseFirewallRule{
        {
         Type:  "ip_addr",
         Value: "192.168.1.1",
         Description: "a development IP address",
       },
        {
         Type:  "droplet",
         Value: "163973392",
       },
        {
         Type:  "k8s",
         Value: "ff2a6c52-5a44-4b63-b99c-0e98e7a63d61",
        },
      },
    }
    _, err := client.Databases.UpdateFirewallRules(ctx, dbID, &req)
}

Python

Using PyDo, the official DigitalOcean API client for Python:

import os
from pydo import Client

client = Client(token=os.environ.get("DIGITALOCEAN_TOKEN"))

req = {
  "rules": [
    {
      "type": "ip_addr",
      "value": "192.168.1.1",
      "description": "a development IP address",
    },
    {
      "type": "k8s",
      "value": "ff2a6c52-5a44-4b63-b99c-0e98e7a63d61"
    },
    {
      "type": "droplet",
      "value": "163973392"
    },
    {
      "type": "tag",
      "value": "backend"
    }
  ]
}
update_resp = client.databases.update_firewall_rules(database_cluster_uuid="a7a8bas", body=req)

Make Bulk Updates to Trusted Sources Using Automation

Bulk updates replace the cluster’s full trusted sources list. Use them when you need to add, remove, or replace multiple trusted sources in one operation.

Make Bulk Updates to Trusted Sources via CLI

To make bulk updates using doctl, use doctl databases firewalls replace with the full list of trusted sources you want the cluster to keep.

How to Make Bulk Updates to Trusted Sources Using the DigitalOcean CLI

To add, remove, or replace multiple trusted sources in one doctl command, replace the cluster’s full firewall rule list with doctl databases firewalls replace.

Pass the rules you want to keep using comma-separated type:value entries in the --rules flag. Each entry uses:

  • type: droplet, k8s, ip_addr, tag, or app
  • value: the resource ID, Kubernetes cluster UUID, IP address or CIDR range, tag name, or App identifier, depending on type

The rules you pass to replace become the cluster’s full trusted sources list. Any existing rule you omit is removed. To change the list safely, first list the current rules with doctl databases firewalls list, then run replace with the full set of type:value entries you want to keep. Clusters are limited to 100 firewall rules.

For required flags, examples, and output formats, see doctl databases firewalls replace.

Make Bulk Updates to Trusted Sources via API

To make bulk updates using the API, send a PUT request to the database firewall endpoint with the full list of trusted sources you want the cluster to keep.

How to Make Bulk Updates to Trusted Sources Using the DigitalOcean API

To add, remove, or replace multiple trusted sources in a single operation, send a PUT request to /v2/databases/{database_cluster_uuid}/firewall with a JSON body that contains a rules array.

Each object in rules supports:

  • type (required): droplet, k8s, ip_addr, tag, or app
  • value (required): the resource ID, Kubernetes cluster UUID, IP address or CIDR range, tag name, or App identifier, depending on type
  • description (optional): a short note; this appears as the rule label in the Control Panel

The rules in your request become the cluster’s full firewall rule list. Any existing rule you omit is removed. To change the list safely, first list firewall rules with GET /v2/databases/{database_cluster_uuid}/firewall, edit the returned rules array, then send your updated array with PUT to the same path. A successful update returns 204 No Content. Clusters are limited to 100 firewall rules.

For example payloads, authentication, and required OAuth scopes (database:read to list, database:update to change rules), see Update firewall rules (trusted sources) for a database in the Databases API reference.

Add a Trusted Source Using the Control Panel

Note

In the Control Panel, you can make bulk changes to trusted sources, but each source must be entered manually. To update many rules at once or replace the entire list in a single operation, use the API or CLI to make bulk updates to trusted sources.

To add trusted sources to restrict database access, go to the Databases page and select the cluster you want to add trusted sources to. Click the Network Access tab, then click Add Trusted Sources.

The Network Access page for an example cluster.

In the Add Trusted Sources window, choose one of the following options:

  • Enter specific IP addresses or CIDR notations: Enter specific IP addresses or a CIDR range. Or click My current IP address to use the Quick Add option, which adds your machine’s current IP address.
The Add Trusted Sources window with the option Enter specific IP addresses or CIDR notations selected, and an example CIDR range shown.
  • Quick select Droplets, Kubernetes clusters, Apps, and tags: Use the search to find a resource or click the dropdown menu and select a resource from the list.
The Add Trusted Sources window with the option Quick select Droplets, Kubernetes clusters, Apps, and tags selected, and the Search or select a resource dropdown menu expanded.

When finished, click Add Trusted Sources.

Warning

You currently cannot add IPv6 rules to a database cluster’s trusted sources.

Copy and Store Connection Details

To copy and store your PostgreSQL vector database cluster’s connection details for later use, go to the Control Panel, in the left menu, click DATA SERVICES, click Vector Databases, and then select the cluster you want to view connection details for.

Then, in the Overview tab, in the CONNECTION DETAILS section, copy the connection parameters for Public network, username, password, host, and port, then store them securely for later use.

Connection Details section showing vector database connection parameters and copy options.

Set Environment Variables for a Trusted Source

To set environment variables for a trusted source, open a terminal session using the trusted source you set up:

export PGHOST="<your-cluster-host>"
export PGPORT="<your-cluster-port>"
export PGUSER="<your-cluster-username>"
export PGPASSWORD="<your-cluster-password>"
export PGDATABASE="<your-database-name>"
export PGSSLMODE="require"

Replace <your-cluster-host>, <your-cluster-port>, <your-cluster-username>, <your-cluster-password>, and <your-database-name> with the values you saved from the cluster’s connection details.

If you added your current IP address as a trusted source, open the terminal from the same computer and network using that IP address.

If you added a DigitalOcean resource, such as a Droplet, as a trusted source, open a terminal session from that resource.

Lastly, verify the connection:

psql -c "SELECT version();"

If successful, the command returns the PostgreSQL version number.

After the cluster is online and you can connect to it, enable the vector extension:

CREATE EXTENSION IF NOT EXISTS vector;
Note

The project is named “pgvector”, but the registered extension name is vector. CREATE EXTENSION pgvector; fails. Always use CREATE EXTENSION vector;.

Then, create a table with a vector column:

CREATE TABLE documents (
    id bigserial PRIMARY KEY,
    title text NOT NULL,
    body text NOT NULL,
    embedding vector(1024)
);

In this table, embedding vector(1024) defines a vector column with 1024 dimensions. Use the dimension required by your embedding model, such as 384, 768, 1024, or 1536.

After you enable the vector extension and create a table with a vector column, you can start indexing and running queries:

We can't find any results for your search.

Try using different keywords or simplifying your search terms.