> ## Documentation Index
> Fetch the complete documentation index at: https://gcore-doc-2189.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage a PostgreSQL server

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).map(c => {
    if (!c || !c.props) return null;
    if (c.props.id) return c;
    const inner = c.props.children;
    if (inner && inner.props && inner.props.id) return inner;
    return null;
  }).filter(Boolean);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
    window.dispatchEvent(new Event("scroll"));
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    <p>Gcore Managed PostgreSQL provisions a fully managed PostgreSQL cluster with automatic backups, optional High Availability replication, and configurable storage. Before creating a cluster, verify that sufficient quota is available in the target region.</p>

    ## Create a server

    <p>If the target region doesn't have sufficient quota, request additional quota first:</p>

    <Steps>
      <Step title="Open the Quotas Viewer">
        Navigate to **Cloud Management** > **Quotas Viewer** and select the region.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-10.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=c7da423e5c0d545b0aff576eacaf4c7b" alt="manage postgresql quotas request" width="1400" height="900" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-10.png" />
        </Frame>
      </Step>

      <Step title="Set quota requirements">
        On the **Database Service** tab, select the required number of PostgreSQL clusters and specify the reason in the field on the right.
      </Step>

      <Step title="Send request" />
    </Steps>

    <p>Requests are typically processed within fifteen minutes. If the quota is not increased after that time, contact [support](mailto:support@gcore.com).</p>

    ### Configure the server

    <p>The creation form configures the region, PostgreSQL version, compute, storage, network, authentication, and database settings.</p>

    <Steps>
      <Step title="Navigate to Managed PostgreSQL">
        In the Cloud menu, navigate to **Managed PostgreSQL** and click **Create PostgreSQL server**.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-30.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=21b03175aa67a9afb5a511c4a96e95ff" alt="manage postgresql create a server" width="1400" height="900" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-30.png" />
        </Frame>
      </Step>

      <Step title="Select a region">
        Select the region where the PostgreSQL server will be hosted.
      </Step>

      <Step title="Select the PostgreSQL version">
        Select the appropriate [PostgreSQL version](/cloud/managed-database-postgresql#supported-versions).
      </Step>

      <Step title="Configure compute and storage">
        In **Compute**, select the server flavor. Optionally, set custom DBMS settings via text mode in the window that opens.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-40.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=cdd8134682e985ebdc38d3bbb767e8fa" alt="manage postgresql select compute and flavor" width="1400" height="900" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-40.png" />
        </Frame>

        In **Storage**, select the volume type and size.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-70.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=79e4cbd577b1cbff34c3caaed2da8407" alt="manage postgresql choose volume" width="1400" height="900" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-70.png" />
        </Frame>
      </Step>

      <Step title="(Optional) Enable high availability">
        Switch on the **Enable high availability** toggle in **PG configuration** to deploy three replicas with the same configuration, ensuring the database remains accessible if the primary server fails. When enabled, select the replication mode:

        1. **Asynchronous**: the primary database sends changes to replicas without waiting for confirmation. Suitable when some data delay is acceptable but high performance is critical.
        2. **Synchronous**: the primary database waits for confirmation that changes have been applied to all replicas. Provides full protection against data loss at the cost of some performance.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-90.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=f3ab6c72652fccc3e2f7aa1465a36cf6" alt="manage postgresql manage replication mode" width="1400" height="900" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-90.png" />
        </Frame>

        This feature can be enabled or disabled later.
      </Step>

      <Step title="Configure network settings">
        In **Network settings**, configure the network interface. Select **Public** and configure the **Access control list** to limit server access to specific IP addresses.

        <Warning>
          Adding `0.0.0.0/0` allows unrestricted access from all IP addresses on the internet. Use this setting only temporarily and exclusively on test servers that do not contain sensitive data.
        </Warning>
      </Step>

      <Step title="Set authentication">
        In **Authentication**, enter a username for the initial database user.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-110-v2.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=0646c2b691071efed3d7b6e0fa956dc9" alt="manage postgresql manage authentication" width="1400" height="900" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-110-v2.png" />
        </Frame>
      </Step>

      <Step title="Configure databases and server details">
        In **Databases**, enter the database name and select the owner. In **Server details**, specify the server name.

        <Info>
          The database size limit is 100 GB during beta. For a larger database size, contact [support](mailto:support@gcore.com).
        </Info>

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-120.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=fa9bd2986bbaea9b042ce64bdcca9f92" alt="manage postgresql specify server details" width="1400" height="900" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-120.png" />
        </Frame>
      </Step>

      <Step title="Create the server">
        Click **Create PostgreSQL server** in the panel on the right.
      </Step>
    </Steps>

    <p>The server will be created in a few minutes.</p>

    ## Get credentials

    <p>Password generation is a one-time operation — the password cannot be recovered after closing the dialog.</p>

    <Steps>
      <Step title="Navigate to the server">
        Navigate to **Managed PostgreSQL** and select the server.
      </Step>

      <Step title="Select the Users tab" />

      <Step title="Generate the password">
        Click **...** next to the user, then click **Generate password**.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-130.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=fd54b865812489793c4f0c6aed7d35a7" alt="Managed PostgreSQL Users tab with Generate password option in the action menu" width="1094" height="533" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-130.png" />
        </Frame>
      </Step>

      <Step title="Copy the password">
        Copy and save the password immediately — it cannot be recovered after the window is closed.

        <Info>
          If the password is lost, it can only be reset. A new password will be generated and the previous one deactivated.
        </Info>
      </Step>

      <Step title="Click OK" />
    </Steps>

    ## Upgrade the PostgreSQL version

    <p>To upgrade to a newer PostgreSQL version:</p>

    <Steps>
      <Step title="Navigate to the server">
        Navigate to **Managed PostgreSQL** and select the server.
      </Step>

      <Step title="Click Update">
        On the **Overview** tab, click **Update** in the General info section.

        <Info>
          If the latest version is already installed, the **Update** button is not displayed.
        </Info>
      </Step>

      <Step title="Select the version and confirm">
        Select the required version from the drop-down list and click **Update**.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-145.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=a67ae1c006cfde897f88d664f4d81b53" alt="manage postgresql update version pop up" width="1026" height="516" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-145.png" />
        </Frame>
      </Step>
    </Steps>

    ## Delete a server

    <p>Deleting a server permanently removes all data and associated resources.</p>

    <Steps>
      <Step title="Navigate to the server">
        Navigate to **Managed PostgreSQL** and select the server to delete.
      </Step>

      <Step title="Select the Delete tab">
        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-150.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=b34e43ed44a0b250d72f41214e05fb3f" alt="Managed PostgreSQL Delete tab with the Delete server button" width="738" height="478" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-150.png" />
        </Frame>
      </Step>

      <Step title="Click Delete server" />

      <Step title="Confirm deletion">
        In the confirmation window, type *Delete* and click **Delete server**.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-160-v2.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=26407d4538fdbbb5c350e6215d111359" alt="Managed PostgreSQL delete server confirmation dialog" width="761" height="426" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-160-v2.png" />
        </Frame>
      </Step>
    </Steps>

    ## Connect to a PostgreSQL server

    <p>Before connecting, collect the server's connection details and verify that the client IP address is included in the access control list.</p>

    <Steps>
      <Step title="Collect connection details">
        On the **Overview** tab of the server, find the connection details:

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-170.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=75d4d82457eef0359e3bf39c5f72be21" alt="Managed PostgreSQL server Overview tab showing Connection details with Endpoint and Port" width="725" height="608" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-170.png" />
        </Frame>

        1. **Endpoint**: available in the **Connection details** section
        2. **Port**: `5432` (fixed for all Managed PostgreSQL clusters)
        3. **Username**: set during server creation — `dbuser` is used in these examples
        4. **Password**: generated separately. If the password was lost, [reset it](/cloud/managed-database-postgresql/manage-postgresql-servers#get-credentials).
      </Step>

      <Step title="Verify client IP in ACL">
        Verify that the client computer's external IP address is included in the access control list (ACL) of the PostgreSQL server.
      </Step>

      <Step title="Select a connection tool">
        1. **psql** — command-line PostgreSQL client.
        2. **pgAdmin** — graphical PostgreSQL administration tool.
      </Step>
    </Steps>

    ### Connect using the psql client

    <p>Run the following commands in a terminal after installing the PostgreSQL client.</p>

    <Steps>
      <Step title="Install the PostgreSQL client">
        [Download](https://www.postgresql.org/download/) and install the PostgreSQL client for the target operating system.
      </Step>

      <Step title="Start psql">
        Run the following command in a terminal:

        ```sh theme={null}
        psql -h hostname -p port -d dbname -U username
        ```

        Replace `hostname`, `port`, `dbname`, and `username` with the actual connection values.
      </Step>

      <Step title="Enter the password">
        Enter the password and press **Enter**.
      </Step>
    </Steps>

    <p>The [PostgreSQL documentation](https://www.postgresql.org/docs/) covers additional psql commands and options.</p>

    ### Connect using pgAdmin

    <p>pgAdmin provides a graphical interface for managing and querying PostgreSQL servers.</p>

    <Steps>
      <Step title="Install pgAdmin">
        [Download](https://www.pgadmin.org/) and install pgAdmin on the client computer.
      </Step>

      <Step title="Launch pgAdmin" />

      <Step title="Add a new server">
        On the **Dashboard** tab, select **Add New Server**.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-180.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=36a60e565915a7165cb742535e3db66c" alt="pgAdmin Dashboard with Add New Server button highlighted" width="900" height="368" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-180.png" />
        </Frame>
      </Step>

      <Step title="Set the server name">
        In the **Create - Server** dialog, type the server name in the **General** tab.

        <Frame>
          <img src="https://mintcdn.com/gcore-doc-2189/XDobTBNnJuS6AvZg/images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-190.png?fit=max&auto=format&n=XDobTBNnJuS6AvZg&q=85&s=934e64cf2b97526644141f1b316ae390" alt="pgAdmin Create Server dialog showing the General tab with a Name field" width="564" height="619" data-path="images/docs/cloud/managed-database-postgresql/manage-postgresql-servers/manage-postgresql-190.png" />
        </Frame>
      </Step>

      <Step title="Set connection details">
        Select the **Connection** tab and enter the endpoint as the host, port (`5432`), username, and password.
      </Step>

      <Step title="Save" />

      <Step title="Connect to the server">
        Locate the server in the left-side menu and click it to connect. The [pgAdmin documentation](https://www.pgadmin.org/docs/) covers advanced configuration options.
      </Step>
    </Steps>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>Gcore Managed PostgreSQL provisions a fully managed database cluster with automatic backups and optional High Availability replication. The workflow below creates a cluster, waits for provisioning to complete, retrieves its connection details and credentials, and connects to it with psql.</p>

    <Info>
      An [API token](/developer-tools/rest-api/authentication) is required, along with a [project ID](/api-reference/cloud/projects/list-projects) and a [region ID](/api-reference/cloud/regions/list-regions).
    </Info>

    <p>Open a bash terminal and set these as environment variables before running the examples:</p>

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    export GCORE_CLOUD_PROJECT_ID="{YOUR_PROJECT_ID}"
    export GCORE_CLOUD_REGION_ID="{YOUR_REGION_ID}"
    ```

    ## Step 1. Activate the PostgreSQL service

    <p>The Managed PostgreSQL service requires a one-time activation per project and region before any clusters can be created.</p>

    ```bash theme={null}
    curl -s -X PUT "https://api.gcore.com/cloud/v1/dbaas/status/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
      -H "Authorization: APIKey $GCORE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"is_initialized": true}'
    ```

    <p>The API returns:</p>

    ```json theme={null}
    {
      "is_initialized": true
    }
    ```

    <p>To check whether activation is already done, call `GET /cloud/v1/dbaas/status/{project_id}/{region_id}` — if `is_initialized` is already `true`, skip this step.</p>

    ## Step 2. Create the cluster

    <p>A single create call provisions the database server, configures network access, creates an initial user, and creates the first database.</p>

    | Parameter                         | Required | Description                                                                                                                     |
    | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
    | `cluster_name`                    | Yes      | Cluster identifier. Pattern `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`, max 50 characters                                                |
    | `pg_server_configuration.version` | Yes      | PostgreSQL major version. Supported values: `"15"`, `"14"`, `"13"`                                                              |
    | `pg_server_configuration.pg_conf` | Yes      | Custom `postgresql.conf` settings as a string. Pass `""` to use defaults                                                        |
    | `flavor.cpu`                      | Yes      | Number of vCPUs allocated to the instance                                                                                       |
    | `flavor.memory_gib`               | Yes      | RAM in GiB                                                                                                                      |
    | `storage.type`                    | Yes      | Block storage type. Use `ssd-hiiops` for best performance                                                                       |
    | `storage.size_gib`                | Yes      | Storage size in GiB. Maximum 100 GiB                                                                                            |
    | `network.acl`                     | Yes      | Allowed source IP addresses in CIDR notation. Use the connecting machine's public IP                                            |
    | `high_availability`               | Yes      | Set to `null` for a single-node cluster, or `{"replication_mode": "sync"}` or `{"replication_mode": "async"}` for three-node HA |
    | `users[].name`                    | No       | Initial database user. Lowercase letters only                                                                                   |
    | `users[].role_attributes`         | No       | PostgreSQL role attributes. Include `"CREATEDB"` to allow creating databases from psql                                          |
    | `databases[].name`                | No       | Initial database name. Lowercase letters only. Must reference a user in `users[]` as `owner`                                    |

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore()
        task_id_list = client.cloud.databases.postgres.clusters.create(
            cluster_name="my-postgres",
            pg_server_configuration={"version": "15", "pg_conf": ""},
            flavor={"cpu": 2, "memory_gib": 4},
            storage={"type": "ssd-hiiops", "size_gib": 10},
            network={
                "network_type": "public",
                "acl": ["{YOUR_IP_ADDRESS}/32"],
            },
            high_availability=None,
            users=[{"name": "dbuser", "role_attributes": ["INHERIT", "LOGIN", "CREATEDB"]}],
            databases=[{"name": "mydb", "owner": "dbuser"}],
        )
        print(task_id_list.tasks[0])
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s -X POST "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID" \
          -H "Authorization: APIKey $GCORE_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{
            "cluster_name": "my-postgres",
            "pg_server_configuration": {
              "version": "15",
              "pg_conf": ""
            },
            "flavor": {
              "cpu": 2,
              "memory_gib": 4
            },
            "storage": {
              "type": "ssd-hiiops",
              "size_gib": 10
            },
            "network": {
              "network_type": "public",
              "acl": ["{YOUR_IP_ADDRESS}/32"]
            },
            "high_availability": null,
            "users": [
              {"name": "dbuser", "role_attributes": ["INHERIT", "LOGIN", "CREATEDB"]}
            ],
            "databases": [
              {"name": "mydb", "owner": "dbuser"}
            ]
          }'
        ```

        Response:

        ```json theme={null}
        {
          "tasks": ["bce1a2e8-d40b-4aca-bbad-fa2c3580cf20"]
        }
        ```
      </Tab>
    </Tabs>

    ```bash theme={null}
    export TASK_ID="{TASK_ID}"
    ```

    ## Step 3. Poll the task

    <p>Cluster creation takes 3-5 minutes. Poll every 5 seconds until `state` is `FINISHED`.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        task = client.cloud.tasks.poll(
            task_id_list.tasks[0],
            polling_interval_seconds=5,
            polling_timeout_seconds=600,
        )
        print("Cluster ready:", task.created_resources.postgresql_clusters[0])
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s "https://api.gcore.com/cloud/v1/tasks/$TASK_ID" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        When complete:

        ```json theme={null}
        {
          "id": "bce1a2e8-d40b-4aca-bbad-fa2c3580cf20",
          "state": "FINISHED",
          "created_resources": {
            "postgresql_clusters": ["my-postgres"]
          }
        }
        ```
      </Tab>
    </Tabs>

    ## Step 4. Get the connection string

    <p>The cluster detail response includes the host, network configuration, and a connection string template in `network.connection_string`. The password field is masked — retrieve it in Step 5.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        cluster = client.cloud.databases.postgres.clusters.get(
            cluster_name="my-postgres",
        )
        print("Status:", cluster.status)
        print("Host:", cluster.network.host)
        print("Connection string:", cluster.network.connection_string)
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        CLUSTER_NAME="my-postgres"

        curl -s "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/$CLUSTER_NAME" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        Response:

        ```json theme={null}
        {
          "cluster_name": "my-postgres",
          "status": "READY",
          "network": {
            "network_type": "public",
            "acl": ["{YOUR_IP_ADDRESS}/32"],
            "host": "my-postgres-67d2e3927a98d77e71c4804f40c4ce1dd68f010d27b11a.pg.k1.frankfurt-2.cloud.gcore.dev",
            "connection_string": "postgres://dbuser:*****@my-postgres-67d2e3927a98d77e71c4804f40c4ce1dd68f010d27b11a.pg.k1.frankfurt-2.cloud.gcore.dev:5432/mydb"
          },
          "flavor": {"cpu": 2, "memory_gib": 4},
          "storage": {"size_gib": 10, "type": "ssd-hiiops"},
          "pg_server_configuration": {"version": "15"},
          "users": [{"name": "dbuser", "is_secret_revealed": false}],
          "databases": [{"name": "mydb", "owner": "dbuser"}]
        }
        ```
      </Tab>
    </Tabs>

    ```bash theme={null}
    export CLUSTER_NAME="my-postgres"
    export PG_HOST="my-postgres-67d2e3927a98d77e71c4804f40c4ce1dd68f010d27b11a.pg.k1.frankfurt-2.cloud.gcore.dev"
    ```

    ## Step 5. Retrieve credentials

    <p>The credentials endpoint reveals the user password. It can only be called once per user — the password is not stored by Gcore afterward. The second call returns an error.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        creds = client.cloud.databases.postgres.clusters.user_credentials.get(
            username="dbuser",
            cluster_name="my-postgres",
        )
        print(creds.username)
        print(creds.password)  # save immediately - second call raises an error
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        USERNAME="dbuser"

        curl -s "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/$CLUSTER_NAME/users/$USERNAME/credentials" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        Response:

        ```json theme={null}
        {
          "username": "dbuser",
          "password": "8T8WieWrkMSvrHlLlnAVtJDV4Vhyxz7..."
        }
        ```
      </Tab>
    </Tabs>

    <Warning>
      Calling this endpoint a second time returns: `"Requested credentials already revealed. You must regenerate credentials"`. To reset the password, call `POST /cloud/v1/dbaas/postgres/clusters/{project_id}/{region_id}/{cluster_name}/users/{username}/credentials`.
    </Warning>

    ## Step 6. Connect with psql

    <p>With the host and password from the previous steps, open a psql session. Set the password via the `PGPASSWORD` environment variable to avoid an interactive prompt.</p>

    ```bash theme={null}
    export PGPASSWORD="{PASSWORD}"

    psql -h $PG_HOST -p 5432 -U dbuser -d mydb
    ```

    ```
    psql (15.x)
    SSL connection (protocol: TLSv1.3, ...)
    Type "help" for help.

    mydb=#
    ```

    <p>Verify the connection and create a table:</p>

    ```sql theme={null}
    CREATE TABLE users (
        id SERIAL PRIMARY KEY,
        name TEXT NOT NULL,
        created_at TIMESTAMPTZ DEFAULT NOW()
    );

    \dt
    ```

    ```
            List of relations
     Schema | Name  | Type  | Owner
    --------+-------+-------+--------
     public | users | table | dbuser
    (1 row)
    ```

    ## Upgrade the PostgreSQL version

    <p>To upgrade to a newer major version, send a PATCH request with the target version. The cluster restarts during the upgrade.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        task_id_list = client.cloud.databases.postgres.clusters.patch(
            cluster_name="my-postgres",
            pg_server_configuration={"version": "16"},
        )
        task = client.cloud.tasks.poll(
            task_id_list.tasks[0],
            polling_interval_seconds=5,
            polling_timeout_seconds=600,
        )
        print("Cluster upgraded:", task.state)
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s -X PATCH "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/$CLUSTER_NAME" \
          -H "Authorization: APIKey $GCORE_API_KEY" \
          -H "Content-Type: application/json" \
          -d '{"pg_server_configuration": {"version": "16"}}'
        ```

        Response:

        ```json theme={null}
        {
          "tasks": ["bce1a2e8-d40b-4aca-bbad-fa2c3580cf20"]
        }
        ```

        Poll the task using the same method as Step 3.
      </Tab>
    </Tabs>

    ## Delete a cluster

    <p>Deleting a cluster removes it and all associated data permanently.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        task_id_list = client.cloud.databases.postgres.clusters.delete(
            cluster_name="my-postgres",
        )
        task = client.cloud.tasks.poll(
            task_id_list.tasks[0],
            polling_interval_seconds=5,
            polling_timeout_seconds=300,
        )
        print("Cluster deleted:", task.state)
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -s -X DELETE "https://api.gcore.com/cloud/v1/dbaas/postgres/clusters/$GCORE_CLOUD_PROJECT_ID/$GCORE_CLOUD_REGION_ID/$CLUSTER_NAME" \
          -H "Authorization: APIKey $GCORE_API_KEY"
        ```

        Response:

        ```json theme={null}
        {
          "tasks": ["bce1a2e8-d40b-4aca-bbad-fa2c3580cf20"]
        }
        ```

        Poll the task using the same method as Step 3.
      </Tab>
    </Tabs>
  </MethodSection>
</MethodSwitch>
