> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# PostgreSQL version upgrades

> Upgrade a Dedicated database to a newer PostgreSQL major version, in place with a short outage or blue/green with a switch that takes seconds.

> [!NOTE]
>
> **Not yet released.** This guide describes implemented changes awaiting rollout. Availability requires the corresponding backend and dashboard release.

## Goal

Move to PostgreSQL 15, 16, 17 or 18 without rebuilding your database by hand.

## Prerequisites

* A Dedicated PostgreSQL database that is running
* Write access to the database
* A plan for your apps: they reconnect after the switch

## Workflow

**Step 1**

Check the upgrade first: `stackshift database upgrade-precheck DATABASE --data '{"target_version":"18"}'` (`POST /api/v1/databases/{id}/upgrade/precheck`). It can take several minutes. Fix every entry in `problems` and read the `warnings`.

**Step 2**

Compare `methods.in_place` and `methods.blue_green`. Each says if it is `available`, why not, its limits and what it costs you in downtime.

**Step 3**

Start it: `stackshift database upgrade-start DATABASE --data '{"target_version":"18","method":"in_place","apply":"window"}'` (`POST /api/v1/databases/{id}/upgrade`). `apply` is `now` or `window` (your maintenance window).

**Step 4**

Follow it with `stackshift database upgrade DATABASE` (`GET /api/v1/databases/{id}/upgrade`): `status`, the current `step` and the list of `steps`.

**Step 5**

For blue/green, test the new copy at the address in `green`, then switch with `stackshift database upgrade-switchover DATABASE` (`POST /api/v1/databases/{id}/upgrade/switchover`).

**Step 6**

When it is `completed`, check your app. Assign a parameter group for the new version if you use one.

## Choosing a method

* In place: the database is unavailable for a few minutes while PostgreSQL is upgraded. A backup and a restore point are taken first. The standby and read replicas are removed for the upgrade and rebuilt afterwards. This works for any database that passes the check.
* Blue/green: a copy of your database is upgraded and kept in sync while the original keeps serving. You test the copy, then the switch takes seconds. The old database stays read-only for 24 hours so you can switch back. It needs spare capacity on our servers while both run, so the check also tells you if there is room.
* Blue/green copies one database. If the server holds several user databases, or you have large objects, use in place. Tables without a primary key are copied with full-row tracking, and unlogged tables are copied without their rows. Don’t change your table structure while the upgrade runs, because those changes aren’t copied.

## What the check looks at

* Whether the database can be upgraded at all, including a dry run of the upgrade.
* Whether each installed extension is available on the target version.
* For blue/green: the number of user databases, tables without a primary key, unlogged tables, large objects and capacity for the copy.
* A warning if your parameter group is for another version: the database runs on the new version’s defaults until you pick a matching group.

## Steps

* In place: back up the database, take a fast restore point, pause the standby and read replicas, upgrade PostgreSQL, refresh query statistics, start a new backup history, rebuild the standby and read replicas.
* Blue/green: restart with replication enabled (one restart of the original), start the replication source, build the new database, upgrade it, start copying changes, refresh statistics, then wait at ready for your test. After the switch: start a new backup history, rebuild the standby and read replicas, keep the old database read-only for 24 hours, then remove it.
* `status` is `scheduled`, `running`, `ready_for_switchover`, `switching`, `awaiting_retirement`, `rolling_back`, `completed`, `rolled_back`, `failed` or `cancelled`.

## Testing and switching (blue/green)

* While the status is `ready_for_switchover`, `green` gives the address of the new copy, for example `db-<id>-green.stackshift.internal`. Connect with the same user and password. Writes made there are lost at the switch.
* `lag` shows how far the copy is behind. Switch with `{"apply":"now"}` (default) or `{"apply":"window"}` on `stackshift database upgrade-switchover DATABASE --data '{"apply":"window"}'` (`POST …/upgrade/switchover`). Connections drop for a few seconds.

## Cancel and roll back

* Cancel with `stackshift database upgrade-cancel DATABASE` (`POST /api/v1/databases/{id}/upgrade/cancel`) while the upgrade is scheduled, before the in-place upgrade step starts, or before a blue/green switch starts. The database stays on its current version.
* Blue/green rollback: within 24 hours of the switch, while the status is `awaiting_retirement`, switch back with `stackshift database upgrade-rollback DATABASE --data '{"confirm_data_loss":true}'` (`POST …/upgrade/rollback`). Everything written since the switch is dropped, which is why it needs the confirmation. `rollback_until` shows the deadline.
* In place has no switch-back. To go back, restore the backup taken at the start into a new database with `snapshot_backup_id` from the upgrade (see Restore to any second).

## While it runs

Stopping, restarting, size changes, standby and replica changes, maintenance updates and deleting the database are refused with `409` until the upgrade finishes. Only versions 15 to 18 are offered, and a database can’t go to an older version or to its current one.

## Availability

Dedicated databases are rolling out. If Create doesn’t offer Dedicated, it isn’t switched on for your account yet, and the API answers `403`.

Major version upgrades are offered for PostgreSQL only.

## Expected result

> [!TIP]
>
> The database runs the new PostgreSQL major version at the same address, with its standby and read replicas rebuilt.

## Common failures

> [!WARNING]
>
> * `409 upgrade_blocked`: the response has the check report. Fix the `problems`, or choose the other method.
> * `400` for the version: it must be a major version from 15 to 18, newer than the current one.
> * `409` “Wait for the size change to finish before upgrading.” or “A version upgrade is already in progress.”: wait.
> * `409` “Start the database before upgrading it.”: start it first.
> * `409` on rollback: send `confirm_data_loss: true`, and do it within 24 hours of the switch.
> * `409` “This upgrade can no longer be cancelled.”: it is already past the point of no return. Let it finish, then use rollback if you are on blue/green.

## Related guides

> **[Parameter groups](https://docs.stackshift.cloud/databases/parameter-groups.md)**
>
> Tune PostgreSQL settings such as work\_mem or statement\_timeout for one or many Dedicated databases with a reusable parameter group.

> **[Maintenance window and updates](https://docs.stackshift.cloud/databases/maintenance-window.md)**
>
> Choose the weekly window when StackShift updates your Dedicated database, see what is waiting, and apply it now if you prefer.

> **[Fast restore points](https://docs.stackshift.cloud/databases/fast-restore-points.md)**
>
> Take a quick restore point before a risky change and roll the database back to it in minutes. Offered on some servers only.

> **[Standby and high availability](https://docs.stackshift.cloud/databases/standby-and-high-availability.md)**
>
> Add a standby on another server. If the primary fails, the standby takes over and your connection address stays the same.

> **[Restore to any second](https://docs.stackshift.cloud/databases/point-in-time-restore.md)**
>
> Dedicated databases archive every change, so you can restore to an exact second. A restore always creates a new database.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.