FastSync is a high-performance file synchronization tool designed for mirroring folders, sharing files over the network, and ensuring safe file transfers. It provides clear progress tracking, secure overwrite behavior, and fast metadata-aware comparisons to optimize sync operations.
Key Features:
Extreme Performance: Built with Rust for native execution speed and efficient resource use.
Network Sync: Share folders securely with a 6-digit code or connect to receive files from others.
Progress Tracking: Detailed terminal progress and JSON output for script integration.
Safe Overwrite: Avoids partial file corruption with temporary-file writes.
Language Support: Available in English and Simplified Chinese, with automatic locale detection.
Audience & Benefit:
Ideal for developers, IT professionals, and teams needing fast, reliable folder synchronization. FastSync ensures efficient syncing of large folders, safe one-time network transfers, and clear visibility into sync operations.
README
⚡ FastSync
Fast folder sync, written in Rust.
Mirror a source folder into a target folder, or share a folder once over the network, with speed, clear previews, and safer overwrite behavior.
flowchart LR
A["Source folder"] --> B["Scan"]
C["Target folder"] --> B
B --> D["Compare"]
D --> E["Copy / update"]
D --> F["Optional delete"]
E --> G["Readable summary"]
F --> G
🏎️ Extreme Performance
Directory sync is a mix of filesystem latency, metadata checks, hashing, and copying. FastSync keeps those stages explicit and controlled.
Performance design
How it helps
Rust implementation
Native binary performance with predictable memory and CPU behavior.
Metadata-aware comparison
Uses file size and modified time where they are valid content signals, while metadata synchronization stays separately configurable.
BLAKE3 hashing
Uses a very fast modern hash for strong content comparison when needed.
Bounded worker queue
Keeps copying concurrent without letting memory usage grow without control.
Direct new-file copy
Files missing from the target are copied directly, avoiding unnecessary temporary rename overhead.
> [!NOTE]
> Fast comparison is the default. Use --strict when same-metadata files should still be confirmed with BLAKE3.
Interactive text runs show a bottom progress indicator; scripted and JSON runs
stay clean. See Progress And Logs.
Example: safe backup mirror
# First run: inspect what would happen.
fastsync -n -d ~/Photos /mnt/backup/Photos
# Second run: apply the same operation.
fastsync -d ~/Photos /mnt/backup/Photos
Example: fast cache mirror
fastsync ./target/release ./cache/release
The default fast mode trusts matching metadata, then hashes only when same-size files have differing modified times or supported permissions.
🎯 Sync Only What Matters
Real project folders often contain caches, logs, local notes, or generated files. FastSync can read a small rule file to decide what should participate in sync:
Option
Use it for
-x, --exclude-from
Blacklist mode: matching files or directories are left alone.
-i, --include-from
Whitelist mode: only matching files or directories are synced.
Rule files use one rule per line. Empty lines and lines starting with # are ignored. A typical blacklist might look like this:
# Skip build output and local caches
target/
cache/
*.tmp
logs/**/*.log
Whitelist mode is handy when you only want to publish or copy a known slice of a folder:
dist/
README.md
docs/**/*.md
fastsync ./project ./release -i sync-list.txt
Filtered-out paths are protected. FastSync will not copy, overwrite, verify, update metadata, or delete them, even when --delete is enabled. In other words: excluded local caches stay in place, and files outside an include list are left untouched.
The initial rule set supports common gitignore-style patterns: *, ?, **, root-anchored rules that start with /, and directory rules that end with /. Directory rules include the whole subtree. Negation rules such as !keep.txt are not supported yet.
🌐 Remote Folder Sync
Use this for a temporary handoff: send a folder to someone, or let them upload one to you. The person sharing the folder starts share, reads out the one-time code, and the other side runs connect.
> [!IMPORTANT]
> This is one-way sync. Choose download or upload for each session; FastSync does not merge changes from both sides.
Send a folder to someone:
fastsync s ./photos
fastsync c server.example.com ./photos -c 123456
Let someone upload a folder to you:
fastsync s ./inbox -r
fastsync c server.example.com ./project -u -c 123456
What happens by default:
Default
Meaning
share sends files
fastsync s ./photos only lets the other side download.
one-time code
FastSync prints a code when sharing starts.
one successful use
The sharing side exits after one completed sync.
no server deletion
Upload clients cannot delete your files unless you explicitly allow it.
You can omit --code; FastSync will prompt for it.
Common shortcuts:
Full form
Shortcut
share / connect
s / c
--code 123456
-c 123456
--mode receive
-r or -m r
--direction push
-u
--delete
-d
--strict
no short form
--allow-delete
-a
--preserve-permissions
-p or --perms
--exclude-from FILE
-x FILE
--include-from FILE
-i FILE
Deleting extra files is always opt-in and only affects the side receiving files:
When you choose
--delete can delete
Extra requirement
download
Extra files in your local folder
None
upload
Extra files in the shared folder
Sharing side must allow deletion
fastsync c server.example.com ./photos -d -c 123456
fastsync s ./inbox -r -a
fastsync c server.example.com ./project -u -d -c 123456
Network sync also accepts -x/--exclude-from and -i/--include-from. Each side applies its own rules locally; rules are not sent to the peer and are not merged into a shared filter. For example, the sharing side can choose not to share private/, while the connecting side can choose to receive only photos/. Each side's filter only affects the paths that side may send, request, write, or delete.
By default, received files keep their modification times. Permission bits are copied only when requested:
Option
Meaning
--strict
Hash same-size local files even when metadata matches before deciding what to transfer.
--no-preserve-times
Do not preserve source modification times on received files and directories.
--preserve-permissions
Preserve source permission bits on received files and directories. Disabled by default.
Without --strict, network sync defaults to fast comparison: matching metadata is trusted, and BLAKE3 is used only for same-size files whose metadata differs.
For auditing, the sharing side logs who connected, whether the session downloaded or uploaded, delete/metadata choices, pairing failures, file count, byte count, deleted count, and elapsed time. Use --log-level debug for more detail.
Technical note: one-shot network sync uses QUIC with a temporary self-signed certificate, verifies received files with BLAKE3, and writes through temporary files before replacement. Use it for short-lived sessions where both sides can confirm the address and code.
🛡️ Safety First By Default
Default
Why it matters
One-way sync
The source is the authority; the target follows it.
No implicit deletion
Target-only files are preserved unless --delete is used.
Filtered paths stay put
Excluded paths and paths outside an include list are not copied, overwritten, or deleted.
Fast comparison
Existing files trust matching metadata by default, and use BLAKE3 only for same-size files whose metadata differs.
Temporary-file overwrite
Existing targets are written to a temporary filename first, then renamed into place, reducing the chance of leaving a partial file after interruption.
Direct new-file copy
Missing target files are copied directly, without unnecessary rename overhead.
Dry-run support
You can inspect the plan before changing anything.
🔍 Choose A Comparison Mode
Mode
Behavior
Use when
fast
If metadata matches, treats the file as unchanged. If metadata differs, size differences are changed immediately; same-size files are checked with BLAKE3. This is the default.
You want good speed while still hashing ambiguous same-size changes.
strict
If sizes match, checks content with BLAKE3 even when metadata also matches.
You want content confirmation for every existing same-size file.
--strict is a shortcut for --compare strict.
> [!IMPORTANT]
> Fast mode can miss content changes when size, modified time, and supported permissions stay the same. Use strict for important data that needs content confirmation even when metadata matches.
Same-name file metadata synchronization is separate from content comparison and is enabled by default. It applies source metadata to matching target files. Use --no-sync-metadata to skip standalone metadata updates, or --preserve-times false and/or --preserve-permissions false to narrow which source metadata is applied to the target.
✅ Verification
Post-copy verification is controlled by --verify:
Mode
Behavior
none
Do not verify after copying.
changed
Verify overwritten files. This is the default.
all
Verify all regular source files after sync.
The summary reports BLAKE3 content checks in two separate counters: comparison-time checks used by fast or strict, and post-copy verifications controlled by --verify.
New files that do not exist in the target are copied directly and are not counted as post-copy BLAKE3 verifications.
📟 Progress And Logs
When running in an interactive terminal with text output, fastsync shows a bottom
progress indicator for local sync stages:
Scanning source and target directories.
Building the sync plan, including processed entries, planned operations, planned data, and BLAKE3 comparison count.
Executing the sync plan.
Full verification when --verify all is enabled.
Network share and connect commands also show progress for active transfer
phases:
Sending and receiving manifests.
Serving or requesting BLAKE3 hashes for ambiguous files.
Planning requested files.
Sending and receiving file streams.
Deleting obsolete entries and applying received metadata when those phases run.
The progress UI is designed for humans at a terminal. It is automatically hidden
for JSON output, non-TTY output, TERM=dumb, and NO_COLOR environments. The
summary and JSON output continue to use stdout, while logs and progress render on
stderr so scripts can consume stdout safely.
fastsync routes tracing logs through a progress-aware writer when the progress UI
is active, so log lines and the bottom indicator can coexist without corrupting
each other. Increase --log-level when you need more detail; progress remains a
visual status layer and does not change sync behavior.
🧾 CLI Cheat Sheet
Option
Meaning
-n, --dry-run
Preview only; do not modify the target.
-d, --delete
Delete target entries that no longer exist in the source.
-x, --exclude-from
Read blacklist rules from a file; matching paths are skipped.
-i, --include-from
Read whitelist rules from a file; only matching paths are synced.
--strict
Use strict BLAKE3 confirmation for same-size existing files.
-c, --compare
Select the comparison strategy.
--no-sync-metadata
Do not update metadata for same-name files whose content already matches.
--preserve-times
Apply source modification times to target files.
--preserve-permissions
Apply source permission bits to target files.
--verify
Select post-copy verification.
-t, --threads
Set the worker count.
-q, --queue-size
Set the bounded task queue size.
--no-atomic-write
Disable temporary-file overwrite writes.
-o, --output
Select summary format.
-l, --log-level
Set log verbosity.
--lang
Select interface language. Also accepts common locale aliases.
Network one-shot commands:
Command
Meaning
fastsync share
Start a temporary server. Defaults to --mode send.
fastsync connect
Connect to a temporary server. Defaults to --direction pull.
Running fastsync without arguments also prints help.
🧪 Development
This crate sets edition = "2024" in Cargo.toml. That is the Rust edition name, not the current calendar year; Rust editions are opt-in language compatibility milestones, and the 2024 edition remains current even when building in 2026.
Maintainers and coding agents should read AGENTS.md.
❓ FAQ
Is FastSync bidirectional?
No. FastSync is intentionally one-way: source to target.
Will FastSync delete files by default?
No. Deletion only happens when --delete or -d is provided.
Should I use --strict?
Use it for important personal or production data where matching metadata is not enough confidence. For generated files, caches, and build outputs, the default fast mode is usually the better tradeoff.