# Automatic Backup into S3

> Back up the databases of MongoDB, PostgreSQL, MySQL, MariaDB, SQL Server and Oracle on schedules into Amazon S3, Cloudflare R2, Backblaze B2, Wasabi, DigitalOcean Spaces, Akamai, Scaleway, Google Cloud Storage or MinIO - encrypted, at the least priority of the server, the old backups removed by your rules - and restore one in a click, compared with the database of now and chosen table by table.

Source: https://docs.apimaker.dev/v4/docs/features/automatic-backups.html

Back up the databases of your instances on schedules into a bucket of S3, and bring a backup back in a click. Each backup is an [export of Import & Export](https://docs.apimaker.dev/v4/docs/features/import-export.html), made by the database's own program at the least priority of the server ; before a restore, the backup is compared with the database of now and you choose what goes back, table by table.

| | |
|---|---|
| Where | `Dashboard → Operations → Automatic Backup` : the plans, the storages, the log. Admins only. |
| Databases | MongoDB, PostgreSQL, MySQL, MariaDB, SQL Server, Oracle : a whole instance or one database. |
| Stores | Amazon S3, Cloudflare R2, Backblaze B2, Wasabi, DigitalOcean Spaces, Akamai (Linode) Object Storage, Scaleway, Google Cloud Storage (S3 interoperability), MinIO, and any other store which speaks S3. |
| Plans | As many as you like (100 per account), each with what it backs up, when, where, for how long, and how. |
| Schedules | Every few hours, every day, some days of the week, once a month, or an expression of cron, in the time zone you choose. |
| Security | The archive encrypted with a password of the plan (AES-256-GCM), the keys of the store sealed on the server, the store's own encryption (SSE-S3, SSE-KMS). |
| Restore | Back into its database, another database or another instance of the same kind : compared, chosen table by table, checked after. |
| Log | Every backup and restore, kept where Analytics keeps its numbers, 90 days by default. Never part of git. |

> Diagram : Automatic Backup : a backup into S3, and a restore table by table
>
> A backup : the moment of a plan comes, one server takes it, the database's own program dumps it at the least priority of the server, the archive is encrypted with the password of the plan and sent into the bucket in parts of 8 MB, the old backups go by the rules of the plan, and the run is written in the log. A restore : the backup comes back from the bucket, is decrypted and checked, compared with the database of now, and only the tables you choose go back, each checked after.

## Start in three steps

1. **New storage** : the bucket the backups go into, and the keys which reach it. **Check** lists, writes, reads and removes a small file with them : what a backup does.
2. **New plan** : the database, the schedule, the storage, how long the backups stay. **Save** — or **Save and back up now**.
3. Wait for the moment, or press **▶ Back up now** on its row. The run shows its progress on the row, then goes into the log.

## Storages

A storage is a bucket and a folder in it. **New storage** opens its dialog :

- **The store** : one tile per store. The tile fills in what it knows : the address for a region (Cloudflare R2 asks for the id of your account), the regions, and whether the bucket goes in the path of the address (MinIO and most other stores) or in the name of the host (Amazon S3). **Another store which speaks S3** takes an address you write.
- **Bucket** and **Folder** : every backup goes below the folder (`apimaker/production`) ; empty for the root of the bucket. The bucket has to be there already.
- **Access key** and **Secret key** : the secret key is sealed on the server as soon as it is saved (`passDBEncryptDecrypt`), and never shown again ; the access key is shown cut.
- **Storage class** (Amazon S3) : Standard, Standard infrequent access, One zone infrequent access, Intelligent tiering, Glacier instant retrieval, Glacier, Deep archive.
- **Encryption of the store** : none, AES256 (SSE-S3) or aws:kms (SSE-KMS, with the key you name or the key of the account).

> **Warning : Glacier and Deep archive**
>
> The objects of these two classes are not read at once : restore the object in S3 first (its console, or `aws s3api restore-object`), which takes minutes to hours, then restore the backup here. **Glacier instant retrieval** is read at once : take it for backups you may need quickly.

### Keys with the least rights

A policy of AWS IAM for the keys of a storage : list the bucket, and write, read and remove the objects of its folder.

**the least a storage needs**

```json
{
  "Version": "2012-10-17",
  "Statement": [
    { "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::my-backups" },
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:AbortMultipartUpload"],
      "Resource": "arn:aws:s3:::my-backups/apimaker/production/*"
    }
  ]
}
```

A plan which removes nothing (it keeps everything) does without `s3:DeleteObject`, except for the small file of **Check**.

## Plans

**New plan** opens its dialog in four parts.

### What

The instance, then a whole instance or one database, the form of the file and the options of the export : the ones of [Import & Export](https://docs.apimaker.dev/v4/docs/features/import-export.html#options-of-an-export).

### When

| Schedule | Says |
|---|---|
| Every few hours | every 1 to 24 hours, at a minute of the hour |
| Every day | at a time |
| Some days of the week | the days you tick, at a time |
| Once a month | on a day from 1 to 28 (every month has it), at a time |
| Cron expression | any expression of cron, of 5 fields or of 6 (with the seconds) |

Every schedule has its **time zone** : `02:00 Europe/Berlin` stays at 02:00 when the clocks change. The dialog says the schedule in words and its next five moments as you write it. A plan backs up at most every 15 minutes : a backup has to end before the next one starts.

### Where and how long

- **Storage** and **folder** : the folder of the backups in the storage, `{instance}/{plan}` by default. It may hold `{instance}`, `{database}`, `{plan}`, `{yyyy}`, `{mm}` and `{dd}` (the date of the backup) : `{instance}/{yyyy}/{mm}` keeps a folder per month.
- **The backups which stay** : **Grandfather-father-son** (the 7 newest, one a day for 7 days, a week for 4 weeks, a month for 12 months : a year in about 25 files), **The 7 newest**, **30 days**, **Keep everything**, or your own numbers. A backup stays when any rule keeps it ; the newest one always stays, so a plan never empties its storage. The rules run after each backup that worked, and remove only the backups of their plan.

### Security and alerts

- **Encrypt** : the archive is encrypted on the server before it leaves, with the password of the plan (AES-256-GCM, in pieces of 1 MB, the key derived with PBKDF2). The password is sealed on the server ; restores on this installation need nothing more. A backup of another installation, or of a plan which is gone, asks for its password.
- **Gently** (on by default) : the programs of the backup get the least share of the processors and the disks of the server — `nice 19` and the idle class of I/O on Linux, the background mode of macOS, the idle class of Windows. The APIs go first ; the backup takes longer.
- **Upload limit** : the most megabytes per second the upload takes, 0 for no limit.
- **Tell an address** : when a backup fails, after every backup, or never, a POST of JSON to the address you write. Its `text` (Slack, Microsoft Teams) and `content` (Discord) say what happened :

**what the address is told**

```json
{
  "text": "❌ Backup 'Shop nightly' of shop_db failed on server1 : …",
  "content": "❌ Backup 'Shop nightly' of shop_db failed on server1 : …",
  "event": "backup.failed",
  "plan": "Shop nightly", "planId": "6723…", "instance": "shop_db", "database": "shop",
  "status": "FAILED", "key": "", "bytes": 0, "error": "…",
  "startedAt": 1793412000000, "finishedAt": 1793412065000, "server": "server1"
}
```

## Runs

Every server looks at the plans every 20 seconds. The first server which takes a moment of a plan runs its backup : one backup per moment, however many servers there are. A plan whose last backups failed says so on its row, with the error.

A run :

1. **The dump** : the program of the database writes the export into the folder of the job, on the disk of the server — the [most compatible version](https://docs.apimaker.dev/v4/docs/features/import-export.html#the-tools-on-sandbox-settings) of it, installed from its publisher the first time.
2. **Encrypted**, when the plan asks : on the disk, 1 MB at a time.
3. **Sent** into the bucket in parts of 8 MB, two at a time ; a part which fails is tried again, and an upload which fails for good is aborted, so no part stays in the bucket. Beside the archive goes its description (`.json`) : the plan, the database, the SHA-256, the tables and their rows.
4. **The old backups removed** by the rules of the plan.
5. **Written in the log**, and the address of the plan told.

Nothing of the archive is held in memory : it goes from the disk to the bucket piece by piece, and its files are removed from the server once it is sent. The driver of S3 (its connections) is made when a run needs it and let go 2 minutes after the last one.

- **Back up now** on a row runs the plan at once, whatever its schedule ; **Stop** ends a run, its upload aborted.
- **Pause** keeps a plan without its schedule : **Back up now** still works.
- A moment no server was there for — every server stopped for more than 6 hours — is noted **missed** in the log, not backed up late at an hour nobody chose. The next moment backs up as usual.
- A run whose server stopped is said failed in the log.

## Backups and restores

**🕘 Its backups** on the row of a plan lists its backups, newest first ; **📂** on a storage browses its folders. For each backup : its size, its date, whether it is encrypted, and :

- **Details** : what its description says — the plan, the instance, the database, the program, the SHA-256, and each table with its rows.
- **Download** : a link straight from the storage, good for 15 minutes. The file never goes through the server.
- **Remove** : the backup and its description, from the bucket.
- **Restore** : in four steps.

### A restore

1. **Where it goes** : the instance and the database of the backup are filled in. Change them to restore elsewhere ; **A new one** fills in a name beside the one of now (`shop_restored_20261031`), to look at the backup without touching anything.
2. **Brought back** : the backup comes from the bucket in ranges of the object it was (a changed object stops it), is decrypted, and its SHA-256 is checked against its description.
3. **Choose** : the backup is compared with the database of now, table by table, the way [an import is compared](https://docs.apimaker.dev/v4/docs/features/import-export.html#table-by-table). Choose what each table becomes : **Replace**, **Merge**, **Keep** or **Remove**. When a choice replaces or removes rows, type the name of the database to confirm.
4. **Restored** : the tables you chose go back, and each one is counted after : its rows now beside the rows of the backup. The restore goes into the log : who, which backup, each table with what was chosen and what was found.

A file of an export of Import & Export can also be sent to a storage : **Send to a storage** on the export which is done. It is listed with the backups of that folder, and restored the same way.

## The log

The log of the page lists every backup, restore, export sent and missed moment of the account, newest first : when, the plan, its state, the size, how long it took, the key in the bucket. A row opens on the details : how long each part took (the dump, the upload, the removal of old backups ; the download and the import of a restore), the storage, the program, the server, the backups the rules removed, the tables a restore brought back, and the last lines of the log of its job.

- Filter it by plan, kind (backups, restores, exports sent, missed) and state.
- **Keep … days** : how long a record stays (1 to 3,650 days, 90 by default).
- **Clear** : the log of the plan you filtered on, or all of it. The backups stay in their storages.

The records are kept in the database of the logs, where [Analytics](https://docs.apimaker.dev/v4/docs/logs/logs-and-dashboards.html) keeps its numbers — in the main database when there is none — and are never part of a commit or a pull of [git](https://docs.apimaker.dev/v4/docs/Git/git.html).

## In the bucket

```text
my-backups/                                   the bucket
└── apimaker/production/                      the folder of the storage
    └── shop_db/                              {instance}
        └── Shop-nightly/                     {plan}
            ├── shop_db-shop-20261031-020000.zip.enc        the archive : the export, encrypted
            ├── shop_db-shop-20261031-020000.zip.enc.json   its description
            ├── shop_db-shop-20261030-020000.zip.enc
            └── shop_db-shop-20261030-020000.zip.enc.json
```

An archive which is not encrypted is the `.zip` of an [export](https://docs.apimaker.dev/v4/docs/features/import-export.html#the-file-of-an-export) : its `README.txt` says how to restore it by hand with the database's own program. An encrypted one opens with API Maker, on any installation, with its password.

## What is saved

The plans and the storages are rows of the main database of the installation (`am_backup_plans`, `am_backup_storages`), the settings of the log `am_backup_settings`, the log `am_backup_logs`. None of them is part of git : they are of the installation, and the keys of a storage stay on its servers.

> **Warning : A backup holds your data**
>
> Encrypt the plans whose data leaves your network, keep their passwords somewhere else than the installation, and give the keys of a storage the least rights. Try a restore now and then : into a new database, it touches nothing.

## Related

- [Import & Export](https://docs.apimaker.dev/v4/docs/features/import-export.html) : the exports the backups are made of, and the imports a restore is.
- [Sandbox Settings](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html#import-export-tools) : the versions of the programs.
- [Logs and dashboards](https://docs.apimaker.dev/v4/docs/logs/logs-and-dashboards.html) : the database of the logs.
