Skip to main content
PocketBase provides built-in backup and restore functionality to protect your data. Backups include the entire pb_data directory (excluding the backups folder itself) packaged as a zip archive.

Understanding backups

Backups in PocketBase:
  • Create a complete snapshot of your pb_data directory
  • Are executed within a database transaction (writes are temporarily blocked)
  • Include the database and all local storage files
  • Exclude the backups/, .pb_temp/, and autocert cache directories
  • Can be stored locally or on S3-compatible storage
If you use S3 storage for collection files, those files are not included in PocketBase backups. You must back up S3 separately using your cloud provider’s backup tools.

Storage requirements

To safely perform backups, ensure you have:
  • Free disk space: At least 2x the size of your pb_data directory
  • Sufficient I/O: Backups run in a transaction and temporarily block writes
Backup creation uses SQLite’s PRAGMA wal_checkpoint(TRUNCATE) to ensure database consistency.

Creating backups manually

Via admin UI

  1. Navigate to SettingsBackups in the admin dashboard
  2. Click Create backup
  3. Enter a backup name (optional, auto-generated if empty)
  4. Click Create
The backup will be created with a name like pb_backup_myapp_20240303120000.zip.

Via API

Create a backup programmatically using the API:
// Authenticate as superuser first
const authData = await pb.admins.authWithPassword(email, password);

// Create backup
await fetch('http://your-domain.com/api/backups', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${authData.token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'manual_backup_20240303.zip'
  })
});
Backup names must match the pattern: ^[a-z0-9_-]+\.zip$

Programmatically in Go

If you’re extending PocketBase with Go, you can create backups programmatically:
import (
    "context"
    "github.com/pocketbase/pocketbase/core"
)

// Create backup with auto-generated name
err := app.CreateBackup(context.Background(), "")
if err != nil {
    log.Fatal(err)
}

// Create backup with custom name
err = app.CreateBackup(context.Background(), "my_backup_20240303.zip")
if err != nil {
    log.Fatal(err)
}
The CreateBackup method from core/base_backup.go:44:
func (app *BaseApp) CreateBackup(ctx context.Context, name string) error
Key behaviors:
  • Blocks if another backup/restore is in progress (checked via StoreKeyActiveBackup)
  • Triggers OnBackupCreate hooks for customization
  • Auto-generates name if not provided
  • Runs in a transaction to ensure data consistency
  • Automatically excludes backup directory and temp files

Automated backups

Configure automatic backups using a cron expression:

Via admin UI

  1. Go to SettingsBackups
  2. Enter a cron expression (e.g., 0 2 * * * for daily at 2 AM)
  3. Set Max backups to keep (e.g., 7 for one week)
  4. Click Save

Cron expression format

PocketBase uses standard cron syntax:
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
* * * * *
Common examples:
ExpressionDescription
0 2 * * *Daily at 2:00 AM
0 */6 * * *Every 6 hours
0 0 * * 0Weekly on Sunday at midnight
0 3 1 * *Monthly on the 1st at 3:00 AM

Automatic cleanup

When cronMaxKeep is set, PocketBase automatically removes old backups:
// From core/base_backup.go:321-366
maxKeep := app.Settings().Backups.CronMaxKeep

if maxKeep == 0 {
    return // no explicit limit
}

// List auto-generated backups
files, err := fsys.List("@auto_pb_backup_")

// Sort by modification time (descending)
sort.Slice(files, func(i, j int) bool {
    return files[i].ModTime.After(files[j].ModTime)
})

// Keep only the most recent n backups
toRemove := files[maxKeep:]
Auto-generated backups are prefixed with @auto_pb_backup_ to distinguish them from manual backups.

S3 storage for backups

Store backups on S3-compatible storage for off-site redundancy:

Configuration

{
  "backups": {
    "cron": "0 2 * * *",
    "cronMaxKeep": 7,
    "s3": {
      "enabled": true,
      "bucket": "my-app-backups",
      "region": "us-east-1",
      "endpoint": "s3.amazonaws.com",
      "accessKey": "YOUR_ACCESS_KEY",
      "secret": "YOUR_SECRET_KEY",
      "forcePathStyle": false
    }
  }
}

S3-compatible providers

PocketBase works with any S3-compatible storage:
  • AWS S3: Standard S3 service
  • Backblaze B2: Set endpoint to s3.us-west-000.backblazeb2.com
  • DigitalOcean Spaces: Set endpoint to nyc3.digitaloceanspaces.com
  • MinIO: Self-hosted S3-compatible storage
  • Wasabi: Cost-effective cloud storage
Some providers require forcePathStyle: true for proper URL formatting.

Listing backups

Via admin UI

View all backups in SettingsBackups.

Via API

const backups = await fetch('http://your-domain.com/api/backups', {
  headers: {
    'Authorization': `Bearer ${authData.token}`
  }
}).then(r => r.json());

console.log(backups);
// [
//   {
//     "key": "pb_backup_myapp_20240303120000.zip",
//     "size": 1048576,
//     "modified": "2024-03-03 12:00:00.000Z"
//   }
// ]

Downloading backups

Via admin UI

  1. Go to SettingsBackups
  2. Click the download icon next to the backup
  3. Authorize with your superuser credentials

Via API

Backup downloads require a file token:
// Generate a file token
const token = authData.token; // Your superuser auth token

// Download backup
const downloadUrl = `http://your-domain.com/api/backups/${backupKey}?token=${token}`;
window.location.href = downloadUrl;

Restoring backups

Restore functionality is experimental and only works on Unix-based systems (Linux and macOS). Windows is not supported.

Prerequisites

  • Free disk space: At least 2x the backup size
  • Unix-based operating system
  • Superuser access

Restore process

The restore process (from core/base_backup.go:149-295):
1

Download and extract

PocketBase downloads the backup (from S3 if configured) and extracts it to a temporary directory inside pb_data/.pb_temp/.
2

Validate backup

Verifies that data.db exists in the extracted backup.
3

Move current data

Moves the current pb_data content (excluding backups and temp) to a temporary location: pb_data/.pb_temp/old_pb_data_*.
4

Move restored data

Moves the extracted backup content to the pb_data directory.
5

Restart application

Restarts the PocketBase process. On successful startup, old data is automatically deleted.

Via admin UI

  1. Go to SettingsBackups
  2. Click the restore icon next to the backup
  3. Confirm the restore operation
  4. PocketBase will restart automatically

Via API

await fetch(`http://your-domain.com/api/backups/${backupKey}/restore`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${authData.token}`
  }
});

// The server will restart after ~1 second

Programmatically in Go

import (
    "context"
    "time"
)

// Restore backup
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()

err := app.RestoreBackup(ctx, "backup_name.zip")
if err != nil {
    log.Fatal(err)
}
// App will restart automatically

Error recovery

If restore fails, PocketBase attempts to revert changes:
// From core/base_backup.go:268-282
if err := e.App.Restart(); err != nil {
    if revertErr := revertDataDirChanges(); revertErr != nil {
        panic(revertErr) // Cannot recover
    }
    return fmt.Errorf("failed to restart the app process: %w", err)
}
If the revert process fails, the application will panic. Always ensure you have external backups before attempting restoration.

Deleting backups

Via admin UI

  1. Go to SettingsBackups
  2. Click the delete icon
  3. Confirm deletion

Via API

await fetch(`http://your-domain.com/api/backups/${backupKey}`, {
  method: 'DELETE',
  headers: {
    'Authorization': `Bearer ${authData.token}`
  }
});
You cannot delete a backup that’s currently being created or restored.

Backup hooks

Customize backup behavior using hooks in your Go application:
app.OnBackupCreate().BindFunc(func(e *core.BackupEvent) error {
    // Before backup creation
    log.Println("Creating backup:", e.Name)
    
    // Exclude additional directories
    e.Exclude = append(e.Exclude, "custom_temp")
    
    // Continue with backup
    return e.Next()
})

app.OnBackupRestore().BindFunc(func(e *core.BackupEvent) error {
    // Before backup restoration
    log.Println("Restoring backup:", e.Name)
    
    // Add custom validation
    if e.Name == "protected_backup.zip" {
        return errors.New("this backup is protected")
    }
    
    return e.Next()
})

Best practices

Schedule quarterly restore tests to verify backup integrity:
  1. Download a recent backup
  2. Restore to a test environment
  3. Verify data completeness
  4. Test critical application functions
  5. Document any issues
Maintain multiple backup copies:
  • 3 total copies of your data
  • 2 different storage types (e.g., local + S3)
  • 1 off-site copy
Track backup metrics:
const backups = await pb.collection('_backups').getList();
const latest = backups.items[0];

console.log(`Latest backup: ${latest.size / 1024 / 1024}MB`);
Alert on anomalies like sudden size increases or long backup times.
  • Store S3 credentials securely (use environment variables)
  • Enable S3 bucket versioning for additional protection
  • Restrict backup API access to superusers only
  • Encrypt backups at rest and in transit
Document your recovery procedures:
  1. Where backups are stored
  2. How to access backups during an outage
  3. Step-by-step restoration process
  4. Contact information for team members
  5. Estimated recovery time objective (RTO)

Troubleshooting

Backup creation fails

Error: “Try again later - another backup/restore process has already been started” Solution: Wait for the current backup/restore to complete, or restart PocketBase if the process is stuck.

Insufficient disk space

Error: “Failed to create backup” with I/O errors Solution: Free up disk space. You need at least 2x your pb_data directory size.

S3 connection errors

Error: “Failed to load backups filesystem” Solutions:
  • Verify S3 credentials are correct
  • Check bucket name and region
  • Ensure forcePathStyle matches your provider’s requirements
  • Verify network connectivity to S3 endpoint

Restore fails on Windows

Error: “Restore is not supported on Windows” Solution: Restore manually:
  1. Stop PocketBase
  2. Extract backup zip
  3. Replace pb_data contents
  4. Start PocketBase

Next steps

Going to production

Learn production deployment best practices

Migrations

Manage database schema changes