Persistence & KV
Each app owns a private volume at $DATA_DIR (/data). It survives redeploys, is quota'd, backed up nightly, and removed when the app is deleted.
Where should my app store data?
Anywhere under /data — a plain SQLite file works great with Node 22's built-in node:sqlite:
const { DatabaseSync } = require("node:sqlite");
const db = new DatabaseSync(process.env.DATA_DIR + "/app.sqlite");
The built-in key-value store
Vendor packages/app-kit/dist/index.js into your app as kv.js:
import { openKV } from "./kv.js";
const kv = openKV(); // or { namespace: "sessions" }
kv.put("greeting", "hi");
kv.get("greeting"); // "hi"
kv.putJSON("cfg", { theme: "dark" });
kv.getJSON("cfg"); // { theme: "dark" }
kv.list("user:"); // prefix scan, sorted
kv.delete("greeting");
It's SQLite underneath (/data/kv.sqlite) — no server, no credentials, isolated per app because volumes are isolated per app.
What are the limits?
- 256 MiB per app by default. A deploy over quota is refused with a clear error, and a background watchdog stops apps that blow past it at runtime.
- Data is deleted with the app (
smallcloud delete) — deletion means deletion.
Backups
Smallcloud backs up the control-plane database and every app volume daily, keeping seven days (smallcloud backup runs one on demand). Restore with node scripts/restore.mjs <date> --yes. See the security model for the full operational picture.