Storage Backends
Store snapshots locally, on S3, Cloudflare R2, or any S3-compatible service. All backends receive only encrypted data โ zero-knowledge by design.
Local Storage (Default)
By default, snapshots are stored at ~/.savestate/snapshots/. No configuration needed.
Config
// .savestate/config.json
{
"storage": {
"type": "local",
"options": {
"path": "~/.savestate"
}
}
}
You can change the storage path to any directory:
// Store in Dropbox for automatic sync
{
"storage": {
"type": "local",
"options": {
"path": "~/Dropbox/savestate-backups"
}
}
}
Amazon S3
Store snapshots in an S3 bucket. Uses AWS Signature V4 authentication with zero external dependencies โ SaveState implements the signing from scratch using native crypto.
Config
// .savestate/config.json
{
"storage": {
"type": "s3",
"options": {
"bucket": "my-savestate-backups",
"endpoint": "https://s3.us-east-1.amazonaws.com",
"region": "us-east-1",
"accessKeyId": "AKIA...",
"secretAccessKey": "wJa...",
"prefix": "snapshots/"
}
}
}
Options
| Option | Required | Description |
|---|---|---|
bucket | Yes | S3 bucket name |
endpoint | Yes | S3 endpoint URL |
region | No | AWS region (default: us-east-1) |
accessKeyId | No* | AWS access key ID |
secretAccessKey | No* | AWS secret access key |
prefix | No | Key prefix for all objects (e.g., snapshots/) |
timeoutMs | No | Request timeout in ms (default: 30000) |
maxRetries | No | Max retries on 5xx errors (default: 3) |
* Credentials can also be provided via AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.
Cloudflare R2
Cloudflare R2 is S3-compatible with zero egress fees โ a great fit for backups. SaveState has been tested with R2.
Config
// .savestate/config.json
{
"storage": {
"type": "r2",
"options": {
"bucket": "savestate",
"endpoint": "https://<account-id>.r2.cloudflarestorage.com",
"region": "auto",
"accessKeyId": "<R2 access key ID>",
"secretAccessKey": "<R2 secret access key>",
"prefix": "backups/"
}
}
}
Setting up R2
- Go to your Cloudflare dashboard โ R2 โ Create bucket
- Create an API token: R2 โ Manage R2 API Tokens โ Create API Token
- Select "Object Read & Write" permissions for your bucket
- Copy the Access Key ID, Secret Access Key, and your Account ID
- The endpoint is:
https://<account-id>.r2.cloudflarestorage.com
"auto".
Backblaze B2
Backblaze B2 is also S3-compatible. Use the s3 or b2 storage type with your B2 S3-compatible endpoint.
{
"storage": {
"type": "b2",
"options": {
"bucket": "my-savestate",
"endpoint": "https://s3.us-west-004.backblazeb2.com",
"region": "us-west-004",
"accessKeyId": "<B2 key ID>",
"secretAccessKey": "<B2 application key>"
}
}
}
Sync Folder Storage
For quick cloud backup without setting up S3, just point local storage at a synced folder:
// Dropbox
{ "storage": { "type": "local", "options": { "path": "~/Dropbox/savestate" } } }
// iCloud Drive
{ "storage": { "type": "local", "options": { "path": "~/Library/Mobile Documents/com~apple~CloudDocs/savestate" } } }
// Google Drive
{ "storage": { "type": "local", "options": { "path": "~/Google Drive/savestate" } } }
Implementation Details
All storage backends implement the same interface:
interface StorageBackend {
readonly id: string;
put(key: string, data: Buffer): Promise<void>;
get(key: string): Promise<Buffer>;
list(prefix?: string): Promise<string[]>;
delete(key: string): Promise<void>;
exists(key: string): Promise<boolean>;
}
The S3 backend uses path-style access and implements AWS Signature V4 from scratch with Node.js native crypto โ zero external dependencies. It handles retries with exponential backoff on 5xx errors and 429 rate limits.