---
layout: article
title: Maintenance
description: Maintenance windows, online engine version upgrades, pause and resume, and the lifecycle states of your PostgreSQL database.
---

Appwrite manages the infrastructure around your database: security patches, engine upgrades, and instance health. This page covers the controls you have over when and how that maintenance happens.

# Maintenance window

Routine maintenance that can briefly affect the database runs inside a weekly window that you choose. Set it under **Settings** > **Maintenance** in the Console by picking a day and start hour (UTC), or through the API:

![Maintenance window grid in database settings](/images/docs/products/databases/postgresql/settings-maintenance.avif)

```server-nodejs
import { Client, Postgresql } from 'node-appwrite';

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

const postgresql = new Postgresql(client);

await postgresql.updateMaintenance({
    databaseId: '<DATABASE_ID>',
    day: 'sun',
    hourUtc: 3,
});
```
```server-deno
import { Client, Postgresql } from "npm:node-appwrite";

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

const postgresql = new Postgresql(client);

await postgresql.updateMaintenance({
    databaseId: '<DATABASE_ID>',
    day: 'sun',
    hourUtc: 3,
});
```
```server-php
<?php

use Appwrite\Client;
use Appwrite\Services\Postgresql;

$client = (new Client())
    ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    ->setProject('<PROJECT_ID>')
    ->setKey('<YOUR_API_KEY>');

$postgresql = new Postgresql($client);

$postgresql->updateMaintenance(
    databaseId: '<DATABASE_ID>',
    day: 'sun',
    hourUtc: 3,
);
```
```server-python
from appwrite.client import Client
from appwrite.services.postgresql import Postgresql

client = Client()
client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
client.set_project('<PROJECT_ID>')
client.set_key('<YOUR_API_KEY>')

postgresql = Postgresql(client)

postgresql.update_maintenance(
    database_id='<DATABASE_ID>',
    day='sun',
    hour_utc=3,
)
```
```server-ruby
require 'appwrite'

include Appwrite

client = Client.new
    .set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
    .set_project('<PROJECT_ID>')
    .set_key('<YOUR_API_KEY>')

postgresql = Postgresql.new(client)

postgresql.update_maintenance(
    database_id: '<DATABASE_ID>',
    day: 'sun',
    hour_utc: 3,
)
```
```server-dotnet
using Appwrite;
using Appwrite.Services;

Client client = new Client()
    .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1")
    .SetProject("<PROJECT_ID>")
    .SetKey("<YOUR_API_KEY>");

Postgresql postgresql = new Postgresql(client);

await postgresql.UpdateMaintenance(
    databaseId: "<DATABASE_ID>",
    day: "sun",
    hourUtc: 3
);
```
```server-dart
import 'package:dart_appwrite/dart_appwrite.dart';

Client client = Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

Postgresql postgresql = Postgresql(client);

await postgresql.updateMaintenance(
    databaseId: '<DATABASE_ID>',
    day: 'sun',
    hourUtc: 3,
);
```
```server-kotlin
import io.appwrite.Client
import io.appwrite.services.Postgresql

val client = Client()
    .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
    .setProject("<PROJECT_ID>")
    .setKey("<YOUR_API_KEY>")

val postgresql = Postgresql(client)

postgresql.updateMaintenance(
    databaseId = "<DATABASE_ID>",
    day = "sun",
    hourUtc = 3,
)
```
```server-swift
import Appwrite

let client = Client()
    .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
    .setProject("<PROJECT_ID>")
    .setKey("<YOUR_API_KEY>")

let postgresql = Postgresql(client)

_ = try await postgresql.updateMaintenance(
    databaseId: "<DATABASE_ID>",
    day: "sun",
    hourUtc: 3
)
```
```server-go
package main

import (
    "github.com/appwrite/sdk-for-go/appwrite"
)

func main() {
    client := appwrite.NewClient(
        appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"),
        appwrite.WithProject("<PROJECT_ID>"),
        appwrite.WithKey("<YOUR_API_KEY>"),
    )

    service := appwrite.NewPostgresql(client)

    _, err := service.UpdateMaintenance("<DATABASE_ID>", "sun", 3)
    if err != nil {
        panic(err)
    }
}
```
```server-rust
use appwrite::client::Client;
use appwrite::services::postgresql::Postgresql;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new()
        .set_endpoint("https://<REGION>.cloud.appwrite.io/v1")
        .set_project("<PROJECT_ID>")
        .set_key("<YOUR_API_KEY>");

    let postgresql = Postgresql::new(&client);

    postgresql.update_maintenance("<DATABASE_ID>", "sun", 3).await?;

    Ok(())
}
```
```bash
curl -X PATCH \
  -H "X-Appwrite-Project: <PROJECT_ID>" \
  -H "X-Appwrite-Key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
      "day": "sun",
      "hourUtc": 3
  }' \
  https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/maintenance
```

`day` accepts `sun` through `sat`, and `hourUtc` accepts `0` to `23`.

# Engine version upgrades

You can upgrade the PostgreSQL version online. A second instance is provisioned on the target version, data streams over with logical replication, and traffic cuts over once replication has caught up. Reads continue throughout. At the cutover the old instance is fenced read-only and existing client connections are closed, so writes pause for that moment and the application has to reconnect. The target version must be higher than the current one:

```server-nodejs
import { Client, Postgresql } from 'node-appwrite';

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

const postgresql = new Postgresql(client);

await postgresql.createUpgrade({
    databaseId: '<DATABASE_ID>',
    targetVersion: '18',
});
```
```server-deno
import { Client, Postgresql } from "npm:node-appwrite";

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

const postgresql = new Postgresql(client);

await postgresql.createUpgrade({
    databaseId: '<DATABASE_ID>',
    targetVersion: '18',
});
```
```server-php
<?php

use Appwrite\Client;
use Appwrite\Services\Postgresql;

$client = (new Client())
    ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    ->setProject('<PROJECT_ID>')
    ->setKey('<YOUR_API_KEY>');

$postgresql = new Postgresql($client);

$postgresql->createUpgrade(
    databaseId: '<DATABASE_ID>',
    targetVersion: '18',
);
```
```server-python
from appwrite.client import Client
from appwrite.services.postgresql import Postgresql

client = Client()
client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
client.set_project('<PROJECT_ID>')
client.set_key('<YOUR_API_KEY>')

postgresql = Postgresql(client)

postgresql.create_upgrade(
    database_id='<DATABASE_ID>',
    target_version='18',
)
```
```server-ruby
require 'appwrite'

include Appwrite

client = Client.new
    .set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
    .set_project('<PROJECT_ID>')
    .set_key('<YOUR_API_KEY>')

postgresql = Postgresql.new(client)

postgresql.create_upgrade(
    database_id: '<DATABASE_ID>',
    target_version: '18',
)
```
```server-dotnet
using Appwrite;
using Appwrite.Services;

Client client = new Client()
    .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1")
    .SetProject("<PROJECT_ID>")
    .SetKey("<YOUR_API_KEY>");

Postgresql postgresql = new Postgresql(client);

await postgresql.CreateUpgrade(
    databaseId: "<DATABASE_ID>",
    targetVersion: "18"
);
```
```server-dart
import 'package:dart_appwrite/dart_appwrite.dart';

Client client = Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

Postgresql postgresql = Postgresql(client);

await postgresql.createUpgrade(
    databaseId: '<DATABASE_ID>',
    targetVersion: '18',
);
```
```server-kotlin
import io.appwrite.Client
import io.appwrite.services.Postgresql

val client = Client()
    .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
    .setProject("<PROJECT_ID>")
    .setKey("<YOUR_API_KEY>")

val postgresql = Postgresql(client)

postgresql.createUpgrade(
    databaseId = "<DATABASE_ID>",
    targetVersion = "18",
)
```
```server-swift
import Appwrite

let client = Client()
    .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
    .setProject("<PROJECT_ID>")
    .setKey("<YOUR_API_KEY>")

let postgresql = Postgresql(client)

_ = try await postgresql.createUpgrade(
    databaseId: "<DATABASE_ID>",
    targetVersion: "18"
)
```
```server-go
package main

import (
    "github.com/appwrite/sdk-for-go/appwrite"
)

func main() {
    client := appwrite.NewClient(
        appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"),
        appwrite.WithProject("<PROJECT_ID>"),
        appwrite.WithKey("<YOUR_API_KEY>"),
    )

    service := appwrite.NewPostgresql(client)

    _, err := service.CreateUpgrade("<DATABASE_ID>", "18")
    if err != nil {
        panic(err)
    }
}
```
```server-rust
use appwrite::client::Client;
use appwrite::services::postgresql::Postgresql;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new()
        .set_endpoint("https://<REGION>.cloud.appwrite.io/v1")
        .set_project("<PROJECT_ID>")
        .set_key("<YOUR_API_KEY>");

    let postgresql = Postgresql::new(&client);

    postgresql.create_upgrade("<DATABASE_ID>", "18").await?;

    Ok(())
}
```
```bash
curl -X POST \
  -H "X-Appwrite-Project: <PROJECT_ID>" \
  -H "X-Appwrite-Key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
      "targetVersion": "18"
  }' \
  https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/upgrades
```

Before a major version upgrade, check that your installed [extensions](/docs/products/databases/postgresql/extensions) support the target version.

# Pause and resume

![Database settings status card](/images/docs/products/databases/postgresql/settings.avif)

A paused database stops its compute but keeps its storage, configuration, and credentials. Pause a database you are not using to stop paying for compute; resume it when you need it again. In the Console, open **Settings** > **General** and use the **Running** toggle in the Details card, then click **Update** to apply it. From the API, update the status:

```server-nodejs
import { Client, Postgresql } from 'node-appwrite';

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

const postgresql = new Postgresql(client);

await postgresql.update({
    databaseId: '<DATABASE_ID>',
    status: 'paused',
});
```
```server-deno
import { Client, Postgresql } from "npm:node-appwrite";

const client = new Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

const postgresql = new Postgresql(client);

await postgresql.update({
    databaseId: '<DATABASE_ID>',
    status: 'paused',
});
```
```server-php
<?php

use Appwrite\Client;
use Appwrite\Services\Postgresql;

$client = (new Client())
    ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    ->setProject('<PROJECT_ID>')
    ->setKey('<YOUR_API_KEY>');

$postgresql = new Postgresql($client);

$postgresql->update(
    databaseId: '<DATABASE_ID>',
    status: 'paused',
);
```
```server-python
from appwrite.client import Client
from appwrite.services.postgresql import Postgresql

client = Client()
client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
client.set_project('<PROJECT_ID>')
client.set_key('<YOUR_API_KEY>')

postgresql = Postgresql(client)

postgresql.update(
    database_id='<DATABASE_ID>',
    status='paused',
)
```
```server-ruby
require 'appwrite'

include Appwrite

client = Client.new
    .set_endpoint('https://<REGION>.cloud.appwrite.io/v1')
    .set_project('<PROJECT_ID>')
    .set_key('<YOUR_API_KEY>')

postgresql = Postgresql.new(client)

postgresql.update(
    database_id: '<DATABASE_ID>',
    status: 'paused',
)
```
```server-dotnet
using Appwrite;
using Appwrite.Services;

Client client = new Client()
    .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1")
    .SetProject("<PROJECT_ID>")
    .SetKey("<YOUR_API_KEY>");

Postgresql postgresql = new Postgresql(client);

await postgresql.Update(
    databaseId: "<DATABASE_ID>",
    status: "paused"
);
```
```server-dart
import 'package:dart_appwrite/dart_appwrite.dart';

Client client = Client()
    .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');

Postgresql postgresql = Postgresql(client);

await postgresql.update(
    databaseId: '<DATABASE_ID>',
    status: 'paused',
);
```
```server-kotlin
import io.appwrite.Client
import io.appwrite.services.Postgresql

val client = Client()
    .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
    .setProject("<PROJECT_ID>")
    .setKey("<YOUR_API_KEY>")

val postgresql = Postgresql(client)

postgresql.update(
    databaseId = "<DATABASE_ID>",
    status = "paused",
)
```
```server-swift
import Appwrite

let client = Client()
    .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
    .setProject("<PROJECT_ID>")
    .setKey("<YOUR_API_KEY>")

let postgresql = Postgresql(client)

_ = try await postgresql.update(
    databaseId: "<DATABASE_ID>",
    status: "paused"
)
```
```server-go
package main

import (
    "github.com/appwrite/sdk-for-go/appwrite"
    "github.com/appwrite/sdk-for-go/postgresql"
)

func main() {
    client := appwrite.NewClient(
        appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"),
        appwrite.WithProject("<PROJECT_ID>"),
        appwrite.WithKey("<YOUR_API_KEY>"),
    )

    service := appwrite.NewPostgresql(client)

    _, err := service.Update(
        "<DATABASE_ID>",
        postgresql.WithUpdateStatus("paused"),
    )
    if err != nil {
        panic(err)
    }
}
```
```server-rust
use appwrite::client::Client;
use appwrite::services::postgresql::Postgresql;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new()
        .set_endpoint("https://<REGION>.cloud.appwrite.io/v1")
        .set_project("<PROJECT_ID>")
        .set_key("<YOUR_API_KEY>");

    let postgresql = Postgresql::new(&client);

    postgresql.update("<DATABASE_ID>", None, Some("paused"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?;

    Ok(())
}
```
```bash
curl -X PATCH \
  -H "X-Appwrite-Project: <PROJECT_ID>" \
  -H "X-Appwrite-Key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
      "status": "paused"
  }' \
  https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>
```

Set `status` back to `ready` to resume. Both transitions are asynchronous: the request returns immediately and the database moves through `pausing` or `resuming` before settling. A database in the `failed` state can also be recovered by setting its status to `ready`.

# Lifecycle states

| Status | Meaning |
|----------------|------------------------------------------------------------------|
| `provisioning` | Being created |
| `ready` | Online and accepting connections |
| `scaling` | A configuration or specification change is being applied |
| `pausing` | Transitioning to paused |
| `paused` | Compute stopped, storage retained |
| `resuming` | Transitioning back to ready |
| `restoring` | A backup or point-in-time restore is in progress |
| `upgrading` | An engine version upgrade is in progress |
| `migrating` | A migration is in progress |
| `failing-over` | A replica is being promoted to primary |
| `inactive` | Idle and scaled down to zero |
| `deleting` | Deletion is in progress |
| `deleted` | Deletion has finished |
| `failed` | An infrastructure error occurred; the database can be resumed |

# Deleting a database

Delete a database from **Settings** > **General** in the Console, or programmatically. The database moves to `deleting` and the teardown runs in the background. Deleting a database also deletes its backups, so export anything you need first.
