Sync Modes Reference
SyncEngine supports five different synchronization modes, each designed for specific use cases. This page provides detailed information about each mode.
Quick Comparison
Mode |
Use Case |
Upload |
Download |
Delete Behavior |
|---|---|---|---|---|
TWO_WAY |
Keep both sides in sync |
Yes |
Yes |
Both directions |
SOURCE_TO_DESTINATION |
Mirror source to dest |
Yes |
No |
Dest only |
SOURCE_BACKUP |
Backup without deletes |
Yes |
No |
Never delete source |
DESTINATION_TO_SOURCE |
Mirror dest to source |
No |
Yes |
Source only |
DESTINATION_BACKUP |
Download without deletes |
No |
Yes |
Never delete dest |
TWO_WAY Mode
Use case: Bidirectional synchronization where both sides should be kept in sync.
Behavior
Uploads: New/modified source files are uploaded to destination
Downloads: New/modified destination files are downloaded to source
Source deletions: Propagated to destination
Destination deletions: Propagated to source
Renames/moves: Applied to both sides
Conflicts: Detected and resolved based on conflict resolution strategy
Example
from syncengine import SyncEngine, SyncMode, SyncPair
pair = SyncPair(
source_root="/home/user/documents",
destination_root="/cloud/documents",
source_client=local_client,
destination_client=cloud_client,
mode=SyncMode.TWO_WAY
)
stats = engine.sync_pair(pair)
Scenarios
Change |
Action |
|---|---|
Add file at source |
Upload to destination |
Add file at destination |
Download to source |
Modify file at source |
Upload to destination |
Modify file at destination |
Download to source |
Modify file at both sides |
Conflict (resolve based on strategy) |
Delete file at source |
Delete at destination |
Delete file at destination |
Delete at source |
Rename file at source |
Rename at destination |
Rename file at destination |
Rename at source |
Best Practices
Use with conflict resolution strategy (NEWEST_WINS, SOURCE_WINS, DESTINATION_WINS)
Enable state management for efficient incremental syncs
Monitor for conflicts and have a resolution plan
Consider using ignore patterns for temporary files
Initial Sync Behavior
Important: The first time you sync with TWO_WAY mode (when no previous sync state exists), you must decide how to handle files that exist on only one side.
The Problem
On first sync, the sync engine cannot distinguish between:
“File was deleted locally” (should delete from destination)
“File was added remotely” (should download to local)
This ambiguity can lead to unexpected data loss if not handled carefully.
Initial Sync Preferences
Use the initial_sync_preference parameter to control first-sync behavior:
from syncengine import SyncEngine, SyncMode, SyncPair, InitialSyncPreference
pair = SyncPair(
source=Path("/local/folder"),
destination="/cloud/folder",
sync_mode=SyncMode.TWO_WAY
)
# Option 1: MERGE (default - safest)
# Merges both sides without deletions
stats = engine.sync_pair(
pair,
initial_sync_preference=InitialSyncPreference.MERGE
)
# Result: Downloads destination files, uploads source files, NO deletions
# Option 2: SOURCE_WINS
# Source is authoritative, destination extras deleted
stats = engine.sync_pair(
pair,
initial_sync_preference=InitialSyncPreference.SOURCE_WINS
)
# Result: Uploads source files, DELETES destination-only files
# Option 3: DESTINATION_WINS
# Destination is authoritative, source extras deleted
stats = engine.sync_pair(
pair,
initial_sync_preference=InitialSyncPreference.DESTINATION_WINS
)
# Result: Downloads destination files, DELETES source-only files
Default Behavior: If not specified, MERGE is used for safety (no data loss).
Common Scenarios
Vault Restoration (destination is master):
# Restore from cloud vault to empty local folder
stats = engine.sync_pair(
pair,
initial_sync_preference=InitialSyncPreference.DESTINATION_WINS
)
# Downloads all vault files to local
First-Time Backup (source is master):
# First backup of local files to empty cloud
stats = engine.sync_pair(
pair,
initial_sync_preference=InitialSyncPreference.SOURCE_WINS
)
# Uploads all local files to cloud
Merging Two Directories:
# Merge local and cloud files without losing anything
stats = engine.sync_pair(
pair,
initial_sync_preference=InitialSyncPreference.MERGE # or omit (default)
)
# Downloads cloud files, uploads local files, NO deletions
Risk Warnings
If you don’t explicitly set a preference, the sync engine will detect risky patterns and warn you:
⚠ WARNING: Destination has 100 files but source has only 5.
Initial TWO_WAY sync will default to MERGE mode (no deletions).
To make destination authoritative and delete source-only files:
initial_sync_preference=InitialSyncPreference.DESTINATION_WINS
After First Sync
After the first successful sync, normal TWO_WAY behavior applies:
New files on either side are copied to the other
Deletions on either side are propagated to the other
Modifications are synced bidirectionally
The
initial_sync_preferenceparameter has no effect
SOURCE_TO_DESTINATION Mode
Use case: One-way mirror from source to destination. Source is the authoritative copy.
Behavior
Uploads: New/modified source files are uploaded to destination
Downloads: Never downloads (destination changes ignored)
Source deletions: Propagated to destination
Destination deletions: Ignored (files re-uploaded from source)
Renames/moves: Applied to destination only
Conflicts: Cannot occur (source always wins)
Example
from syncengine import SyncMode, SyncPair
pair = SyncPair(
source_root="/home/user/website",
destination_root="/var/www/html",
source_client=local_client,
destination_client=remote_client,
mode=SyncMode.SOURCE_TO_DESTINATION
)
stats = engine.sync_pair(pair)
Scenarios
Change |
Action |
|---|---|
Add file at source |
Upload to destination |
Add file at destination |
Delete at destination (not in source) |
Modify file at source |
Upload to destination |
Modify file at destination |
Overwrite with source version |
Delete file at source |
Delete at destination |
Delete file at destination |
Re-upload from source |
Rename file at source |
Rename at destination (old file deleted) |
Best Practices
Use for deployment scenarios (dev → prod)
Use for distributing files to multiple locations
Ensure source is always the authoritative version
Be careful with deletions (propagated to destination)
SOURCE_BACKUP Mode
Use case: Backup source to destination without ever deleting from source. Upload-only backup.
Behavior
Uploads: New/modified source files are uploaded to destination
Downloads: Downloads destination changes to source
Source deletions: NOT propagated to destination (backup preserved)
Destination deletions: Ignored (files re-uploaded from source)
Renames/moves: Applied to destination
Conflicts: Source modifications win
Example
from syncengine import SyncMode, SyncPair
pair = SyncPair(
source_root="/home/user/photos",
destination_root="/backup/photos",
source_client=local_client,
destination_client=backup_client,
mode=SyncMode.SOURCE_BACKUP
)
stats = engine.sync_pair(pair)
Scenarios
Change |
Action |
|---|---|
Add file at source |
Upload to destination |
Add file at destination |
Download to source |
Modify file at source |
Upload to destination |
Modify file at destination |
Download to source |
Delete file at source |
NO ACTION (backup preserved) |
Delete file at destination |
Re-upload from source |
Rename file at source |
Rename at destination (old backup kept) |
Best Practices
Use for important data you never want to lose
Great for photo/document backups
Destination grows over time (deleted files remain)
Periodically clean destination manually if needed
Consider implementing versioning on destination
Use Cases
Photo Backup: Backup photos to cloud, never delete from cloud even if deleted locally
Document Archive: Archive important documents without risk of accidental deletion
Code History: Keep all versions of code files even if deleted from working directory
DESTINATION_TO_SOURCE Mode
Use case: One-way mirror from destination to source. Destination is the authoritative copy.
Behavior
Uploads: Never uploads (source changes ignored)
Downloads: New/modified destination files are downloaded to source
Source deletions: Ignored (files re-downloaded from destination)
Destination deletions: Propagated to source
Renames/moves: Applied to source only
Conflicts: Cannot occur (destination always wins)
Example
from syncengine import SyncMode, SyncPair
pair = SyncPair(
source_root="/home/user/downloads",
destination_root="/cloud/shared_files",
source_client=local_client,
destination_client=cloud_client,
mode=SyncMode.DESTINATION_TO_SOURCE
)
stats = engine.sync_pair(pair)
Scenarios
Change |
Action |
|---|---|
Add file at source |
Delete at source (not in destination) |
Add file at destination |
Download to source |
Modify file at source |
Overwrite with destination version |
Modify file at destination |
Download to source |
Delete file at source |
Re-download from destination |
Delete file at destination |
Delete at source |
Rename file at destination |
Rename at source (old file deleted) |
Best Practices
Use for downloading content from authoritative remote source
Use for receiving shared files from cloud
Ensure destination is always the authoritative version
Be careful with deletions (propagated to source)
Use Cases
Cloud Download: Download files from cloud to local (cloud is master)
Shared Folders: Receive updates from shared team folder
Content Distribution: Download content from master repository
DESTINATION_BACKUP Mode
Use case: Backup destination to source without ever deleting from destination. Download-only backup.
Behavior
Uploads: Never uploads (source changes ignored)
Downloads: New/modified destination files are downloaded to source
Source deletions: Ignored (files re-downloaded from destination)
Destination deletions: NOT propagated to source (backup preserved)
Renames/moves: Applied to source
Conflicts: Destination modifications win
Example
from syncengine import SyncMode, SyncPair
pair = SyncPair(
source_root="/home/user/backup",
destination_root="/cloud/important_data",
source_client=local_client,
destination_client=cloud_client,
mode=SyncMode.DESTINATION_BACKUP
)
stats = engine.sync_pair(pair)
Scenarios
Change |
Action |
|---|---|
Add file at source |
NO ACTION (ignored) |
Add file at destination |
Download to source |
Modify file at source |
Overwrite with destination version |
Modify file at destination |
Download to source |
Delete file at source |
Re-download from destination |
Delete file at destination |
NO ACTION (backup preserved) |
Rename file at destination |
Rename at source (old backup kept) |
Best Practices
Use for backing up remote data locally
Great for disaster recovery scenarios
Source grows over time (deleted remote files remain)
Periodically clean source manually if needed
Consider implementing versioning on source
Use Cases
Cloud Backup: Backup cloud data locally, keep deleted files
Disaster Recovery: Maintain local copy of critical remote data
Archive: Download and preserve historical data from remote source
Choosing the Right Mode
Decision Tree
Do you need bidirectional sync?
├─ Yes → TWO_WAY
└─ No → Do you need to upload or download?
├─ Upload → Do you want to delete from destination?
│ ├─ Yes → SOURCE_TO_DESTINATION
│ └─ No → SOURCE_BACKUP
└─ Download → Do you want to delete from source?
├─ Yes → DESTINATION_TO_SOURCE
└─ No → DESTINATION_BACKUP
Common Scenarios
Development Workflow
Local dev → Production server:
SOURCE_TO_DESTINATIONProduction → Local dev:
DESTINATION_TO_SOURCELocal ↔ Remote dev:
TWO_WAY
Backup Scenarios
Local → Cloud backup (never delete):
SOURCE_BACKUPCloud → Local backup (never delete):
DESTINATION_BACKUPMirror backup:
SOURCE_TO_DESTINATIONorDESTINATION_TO_SOURCE
Content Management
Master → Distribution:
SOURCE_TO_DESTINATIONTeam shared folder:
TWO_WAYContent download:
DESTINATION_TO_SOURCE
Mode Properties
You can check mode properties programmatically:
from syncengine import SyncMode
mode = SyncMode.TWO_WAY
# Check capabilities
print(f"Allows upload: {mode.allows_upload}")
print(f"Allows download: {mode.allows_download}")
print(f"Allows source delete: {mode.allows_source_delete}")
print(f"Allows dest delete: {mode.allows_destination_delete}")
print(f"Is bidirectional: {mode.is_bidirectional}")
# Check scan requirements
print(f"Requires source scan: {mode.requires_source_scan}")
print(f"Requires dest scan: {mode.requires_destination_scan}")
Mode Aliases
SyncEngine supports friendly aliases for modes:
from syncengine import SyncMode
# These are equivalent:
mode = SyncMode.from_string("twoWay")
mode = SyncMode.from_string("tw")
mode = SyncMode.from_string("sourceToDestination")
mode = SyncMode.from_string("std")
mode = SyncMode.from_string("localtocloud")
mode = SyncMode.from_string("destinationToSource")
mode = SyncMode.from_string("dts")
mode = SyncMode.from_string("cloudtolocal")
mode = SyncMode.from_string("sourceBackup")
mode = SyncMode.from_string("sb")
mode = SyncMode.from_string("localbackup")
mode = SyncMode.from_string("destinationBackup")
mode = SyncMode.from_string("db")
mode = SyncMode.from_string("cloudbackup")
Next Steps
Core Concepts - Deep dive into state management and conflict resolution
Examples - Example code for each mode
API Reference - Complete API documentation