13 KiB
13 KiB
Backup & Upload
This document describes the photo/video backup functionality, including foreground and background uploads.
Backup Overview
The backup system automatically uploads photos and videos from the device to the server:
┌─────────────────────────────────────────────────────────────┐
│ Backup Flow │
├─────────────────────────────────────────────────────────────┤
│ Device Photos → Backup Service → Server │
│ │
│ 1. Select albums to backup │
│ 2. Find new/changed assets │
│ 3. Check for duplicates (hash) │
│ 4. Upload assets │
│ 5. Update local database │
└─────────────────────────────────────────────────────────────┘
Backup Configuration
Backup Controller Screen
┌─────────────────────────────────────────────────────────────┐
│ ← Backup │
├─────────────────────────────────────────────────────────────┤
│ Backup Status │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ✓ Backup Complete │ │
│ │ 1,234 of 1,234 backed up │ │
│ │ Last backup: 2 hours ago │ │
│ └─────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Backup Albums │
│ [Select albums to backup] │
├─────────────────────────────────────────────────────────────┤
│ Excluded Albums │
│ [Select albums to exclude] │
├─────────────────────────────────────────────────────────────┤
│ Settings │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Background Backup [Toggle: ON] │ │
│ │ Use Wi-Fi only [Toggle: ON] │ │
│ │ Require charging [Toggle: OFF] │ │
│ │ Ignore iCloud assets [Toggle: OFF] │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Album Selection
Backup Albums
- Select which device albums to back up
- "Recents" includes all photos
- Individual albums for selective backup
Excluded Albums
- Exclude specific albums
- Useful for Screenshots, WhatsApp Images, etc.
- Takes precedence over selected albums
Album Selection Logic
Backup Candidates = Selected Albums - Excluded Albums
If "Recents" selected (Android):
- Back up all device photos
- Individual album folders tracked for sync
If "Recents" selected (iOS):
- Use "All Photos" album
- Check against excluded albums per asset
Backup Process
Step 1: Build Upload Candidates
1. Get selected backup albums
2. Get excluded backup albums
3. For each selected album:
a. Check if album modified since last backup
b. Get assets newer than last backup time
c. Add album name to asset metadata
4. Remove assets from excluded albums
Step 2: Remove Already Uploaded
1. Check local duplicates database
2. Call server to check existing assets
POST /assets/exist
Body:
{
"deviceAssetIds": ["local-id-1", "local-id-2", ...],
"deviceId": "device-uuid"
}
Response:
{
"existingIds": ["local-id-1"]
}
Step 3: Upload Assets
For each asset:
1. Get original file from device
2. If live photo, also get video component
3. Calculate upload metadata
4. Upload via multipart form
POST /assets
Content-Type: multipart/form-data
Fields:
- deviceAssetId: local ID
- deviceId: device UUID
- fileCreatedAt: creation timestamp
- fileModifiedAt: modification timestamp
- isFavorite: boolean
- duration: video duration
Files:
- assetData: the file
- livePhotoData: motion video (if applicable)
Step 4: Handle Response
200 OK: Asset already exists (duplicate)
201 Created: Asset uploaded successfully
Response:
{
"id": "remote-asset-uuid",
"deviceAssetId": "local-id",
...
}
Upload Progress Tracking
Progress Model
CurrentUploadAsset {
id: String // Local asset ID
fileName: String // File name
fileType: String // IMAGE, VIDEO, etc.
fileSize: Integer // Bytes
fileCreatedAt: DateTime
iCloudAsset: Boolean // Downloading from iCloud
}
UploadProgress {
bytesUploaded: Integer
totalBytes: Integer
percentage: Double
}
Progress UI
┌─────────────────────────────────────────────────────────────┐
│ Uploading... │
│ │
│ IMG_1234.jpg │
│ [████████████░░░░░░░░░░░░░░░░░] 45% │
│ │
│ 12 of 50 • 2.4 MB / 5.1 MB │
└─────────────────────────────────────────────────────────────┘
Background Backup
Platform Differences
Android:
- Uses WorkManager for scheduling
- Triggers on content changes
- Requires battery optimization disabled
iOS:
- Uses Background App Refresh
- Limited execution time
- BGProcessingTask for longer uploads
Background Service Configuration
RequireUnmetered: true/false // Wi-Fi only
RequireCharging: true/false // Charging only
TriggerDelay: 5000ms // Minimum delay
MaxDelay: 50000ms // Maximum delay
Background Notification
┌─────────────────────────────────────────────────────────────┐
│ Immich │
│ Uploading 12/50 photos... │
│ [Progress bar] │
└─────────────────────────────────────────────────────────────┘
Background Process Flow
1. System triggers background task
2. Acquire lock (prevent concurrent runs)
3. Load translations
4. Initialize database
5. Set API endpoint
6. Get selected/excluded albums
7. Run backup process
8. Update last backup timestamps
9. Release lock
iCloud Assets (iOS)
Handling iCloud Photos
- Check if asset is locally available
- If not, option to download from iCloud
- Show progress during download
- Upload after download complete
Settings
ignoreIcloudAssets: Skip assets not on device
Album Sync Feature
Purpose
Automatically organize uploads into server albums matching device album names.
How It Works
- Asset uploaded with album names in metadata
- After upload, check for matching albums
- Create album if doesn't exist
- Add asset to album
API
POST /albums/{albumName}/assets
Body:
{
"assetIds": ["uploaded-asset-id"]
}
Duplicate Detection
Hash-Based Detection
- Calculate file hash (checksum)
- Store in local duplicates database
- Skip uploads for known duplicates
Server-Side Check
POST /assets/exist
Checks if assets already on server by device ID + local ID
Error Handling
Retry Logic
- Failed uploads retry automatically
- Exponential backoff
- Maximum retry attempts
Error Notifications
┌─────────────────────────────────────────────────────────────┐
│ ⚠️ Upload Failed │
│ IMG_5678.jpg could not be uploaded │
│ Error: Network connection lost │
└─────────────────────────────────────────────────────────────┘
Common Errors
| Error | Cause | Action |
|---|---|---|
| Network error | No connection | Retry when online |
| Quota exceeded | Storage full | Stop backup, notify user |
| File not found | Asset deleted | Skip asset |
| Permission denied | Gallery access lost | Request permission |
Failed Uploads Screen
Layout
┌─────────────────────────────────────────────────────────────┐
│ ← Failed Uploads │
├─────────────────────────────────────────────────────────────┤
│ 5 uploads failed │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 📷 IMG_1234.jpg │ │
│ │ Network timeout │ │
│ │ [Retry] │ │
│ └─────────────────────────────────────────────────────┘ │
│ ... │
├─────────────────────────────────────────────────────────────┤
│ [Retry All] │
└─────────────────────────────────────────────────────────────┘
Backup Statistics
Tracked Metrics
- Total assets to backup
- Successfully uploaded
- Failed uploads
- Duplicate (already on server)
- Last backup timestamp
Storage Usage
GET /users/me
Response includes:
{
"quotaUsageInBytes": 1234567890,
"quotaSizeInBytes": 10737418240
}
Cellular Data Settings
Options
useCellularForUploadPhotos: Allow photo upload on cellularuseCellularForUploadVideos: Allow video upload on cellular