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_preference parameter 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

  1. Photo Backup: Backup photos to cloud, never delete from cloud even if deleted locally

  2. Document Archive: Archive important documents without risk of accidental deletion

  3. 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

  1. Cloud Download: Download files from cloud to local (cloud is master)

  2. Shared Folders: Receive updates from shared team folder

  3. 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

  1. Cloud Backup: Backup cloud data locally, keep deleted files

  2. Disaster Recovery: Maintain local copy of critical remote data

  3. 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_DESTINATION

  • Production → Local dev: DESTINATION_TO_SOURCE

  • Local ↔ Remote dev: TWO_WAY

Backup Scenarios

  • Local → Cloud backup (never delete): SOURCE_BACKUP

  • Cloud → Local backup (never delete): DESTINATION_BACKUP

  • Mirror backup: SOURCE_TO_DESTINATION or DESTINATION_TO_SOURCE

Content Management

  • Master → Distribution: SOURCE_TO_DESTINATION

  • Team shared folder: TWO_WAY

  • Content 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