# Persistence and backups

> Snapshots, the append-only file, and HotKV Cloud backups.

URL: https://docs.hotkv.com/persistence/

HotKV persists data to disk two ways, which can be used together: periodic
binary snapshots and an append-only file (AOF) that logs every write. Both
are configured under `[persistence]` in `hotkv.toml`, or the matching
flat directives in `hotkv.conf`.

## Snapshots

A snapshot is a binary dump (`.hkv`, HotKV's own format) of every
database. Configure when one is taken with one or more save points, each
`seconds changes`: HotKV writes a new snapshot in the background once at
least `changes` writes were made and more than `seconds` passed since the
last one. It also saves at shutdown when there are save points. Without
any `save` setting these three defaults apply:

```toml
[persistence]
dbfilename = "dump.hkv"
dir = "/var/lib/hotkv"

[[persistence.save]]
seconds = 3600
changes = 1

[[persistence.save]]
seconds = 300
changes = 100

[[persistence.save]]
seconds = 60
changes = 10000
```

or in `hotkv.conf`:

```
dbfilename dump.hkv
dir /var/lib/hotkv
save 3600 1
save 300 100
save 60 10000
```

For no automatic snapshots, set `save = []` under `[persistence]` in
`hotkv.toml`, or `save ""` in `hotkv.conf` (removing the lines is not
enough: the defaults apply then). `CONFIG SET save "900 1 300 10"` changes
the save points at runtime.

`save ""` only stops new snapshots. A server started in a directory that
holds a snapshot still loads it. See
[Start without the snapshot](#start-without-the-snapshot) to start empty.

Take one yourself with `SAVE` or `BGSAVE`. `SAVE` makes every other
command wait while it writes, so its snapshot is the data at one moment.
`BGSAVE` and the save points write in the background while commands keep
running: each key is saved as it is when the snapshot reaches it, so a
background snapshot is not a single point in time. `LASTSAVE` returns the UNIX timestamp of the last successful
save, and `INFO persistence` the changes since then
(`rdb_changes_since_last_save`).

A snapshot is written to a temporary file, synced to disk and renamed over
the previous one, so a crash leaves one or the other whole. If the server
cannot read the snapshot at startup (a damaged file, or one encrypted with
another key), it does not start, rather than start without the data and
save over it.

When a background save fails (a full disk, say) and there are save points,
commands that change data are refused with a `MISCONF` error until a save
succeeds, so that the server does not keep taking writes it cannot save.
Reads keep working; `PING` gets the error too, so that monitoring notices.
The server log says why the save failed; once the cause is fixed, the next
save (`BGSAVE`, `SAVE`, or the save points, which try again every few
seconds) accepts writes again. To keep taking writes regardless, set
`stop_writes_on_bgsave_error = false` under `[persistence]`
(`stop-writes-on-bgsave-error no` in `hotkv.conf`, or with `CONFIG SET`).

### Start without the snapshot

For a throwaway instance, a benchmark or a test, start the server with
`--no-snapshot`:

```bash
hotkv --no-snapshot --dir /tmp/scratch
```

It does not load the snapshot in `dir`, so it starts empty even if an earlier
run saved there, and it has no save points: nothing is written at shutdown or
by the background saves. The snapshot file already in `dir` is left as it was.
`SAVE` and `BGSAVE` still write a snapshot when you ask for one, and a later
start without the flag loads it. The append-only file is read as usual.

## Append-only file (AOF)

The AOF logs every write as it happens, for finer-grained crash recovery
than a snapshot alone:

```toml
[persistence]
appendonly = true
appendfilename = "appendonly.hkv"
appendfsync = "everysec"

[persistence.aof]
no_appendfsync_on_rewrite = false
auto_rewrite_percentage = 100
auto_rewrite_min_size = "64mb"
```

`appendfsync` controls durability versus throughput: `always` syncs the
AOF to disk with every write, within about a millisecond (safest,
slowest), `everysec` once per second on a background thread (recommended:
a power loss costs at most about a second of writes), and `no` leaves it
to the operating system (fastest, most risk on a power loss).
`BGREWRITEAOF` compacts the AOF; it also runs automatically once the file
has grown by `auto-aof-rewrite-percentage` since the last rewrite and is
larger than `auto-aof-rewrite-min-size` (`auto_rewrite_percentage` and
`auto_rewrite_min_size` under `[persistence.aof]`; a percentage of `0`
turns automatic rewrites off). As in Redis, a child process writes the new
file from the data as it was when it started, while commands keep
running; the writes made meanwhile follow the data in the new file. The
child shares the server's memory until pages change, so heavy writes
during a rewrite use more memory. A command cut off at the end of
the file (the process died while writing it) is dropped at startup; damage
before the end stops the start, and the log says at which byte, so you can
keep everything before it.

If the AOF cannot be written or synced to disk, commands that change data
are refused with a `MISCONF` error, and `INFO persistence` shows
`aof_last_write_status:err`. The writes it could not get are kept in memory
and written, whole, as soon as the disk takes them again (a partly written
command is cut off the file first), after which writes are accepted again
on their own; a `BGREWRITEAOF` also starts a new file that holds everything.
The server does not start if it cannot open the AOF, and
`CONFIG SET appendonly yes` fails then, rather than run without it.

## Moving from Redis

HotKV starts from Redis's data where Redis ran: point `dir` at Redis's data
directory. With no snapshot or AOF of its own there yet, HotKV reads
Redis's in their place, as Redis 2.8 to 8.10 write them, every type with
its TTLs, databases, stream groups, hash field TTLs and function
libraries:

- the snapshot, `dump.rdb`;
- with `appendonly yes`, the AOF: the `appendonlydir` directory of Redis 7
  and later (`appenddirname` names another) or the one `appendonly.aof`
  file of Redis 6.

Redis's files are left as they are, and HotKV writes its own beside them.
If your settings give HotKV Redis's file names (`dbfilename dump.rdb` or
`appendfilename appendonly.aof`, as a `redis.conf` does), HotKV first keeps
the Redis file as `dump.rdb.redis` (or `appendonly.aof.redis`), since Redis
cannot read HotKV's format: to go back to Redis, put it back under its
name. HotKV reads a `redis.conf`, including `bind 127.0.0.1 -::1` and the
other settings it shares with Redis, but a line it does not accept stops the
start and is named in the log: unknown directives, and `rename-command`,
`user`, `loadmodule`, `sentinel`, `replicaof` and `slaveof`. Remove those
lines, or add `ignore-unknown-directives yes` to start with them skipped. See
[Migrating from Redis](https://docs.hotkv.com/get-started/migrate-from-redis/index.md).

A Redis file that is damaged or cut short stops the start, as HotKV's own
would, and so does a key holding a module's value (JSON, search indexes,
vector sets), a type HotKV does not have: delete such keys in Redis first,
and take a new snapshot. Keys can also be moved one by one, from a running
Redis, with `MIGRATE` or `DUMP` and `RESTORE`.

## Encryption at rest

With the `encryption-at-rest` license feature, snapshots are encrypted as
they are written, so the plaintext never reaches the disk. The AOF is not
encrypted; see [Security](https://docs.hotkv.com/security/index.md#encryption-at-rest).

## Replication

Primary-replica streaming replication keeps a copy of your data on other
nodes. Outside cluster mode you set it up under `[replication]` in
`hotkv.toml` (`enabled`, `role`, `primary_addr`, and the same `password`
on the primary and its replicas, by default `requirepass`). HotKV Cloud
instances are single nodes. In cluster mode a replica takes over automatically when its primary
goes down; see [Clustering](https://docs.hotkv.com/clustering/index.md), and
[Cluster backup and restore](https://docs.hotkv.com/clustering/backup-and-restore/index.md) for what to
copy from each node and how to restore it. Without cluster mode you
promote a replica yourself with `REPLICAOF NO ONE` or `REPLICATION.FAILOVER`;
see the [command reference](https://docs.hotkv.com/commands/index.md) for the `REPLICATION.*`
commands. Writes are buffered and streamed in order, tracked by
replication offset so a reconnecting replica resumes without data loss,
and a replica that has fallen too far behind receives a full snapshot
instead.

## HotKV Cloud backups

On HotKV Cloud's Performance and Scale plans, every instance gets daily
automatic backups from the moment it is provisioned; Starter instances
have no backups. You can also create up to 5 manual backups from the
instance's Backups tab, for example before a migration or a risky schema
change. Backups are incremental: each one stores only what changed since
the previous one, and automatic and manual backups together count against
your plan's included backup storage. When that is full, delete a manual
backup or upgrade your plan before creating another. Backups are these
daily and manual copies of the whole instance, not point-in-time recovery.

Restoring is self-serve and in-place: your instance keeps its name,
endpoint, and password, only the data is replaced. As a safety check,
restoring asks for your account password and then emails a one-time
6-digit code to your account address before it starts. The instance is
briefly unavailable, typically 1-2 minutes, while the restore completes,
and any data written since that backup was taken is lost, so confirm you
have the right one before continuing.

## Next steps

- [Security](https://docs.hotkv.com/security/index.md)
- [Clustering](https://docs.hotkv.com/clustering/index.md)
- [Command reference](https://docs.hotkv.com/commands/index.md)