AI Infrastructure·8 min read·

Back Up Vector Databases and Model Configs

Snapshot vector indexes, prompt packs, and router YAML on a Lucknow VPS, skip re-downloadable weights, and rehearse a restore before the disk fills.

NB

Netbay Engineering

Netbay Engineering

On this page

An LLM app has two kinds of state people forget to back up. The first is model config: which model name is cheap, which is local, system prompts, tool allowlists, eval gold.jsonl. The second is the vector index or embedding store you built from product text. Weights you can re-download are not state. A 7B file you still have on the original URL is a cache. Losing the router YAML and the index is how you spend a week reconstructing a product that "just worked".

This is not a chunking tutorial. Assume the index already exists on disk or in a local engine. The job is to copy it consistently, encrypt it, get it off the box, and prove a restore. Netbay is a Lucknow VPS with High-Speed SSD, Intel Xeon Platinum, and L3/L4 DDoS filtering. There is no managed object store as a platform feature. Use restic or rclone to a destination you control, or copy to a second machine you pay for.

What to copy, what to skip

Copy:

  • /etc/ai-app.env is secrets. Back it up encrypted, separately, or restore it by hand from a password manager. Do not drop it into an unencrypted tarball next to the index.
  • /srv/ai-app/config: router.json, prompt pack, tool schemas, nginx snippets you customized.
  • /srv/ai-app/eval/gold.jsonl and the last score log.
  • Vector store files: a Qdrant storage directory, a Chroma folder, sqlite-vec, pgvector dumps, whatever you actually run. One tree.
  • Redis RDB only if you insist job history matters. Prefer empty queues at backup time.

Skip:

  • Weight files that you can fetch again. Record the URL, the hash, and the local path in config instead.
  • node_modules and Python venvs. Reinstall from a lockfile.
  • Vendor transcript caches full of PII unless you have a retention policy that says keep them.
bash
sudo mkdir -p /var/backups/ai-app
sudo -u aiapp test -d /srv/ai-app/config
install -d -o aiapp -g aiapp /var/backups/ai-app
TS=$(date -u +%Y%m%dT%H%M%SZ)
tar -C /srv/ai-app -czf /var/backups/ai-app/config.$TS.tgz config eval
tar -C /srv/vectors -czf /var/backups/ai-app/vectors.$TS.tgz store
sha256sum /var/backups/ai-app/config.$TS.tgz /var/backups/ai-app/vectors.$TS.tgz | sudo tee /var/backups/ai-app/SHA256.$TS

Take the vector snapshot after you stop writes or use the engine's snapshot API. A torn index is worse than an old one. For sqlite, copy with the engine's backup API, not cp on a live file. For a directory-based store, stop the writer unit for a few seconds or snapshot a consistent export.

Automate and get a copy off the VPS

A local tarball on the same High-Speed SSD is not a backup. The disk that dies still has your only copy. Push to another host or to a restic repository you own. Encrypt. Keep 7 daily and 4 weekly until you know better.

bash
#!/bin/sh
set -eu
TS=$(date -u +%Y%m%dT%H%M%SZ)
DEST=/var/backups/ai-app
tar -C /srv/ai-app -czf $DEST/config.$TS.tgz config eval
systemctl stop ai-embed.service || true
tar -C /srv/vectors -czf $DEST/vectors.$TS.tgz store
systemctl start ai-embed.service || true
sha256sum $DEST/config.$TS.tgz $DEST/vectors.$TS.tgz > $DEST/SHA256.$TS
restic backup --tag ai-app $DEST/config.$TS.tgz $DEST/vectors.$TS.tgz $DEST/SHA256.$TS
find $DEST -type f -mtime +7 -delete

Run that from a systemd timer as root or as a backup user that can stop ai-embed. EnvironmentFile for RESTIC_PASSWORD must not be world-readable. Do not print the password. Do not backup /etc/ai-app.env in the same unencrypted tar.

If you use pgvector, pg_dump the database instead of tarring PGDATA. If you use a local Qdrant, prefer its snapshot endpoint, then tar the snapshot file. The pattern is the same: consistent export, hash, off-box, retention.

Restore is the only test

Pick a directory, unpack, point a staging unit at it, run the eval, and run one retrieval query you know the answer to. If the index restores but the prompt pack is from a different week, the product is still wrong. Version the config and the index together in the same $TS name.

bash
mkdir -p /tmp/ai-restore
tar -C /tmp/ai-restore -xzf /var/backups/ai-app/config.LATEST.tgz
tar -C /tmp/ai-restore -xzf /var/backups/ai-app/vectors.LATEST.tgz
python3 /srv/ai-app/eval/run.py --prompts /tmp/ai-restore/eval/gold.jsonl
python3 /srv/ai-app/tools/query_index.py --root /tmp/ai-restore/store --q 'refund window'

Replace LATEST with the real timestamp. Keep a written runbook: stop app, restore config, restore index, restore env from the password manager, start local model if needed, start app, hit /health, run eval. Time it once. That duration is your RTO.

Do not restore weights from backup if a download is faster and the hash matches config. Do restore the hash file so you can prove the weights you downloaded are the ones production used.

Config and indexes are state, weights are a cache router + prompts gold.jsonl vector store consistent export sha256 + tar same timestamp restic off-box encrypted Skip re-downloadable GGUF weights Secrets restore from a password manager RTO is the timed restore plus eval, not the tar command Lucknow VPS · High-Speed SSD local copy is not off-box

The takeaway: back up config plus index plus an encrypted secret path, skip re-downloadable weights, and rehearse unpack plus eval on the same Lucknow box you will have to recover.

You can spin up an Ubuntu 24.04 instance on Netbay in under 60 seconds and follow along — netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance