{"id":1873,"date":"2025-05-22T10:22:00","date_gmt":"2025-05-22T07:22:00","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/deploying-a-high-availability-postgresql-database-on-upcloud\/"},"modified":"2026-05-12T22:37:07","modified_gmt":"2026-05-12T21:37:07","slug":"deploying-a-high-availability-postgresql-database-on-upcloud","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/deploying-a-high-availability-postgresql-database-on-upcloud\/","title":{"rendered":"Deploying a High-Availability PostgreSQL Database on UpCloud"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PostgreSQL is an open-source relational database management system that is compliant with SQL standards and ACID properties. In addition to its relational data model, PostgreSQL also supports the object-oriented database model, which enables working with complex and user-defined data types and structures for storing and querying data. This hybrid object-relational model makes it suitable for a wide range of use cases and aligns it with a variety of application requirements without sacrificing performance or reliability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In a typical production environment, PostgreSQL is configured in a highly-available setup that comprises multiple instances or database servers that work together as a cluster. This setup improves system availability by removing the single point of failure associated with a single-instance setup, and can also boost performance by distributing the traffic of database queries among the cluster instances.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, setting up a high-availability PostgreSQL cluster can be a complex task that involves a lot of manual work and requires deep expertise with PostgreSQL and clustering solutions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To overcome these complexities, UpCloud offers a managed PostgreSQL database solution that offloads the underlying details of provisioning the database instance and allows for seamless scaling and cluster setup. By using UpCloud\u2019s managed PostgreSQL service, you don\u2019t have to worry about setting up the database cluster yourself, you can just specify the number of instances you want for your cluster and let UpCloud handle the heavy lifting for you!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Considering a Switch? Seamless Migration to UpCloud Managed PostgreSQL<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Many developers managing PostgreSQL on other cloud platforms, like DigitalOcean, are constantly seeking better performance, greater reliability, and more predictable costs. We understand that migrating critical databases can seem daunting. To simplify this process and highlight the advantages of UpCloud&#8217;s managed service, we&#8217;ve prepared a quick video guide to walk you through a smooth migration.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-vimeo wp-block-embed-vimeo wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"PostgreSQL Migration from DigitalOcean to UpCloud\" src=\"https:\/\/player.vimeo.com\/video\/1102153669?dnt=1&amp;app_id=122963\" width=\"500\" height=\"281\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we\u2019ll cover the steps for creating a highly available PostgreSQL cluster using UpCloud&#8217;s managed service. We\u2019ll start by provisioning a PostgreSQL instance, connecting to it, and creating some test data. Then, we\u2019ll scale our setup for high availability with multiple instances. Finally, we\u2019ll test a failover scenario when a database instance in the cluster goes down.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To follow along with this guide, you\u2019ll need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Create an <\/strong><a href=\"https:\/\/signup.upcloud.com\/\"><strong>UpCloud account<\/strong><\/a><strong>:<\/strong> This gives you access to different UpCloud services using the GUI control panel, <a href=\"https:\/\/upcloud.com\/global\/resources\/tools\/upcloud-command-line-interface\">command-line interface<\/a>, or the <a href=\"https:\/\/upcloud.com\/global\/resources\/tools\/category\/api-clients\">API<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/upcloud.com\/global\/resources\/tutorials\/deploy-server\"><strong>Deploy a Cloud server on UpCloud<\/strong><\/a><strong>:<\/strong> We\u2019ll use this server to connect to the database using the postgresql client.<\/li>\n\n\n\n<li><strong>Familiarity with using the CLI:<\/strong> We\u2019ll be using some basic commands throughout this guide to install our tools, navigate project directories, and work with SSH.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a PostgreSQL Instance<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s begin by creating the first PostgreSQL instance. As this is a managed service from UpCloud, we don\u2019t have to install the database ourselves; we can simply provision it through UpCloud control panel GUI with the following steps:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. From the UpCloud dashboard, select <strong>Databases<\/strong> from the left and then select <strong>Create new Database<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/1-ha-postgresql-databases.png\" alt=\"-\" class=\"wp-image-58518\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">2. Select a location where you want to deploy the database, then choose the database type as PostgreSQL. You can choose a specific version by expanding the <strong>Change version<\/strong> option, here I\u2019ll use the latest provided version of <strong>17.5.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/2-ha-postgresql-db-types.png\" alt=\"-\" class=\"wp-image-58519\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">3. Under the <strong>Plan<\/strong>, you can choose the number of instances you want and the resources for each instance. Here we\u2019ll just start with a single instance, which is suitable for testing purposes as it\u2019s not a highly available setup.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/3-ha-postgresql-plans.png\" alt=\"-\" class=\"wp-image-58522\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">4. Specify whether you want to allow public access through the internet or only private access. Private access can be through the <a href=\"https:\/\/upcloud.com\/global\/docs\/products\/networking\/utility-network\/\">Utility network<\/a> or an <a href=\"https:\/\/upcloud.com\/global\/docs\/products\/networking\/sdn-private-networks\/\">SDN network<\/a> if you already have one available in the same location.<br><br>Databases are usually allowed private access only, while the applications that use the database are the ones exposed publicly<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/4-ha-postgresql-connection-access.png\" alt=\"-\" class=\"wp-image-58524\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">5. In the Allowed IP access, you can specify which source IP addresses can access this database. For our scenario, we\u2019re going to use a cloud server within the Utility network, so I\u2019m going to leave the default Utility network access only.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/5-ha-postgresql-allowed-ip-access.png\" alt=\"-\" class=\"wp-image-58526\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">6. Specify a maintenance schedule for the database. Since this is a managed service, patches and updates are automatically applied when required, so you don\u2019t have to download or install them on your own. But because these automated updates can cause disruption to the service, you control the time window when you want these updates to take place using this maintenance schedule.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/6-ha-postgresql-maintenance.png\" alt=\"-\" class=\"wp-image-58527\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">7. The Termination protection option is a preventative measure that protects the database from accidental deletion or shutdown.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/7-ha-postgresql-termination-protection.png\" alt=\"-\" class=\"wp-image-58529\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">8. Provide a Hostname prefix and click on <strong>Create Database<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/8-ha-postgresql-hostname.png\" alt=\"-\" class=\"wp-image-58530\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">9. Wait until the status changes to <strong>Started<\/strong>; this means that the database is ready to be used.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/9-ha-postgresql-status-started.png\" alt=\"-\" class=\"wp-image-58532\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Connecting to The Database<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that our database is running, the next step is to test connectivity to it. We\u2019ll be using an Ubuntu cloud server for the connection, and it must use the Utility network because we only allow private database access from the Utility network.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From inside the cloud server, use the following steps to test the database connection:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Check if the <strong>psql<\/strong> client is already installed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">psql --version\nCommand 'psql' not found<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The above output means that psql is not installed, however, if the output shows the version correctly it means that psql is installed and you can <strong>skip to step 5<\/strong> here.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2. Update the package index.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">sudo apt update<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3. Install the postgres client, this is a command-line utility that we\u2019ll use to connect to the database.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">sudo apt install -y postgresql-client<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. Verify the installation.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">psql --version\npsql (PostgreSQL) 16.8 (Ubuntu 16.8-0ubuntu0.24.04.1)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We can notice here that the psql client version is slightly older than our PostgreSQL database version, this should be fine and satisfies the compatibility requirements for most use cases as mentioned in the <a href=\"https:\/\/www.postgresql.org\/docs\/current\/app-psql.html\" target=\"_blank\" rel=\"noopener\">psql documentation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">5. Select the <strong>Connect<\/strong> option on the top right of the database main page. This will provide the instructions for connecting to the database using different tools including our postgres client (PSQL).<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" data-id=\"58533\" src=\"https:\/\/upcloud.com\/media\/10a-ha-postgresql-connect.png\" alt=\"-\" class=\"wp-image-58533\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" data-id=\"58536\" src=\"https:\/\/upcloud.com\/media\/10b-ha-postgresql-connect.png\" alt=\"-\" class=\"wp-image-58536\" \/><\/figure>\n<\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Note that it\u2019s strongly not recommended to provide these credentials in the psql command directly as plain text. In a production setup, you can store these credentials in a separate configuration file for the client that is properly secured with access permissions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">6. Create a <strong><em>.pgpass<\/em><\/strong> file under the user home directory. The .pgpass file is a secure way to store and use PostgreSQL credentials.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">touch ~\/.pgpass<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">7. Open the file and add the database information in the following format:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">{HOST}:{PORT}:{DB_NAME}:{DB_USER}:{DB_PASSWORD}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">8. Adjust the permissions for the .pgpass file access.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">chmod 0600 ~\/.pgpass<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">9. Use the provided <strong>psql<\/strong> command to test connectivity to the database <strong>without providing the password<\/strong>, it will automatically retrieve it from the .pgpass file.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/11-ha-postgresql-terminal.png\" alt=\"-\" class=\"wp-image-58537\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>defaultdb<\/strong> is a default database created automatically when you provision the database instance. You can create a new database using the <strong>psql<\/strong> client or from the Database page in the UpCloud control panel.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/12-ha-postgresql-deaultdb-1024x525.png\" alt=\"-\" class=\"wp-image-58539\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we\u2019ve verified the connection to the database, the next step is to try writing some data. Instead of using the <strong>psql<\/strong> client, we\u2019ll demonstrate this by connecting to the database using <a href=\"https:\/\/n8n.io\/\" target=\"_blank\" rel=\"noopener\">n8n<\/a>, which is a popular workflow automation tool that supports using external PostgreSQL databases. So let\u2019s first install n8n on our cloud server with the following steps:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Set the required environment variables for the database connection. n8n will use these environment variables to connect to the database.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>DB_TYPE = postgresdb<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">n8n can use sqlite or PostgreSQL, this specifies that we need to use PostgreSQL<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>DB_POSTGRESDB_DATABASE = n8n<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is the database name that n8n will use, we\u2019ll need to create this in our PostgreSQL instance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>DB_POSTGRESDB_HOST = <\/strong><strong><em>&lt;Host name of the database instance&gt;<\/em><\/strong><strong><em><br><\/em><\/strong><strong><em><br><\/em><\/strong><strong>DB_POSTGRESDB_PORT = <\/strong><strong><em>&lt;db port number&gt;<\/em><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The database host name and port number, we can retrieve this from the database connection information in the UpCloud control panel.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/13-ha-postgresql-host-port.png\" alt=\"-\" class=\"wp-image-58540\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>DB_POSTGRESDB_USER = <em>&lt;database username&gt;<br><br><\/em>DB_POSTGRESDB_PASSWORD = <em>&lt;password&gt;<\/em><\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The database username and password, we can get this information also from the UpCloud control panel under the database <strong>Auth<\/strong> section.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/14-ha-postgresql-credentials.png\" alt=\"-\" class=\"wp-image-58543\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>DB_POSTGRESDB_SSL_ENABLED = true<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since our database requires SSL connections, we need to set this to true.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2. Create the new database for n8n. Here I\u2019ll simply use the UpCloud control panel.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/15-ha-postgresql-new-db.png\" alt=\"-\" class=\"wp-image-58545\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">3. n8n requires <a href=\"https:\/\/nodejs.org\/en\" target=\"_blank\" rel=\"noopener\">Node.js<\/a> version 18 or higher, the easiest way to install it is through <a href=\"https:\/\/github.com\/nvm-sh\/nvm\" target=\"_blank\" rel=\"noopener\">nvm<\/a> with the following commands<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">curl -o- https:\/\/raw.githubusercontent.com\/nvm-sh\/nvm\/v0.40.3\/install.sh | bash\n\n\\. \"$HOME\/.nvm\/nvm.sh\"\n\nnvm install 22<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. Start n8n directly using npx.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">npx n8n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/16-ha-postgresql-n8n-started.png\" alt=\"-\" class=\"wp-image-58546\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">5. You should be able to access n8n using the cloud server IP and port <strong>5678<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/17-ha-postgresql-n8n-login.png\" alt=\"-\" class=\"wp-image-58549\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">6. Create a test workflow. This can be anything, we\u2019ll only use it to test writing data to the database.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/18-ha-postgresql-test-workflow.png\" alt=\"-\" class=\"wp-image-58552\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Simulating a Database Failure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s simulate a database failure by manually shutting down our database instance, we\u2019ll then try to access our n8n server again and see what happens:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Select the Shutdown option from the database main page.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/19-ha-postgresql-shut-down.png\" alt=\"-\" class=\"wp-image-58553\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">2. After the database is stopped, try to access the n8n server again.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/20-ha-postgresql-n8n-database-not-ready.png\" alt=\"-\" class=\"wp-image-58555\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As we can see, we\u2019re getting an error of <strong>\u201cDatabase is not ready!\u201d<\/strong>, simply because we only had one instance of the database the n8n service became unavailable when the instance is down.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3. We can also see the status of each specific instance under the nodes section. This can be helpful if we have a cluster of instances as we\u2019ll see later.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/21-ha-postgresql-node-unavailable.png\" alt=\"-\" class=\"wp-image-58557\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">4. Now let\u2019s restore the service by starting our database instance again. You\u2019ll notice that the database instance will transition first to the <strong>standby<\/strong> state and then to the <strong>master<\/strong> state. In a cluster setup, if a master is already running and serving the database writes, the other instances should remain in the standby state.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" data-id=\"58558\" src=\"https:\/\/upcloud.com\/media\/22a-ha-postgresql-node-starting.png\" alt=\"-\" class=\"wp-image-58558\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" data-id=\"58561\" src=\"https:\/\/upcloud.com\/media\/22b-ha-postgresql-node-started.png\" alt=\"-\" class=\"wp-image-58561\" \/><\/figure>\n<\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">5. You should be able to access the n8n server again and see the previously created workflow.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/23-ha-postgresql-n8n-available.png\" alt=\"-\" class=\"wp-image-58563\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Configure High-Availability for PostgreSQL<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To avoid a single-instance failure from disrupting the whole service, we need to set up a high-availability cluster for our PostgreSQL database. One benefit of using a managed service is that it removes the complexities of such configuration. So we can simply create our cluster with the following steps:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Under the settings tab, increase the number of nodes for the database. You might need to select a new plan as part of this operation.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/24-ha-postgresql-settings.png\" alt=\"-\" class=\"wp-image-58565\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/25-ha-postgresql-change-plan.png\" alt=\"-\" class=\"wp-image-58566\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">2. Save your changes and wait for the rebalancing process and data sync to finish.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/26-ha-postgresql-rebalancing.png\" alt=\"-\" class=\"wp-image-58567\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">3. You should be able to see two instances with master and standby status.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/27-ha-postgresql-2-nodes-running.png\" alt=\"-\" class=\"wp-image-58570\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s it, you now have a high-availability PostgreSQL cluster with these simple steps!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It\u2019s important to note that the hostname used for accessing the database doesn\u2019t change, so you don\u2019t have to modify any configuration for the clients connecting to the database. During a connection, this hostname will resolve to one of the database instances IP addresses, and if any failure occurs it will seamlessly switch over to the other IP address without the need for any manual configuration changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, there\u2019s a dedicated hostname created for serving <strong><em>Read<\/em><\/strong> requests from the standby\/replica instances. You can use this dedicated hostname to reduce the load on the master instance and optimize your database performance.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/28-ha-postgresql-read-only-replicas.png\" alt=\"-\" class=\"wp-image-58573\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Another benefit of using a high-availability cluster is during the updates or maintenance. Instead of interrupting the database service for applying the required updates, they can now be rolled out first on the replica instance without impacting the master node, and once the update is finished on the replica it can be applied to the master after that, while promoting the replica temporarily to a master role to serve the traffic. This avoids the downtime caused during the update process.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the Database Cluster<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s test that our database cluster is operational. In a managed database we don\u2019t have direct access to an instance, so we\u2019ll try our scenario by applying an update to our database version, this should take one of the instance down during the process without interrupting the database access:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/29-ha-postgresql-upgrade-version.png\" alt=\"-\" class=\"wp-image-58574\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once the upgrade is started, we should see our standby instance is not ready while the master instance will keep running:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/30-ha-postgresql-master-standby.png\" alt=\"-\" class=\"wp-image-58576\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><br>This means that the upgrade process is now occurring on the standby instance first, while the cluster is still operational and serving requests through the master. We can test this by accessing our n8n server:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/31-ha-postgresql-n8n-overview.png\" alt=\"-\" class=\"wp-image-58578\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once the upgrade is complete you should see both instances as running:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/32-ha-postgresql-2-nodes-running.png\" alt=\"-\" class=\"wp-image-58579\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">All this process happens seamlessly in the background without any manual changes required.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PostgreSQL is a popular relational database management system that fits a wide range of use cases. From scalability, to performance and extensibility, PostgreSQL is capable of satisfying enterprise-level application requirements. However, setting up a production-grade high-availability PostgreSQL cluster can be a complex task, that\u2019s where a managed database service comes into play.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Managed databases remove the administrative overhead associated with manually provisioning database instances and setting up database clusters. It offloads the underlying complexities to the cloud service provider while offering users the flexibility to specify their desired cluster configuration. UpCloud offers a managed PostgreSQL service that makes provisioning database clusters a breeze. You just specify the desired number of nodes and the cluster automatically gets created for you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this article, we covered the steps for creating a managed PostgreSQL on UpCloud. We tested the connectivity to the database instance by deploying n8n on a cloud server, then we created some test data to verify the database access. Finally, we scaled our database for high-availability by configuring additional nodes in the setup, and we verified the cluster operations during maintenance and updates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ready to deploy your high-availability PostgreSQL in the Cloud? <a href=\"https:\/\/signup.upcloud.com\/\">Try UpCloud<\/a> now and create a reliable and performant database cluster setup with minimal effort.<\/p>\n","protected":false},"author":85,"featured_media":6837,"comment_status":"open","ping_status":"closed","template":"","community-category":[226,223],"class_list":["post-1873","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/1873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/85"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=1873"}],"version-history":[{"count":1,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/1873\/revisions"}],"predecessor-version":[{"id":6838,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/1873\/revisions\/6838"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media\/6837"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=1873"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=1873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}