Releases: oferchen/rsync
v0.6.0
oc-rsync 0.6.0
Wire-compatible with upstream rsync 3.4.1 (protocol 32).
Install
Homebrew:
brew install oferchen/rsync/oc-rsyncBinary: Download the asset for your platform below.
| Platform | Formats |
|---|---|
| Linux (x86_64, aarch64) | .deb, .rpm (with OpenSSL), static musl .tar.gz, *-openssl.tar.gz |
| macOS (x86_64, aarch64) | .tar.gz |
| Windows (x86_64) | .tar.gz, .zip |
Linux static tarballs: *-musl.tar.gz (pure Rust) or *-musl-openssl.tar.gz (OpenSSL-accelerated checksums).
What's Changed
Features
- feat: inject SSH keepalive options to prevent idle drops by @oferchen in #2747
- feat: add O_TMPFILE availability probe with OnceLock caching by @oferchen in #2890
- feat: spawn background stderr drain thread in SSH connection by @oferchen in #2912
- feat: add error_location! macro for upstream-compatible error format by @oferchen in #2911
- feat: add rsync_error_fmt! macro with upstream-compatible error format by @oferchen in #2904
- feat: implement O_TMPFILE + linkat for anonymous temp file writes by @oferchen in #2918
- feat: include SSH stderr output in transfer error messages by @oferchen in #2952
- feat: wire O_TMPFILE + linkat finalization into AnonymousTempFile write strategy by @oferchen in #2957
- feat: design PlatformCopy trait interface for platform-specific copy optimizations by @oferchen in #2972
- feat: wire try_io_uring_copy as fallback in copy_file_contents by @oferchen in #2973
- feat: add Windows CopyFileEx platform copy stub by @oferchen in #2975
- feat: add hard memory cap with backpressure to BufferPool by @oferchen in #2976
- feat: implement per-token lz4 frame flush by @oferchen in #2977
- feat: add bounded work queue to concurrent_delta to prevent OOM by @oferchen in #2971
- feat: add macOS clonefile and copyfile platform copy stubs by @oferchen in #2974
- feat: advertise zstd and lz4 compression in protocol negotiation by @oferchen in #2978
- feat: implement global bounded buffer pool singleton by @oferchen in #2979
- feat: add PhaseTimer RAII struct for transfer phase timing by @oferchen in #2982
- feat: make SPSC disk commit channel capacity configurable by @oferchen in #2981
- feat: add PhaseTimer RAII instrumentation to transfer hot paths by @oferchen in #2986
- feat: add Linux FICLONE reflink support via rustix by @oferchen in #3025
- feat: wire --write-batch into SSH and daemon transfer paths by @oferchen in #3026
- feat: add zstd and lz4 per-token compression codecs by @oferchen in #3028
- fix: eliminate TOCTOU race in BufferPool memory cap backpressure by @oferchen in #3029
- feat: wire zstd/lz4 per-token codecs into transfer layer by @oferchen in #3030
- feat: add EMA throughput tracker and dynamic buffer sizing to BufferPool by @oferchen in #3032
- feat: add FilterChain for per-directory merge filter scoping by @oferchen in #3033
- feat: add compression codec interop test infrastructure by @oferchen in #3031
- feat: wire per-directory merge filters into transfer layer by @oferchen in #3034
- feat: add io_uring buffer registration for READ_FIXED/WRITE_FIXED ops by @oferchen in #3035
- feat: add ReFS filesystem detection for Windows reflink support by @oferchen in #3036
- feat: sender-side INC_RECURSE with optimized partitioning and lazy segment scheduling by @oferchen in #3038
- feat: two-level buffer pool with thread-local cache + Mutex by @oferchen in #3037
- feat: implement Windows console signal handling for daemon mode by @oferchen in #3041
- feat: add platform crate for unsafe code isolation by @oferchen in #3042
- fix: address multiple interop test failures by @oferchen in #3044
- feat: add HardlinkApplyTracker for receiver-side hardlink restoration by @oferchen in #3048
- feat: add InodeDeviceMap for protocol < 30 hardlink grouping by @oferchen in #3049
- feat: enable zstd and lz4 auto-negotiation in compression capability string by @oferchen in #3050
- feat: enable lz4 and zstd auto-negotiation in compression interop tests by @oferchen in #3055
- feat: wire HardlinkApplyTracker into receiver hardlink creation path by @oferchen in #3066
- feat: add explicit sequence-based reordering for DeltaResult items by @oferchen in #3074
- feat: enable zstd compression auto-negotiation by @oferchen in #3081
- feat: add Windows daemon privilege dropping and name resolution (phase 2) by @oferchen in #3089
- feat: implement ACL wire format for upstream rsync 3.4.1 interop by @oferchen in #3092
- feat: implement hardlink receiver-side inode/device mapping for daemon push by @oferchen in #3111
- feat: implement xattr abbreviation wire format for -X/--xattrs interop by @oferchen in #3117
- feat: enable zstd compression auto-negotiation by @oferchen in #3108
Performance
- perf: match upstream rsync compression negotiation precedence by @oferchen in #2737
- perf: optimize large file copy with direct write and adaptive 1MB buffers by @oferchen in #2738
- perf: replace BufferPool Mutex with lock-free crossbeam ArrayQueue by @oferchen in #2923
- perf: add 1GB file benchmark with phase breakdown by @oferchen in #3018
- perf: add 100K files benchmark with phase breakdown by @oferchen in #3019
- perf: add BufferPool lock contention benchmark by @oferchen in #3013
- perf: add criterion benchmark suite for delta transfer path by @oferchen in #3014
- perf: add criterion benchmark suite for daemon mode by @oferchen in #3016
- perf: add binary startup overhead benchmark by @oferchen in #3023
- perf: wire batched parallel stat into generator file list building by @oferchen in #3039
Bug Fixes
- fix: drain SSH child stderr in background thread by @oferchen in #2741
- fix: use shared base directory for --files-from file list building by @oferchen in #2746
- fix: correct itemize time position T/t to match upstream by @oferchen in #2745
- fix: activate receiver input multiplex for proto 28/29 daemon pulls by @oferchen in #2749
- fix: add sanitize_path for files_from path traversal prevention by @oferchen in #2750
- fix: fix --read-batch file list finalization and destination resolution by @oferchen in #2751
- fix: add role trailers to error messages in transfer and daemon by @oferchen in #2758
- fix: detect secluded-args flag in compact flag strings for protocol 28/29 by @oferchen in #2760
- fix: apply upstream option interactions when --files-from is active by @oferchen in #2762
- fix: propagate --itemize-changes flag to remote server and enable client-mode output by @oferchen in #2761
- fix: forward itemize-changes via --log-format=%i instead of compact flag by @oferchen in #2766
- fix: correct batch file list reader and add replay tests by @oferchen in #2764
- fix: gate info_log import behind #[cfg(unix)] to fix Windows build by @oferchen in #2837
- fix: gate SocketOptionKind import behind cfg(not(windows)) in apply.rs by @oferchen in #2866
- fix: correct --files-from operand assembly and implied --relative handling by @oferchen in #2859
- fix: gate tracing target constant imports behind cfg(feature = "tracing") by @oferchen in #2873
- fix: correct --files-from...
v0.5.9
oc-rsync 0.5.9
Wire-compatible with upstream rsync 3.4.1 (protocol 32).
Install
Homebrew:
brew install oferchen/rsync/oc-rsyncBinary: Download the asset for your platform below.
| Platform | Formats |
|---|---|
| Linux (x86_64, aarch64) | .deb, .rpm (with OpenSSL), static musl .tar.gz, *-openssl.tar.gz |
| macOS (x86_64, aarch64) | .tar.gz |
| Windows (x86_64) | .tar.gz, .zip |
Linux static tarballs: *-musl.tar.gz (pure Rust) or *-musl-openssl.tar.gz (OpenSSL-accelerated checksums).
What's Changed
Features
- feat: add -4/-6/-0/-I short option aliases by @oferchen in #2361
- feat: improve daemon transfer socket and error handling by @oferchen in #2363
- feat: add --aes/--no-aes CLI flags for SSH cipher control by @oferchen in #2364
- feat: wire --aes/--no-aes to SSH cipher selection by @oferchen in #2369
- feat: add TokenReader for plain/compressed delta token dispatch by @oferchen in #2373
- feat: wire --dparam values to daemon config override by @oferchen in #2375
- feat: add daemon signal handling (SIGHUP/SIGTERM/SIGPIPE) by @oferchen in #2376
- feat: implement munge symlinks daemon directive by @oferchen in #2377
- feat: add missing daemon config directives and fix unknown directive handling by @oferchen in #2381
- feat: implement daemon chroot and privilege dropping by @oferchen in #2382
- feat: implement pre-xfer and post-xfer exec daemon directives by @oferchen in #2386
- feat: implement daemon transfer log format engine by @oferchen in #2387
- feat: wire --munge-links client-side symlink munging by @oferchen in #2388
- feat: implement --write-devices flag enforcement by @oferchen in #2389
- feat: implement --atimes/-U access time preservation by @oferchen in #2390
- feat: implement --copy-as USER:GROUP privilege switching by @oferchen in #2391
- feat: implement --early-input file transmission by @oferchen in #2392
- feat: implement --crtimes/-N creation time preservation by @oferchen in #2393
- feat: implement --trust-sender path safety enforcement by @oferchen in #2394
- feat: wire --address bind address to SSH and daemon connections by @oferchen in #2396
- feat: implement --stop-at/--stop-after deadline enforcement by @oferchen in #2397
- feat: wire --qsort flag for file list sorting order by @oferchen in #2398
- feat: add Alpine Linux APK packaging to release workflow by @oferchen in #2418
- feat: parse 'strict modes' directive in rsyncd.conf by @oferchen in #2428
- feat: add --io-uring/--no-io-uring CLI flags by @oferchen in #2429
- feat: add connection counter to daemon server loop by @oferchen in #2430
- feat: add skip logging for --min-size/--max-size filtering by @oferchen in #2433
- feat: add AttrsFlags for selective time attribute application by @oferchen in #2442
- feat: add FnameCmpType enum for alternate basis selection by @oferchen in #2447
- feat: extract read_early_input_file with 5K size cap by @oferchen in #2449
- feat: Windows ACL support with upstream-aligned protocol handling by @oferchen in #2463
- feat: implement .
tmpsubdirectory for --delay-updates staged files (#349) by @oferchen in #2465 - feat: enforce --min-size/--max-size in network transfer receiver (#365) by @oferchen in #2473
- feat: parse 'exclude from' and 'include from' directives in rsyncd.conf (#274, #275) by @oferchen in #2477
- feat: enforce strict modes on secrets file permissions (#278, #279) by @oferchen in #2478
- feat: wire --config CLI flag to daemon config loader (#237, #264) by @oferchen in #2479
- feat: implement --detach daemon daemonization (Unix) by @oferchen in #2487
- feat(flist): add Adaptive Radix Tree backend behind art feature by @oferchen in #2493
- feat(daemon): add SIGUSR1 graceful exit and SIGUSR2 progress dump signals by @oferchen in #2494
- feat(daemon): parse syslog facility and syslog tag directives in rsyncd.conf by @oferchen in #2496
- feat(daemon): implement --early-input file transmission by @oferchen in #2498
- feat(protocol): implement --secluded-args stdin argument passing by @oferchen in #2499
- feat(daemon): implement SIGHUP config reload by @oferchen in #2497
- feat(logging): add syslog backend for daemon mode by @oferchen in #2500
- feat(core): complete server invocation builder with all flag forwarding by @oferchen in #2503
- feat(daemon): add max verbosity parsing and enforcement by @oferchen in #2508
- feat(daemon): add glob pattern matching for refuse options enforcement by @oferchen in #2510
- feat(cli): add missing server-side flag parser options by @oferchen in #2511
- feat(transfer): implement MSG_NO_SEND support for protocol >= 30 by @oferchen in #2512
- feat(flist): propagate preserve_specials through CLI and flist writer by @oferchen in #2515
- feat(protocol): add pre-release 'V' compat flag support by @oferchen in #2516
- feat(transfer): add async transfer pipeline with tokio channels by @oferchen in #2518
- feat(transfer): add redo mechanism for failed checksum verification by @oferchen in #2524
- feat: add --files-from config, wire protocol, and server forwarding by @oferchen in #2526
- feat(daemon): add two-phase secluded-args protocol for --protect-args by @oferchen in #2527
- feat: add MSG_REDO wire protocol support for redo phase signaling by @oferchen in #2529
- feat(transfer): add --inplace support for remote transfers by @oferchen in #2531
- feat(protocol): add path interning for FileEntry dirname deduplication by @oferchen in #2533
- feat: add progress forwarding for remote SSH/daemon transfers by @oferchen in #2550
- feat(protocol): implement incremental recursion file list exchange by @oferchen in #2551
- feat(protocol): implement incremental recursion file list exchange by @oferchen in #2553
- feat(daemon): incremental recursion, compression, and interop improvements by @oferchen in #2554
- feat: wire atime and crtime preservation into generator file list building by @oferchen in #2561
- feat: accumulate NDX_DEL_STATS deletion counts in generator by @oferchen in #2563
- feat: track deletion counts by file type in receiver by @oferchen in #2568
- feat: send NDX_DEL_STATS from generator during goodbye phase by @oferchen in #2570
- feat: crtime preservation, PreserveFlags refactor, NDX_DEL_STATS fix, interop tests by @oferchen in #2575
- feat: resolve symlinks in flist walker when copy_links is active by @oferchen in #2588
- feat: filter unsafe symlinks from file list when safe-links is active by @oferchen in #2590
- feat: graceful fallback for unsupported ACL/xattr capabilities by @oferchen in #2584
- feat: detect remote daemon xattr capability rejection and fall back by @oferchen in #2586
- feat: implement daemon config global parameters (bind_address, uid/gid, open_noatime, listen_backlog) by @oferchen in #2592
- feat: implement socket_options global parameter for daemon TCP tuning by @oferchen in #2595
- feat: implement fuzzy level 2 sibling directory search by @oferchen in #2596
- feat: implement legacy goodbye handshake for protocol 28/29 by @oferchen in #2593
- feat: implement daemon ea...
v0.5.8
oc-rsync 0.5.8
Wire-compatible with upstream rsync 3.4.1 (protocol 32).
Install
Homebrew:
brew install oferchen/rsync/oc-rsyncBinary: Download the asset for your platform below.
| Platform | Formats |
|---|---|
| Linux (x86_64, aarch64) | .deb, .rpm (with OpenSSL), static musl .tar.gz, *-openssl.tar.gz |
| macOS (x86_64, aarch64) | .tar.gz |
| Windows (x86_64) | .tar.gz, .zip |
Linux static tarballs: *-musl.tar.gz (pure Rust) or *-musl-openssl.tar.gz (OpenSSL-accelerated checksums).
What's Changed
Features
- feat: add OpenSSL checksum acceleration for Linux GNU builds by @oferchen
- feat: produce distinct Linux artifacts with and without OpenSSL by @oferchen
Performance
- perf: eliminate per-file heap allocations in hot paths by @oferchen in #2335
- perf: zero-copy data path and per-file allocation reuse by @oferchen in #2336
- perf: buffer recycling, pre-allocation, and reusable write buffer by @oferchen in #2337
- perf: decoupled receiver + upstream architectural patterns by @oferchen in #2338
- perf: reduce checksum and memcpy overhead in receiver pipeline by @oferchen in #2340
- perf: implement receiver quick-check to skip unchanged files by @oferchen in #2343
- perf: move metadata application into disk commit thread by @oferchen in #2345
- perf: replace std::sync::mpsc with flume for channel communication by @oferchen in #2346
- perf: reduce syscalls with writev, BufReader, and message coalescing by @oferchen in #2348
- perf: replace flume with lock-free SPSC spin channel by @oferchen in #2349
Bug Fixes
- fix: correct --sender flag and filter list in SSH transfers by @oferchen in #2339
- fix: eliminate flaky tests from port TOCTOU race and CI timing by @oferchen in #2341
- fix: add ChecksumVerifier::None variant and enforce --whole-file flag by @oferchen in #2342
- fix: defer metadata application until after disk thread commit by @oferchen in #2344
- fix: eliminate port TOCTOU race in daemon integration tests by @oferchen in #2347
- fix: add -e.LsfxCIvu capability string to SSH remote invocation by @oferchen in #2350
- fix: upload benchmark chart on manual workflow triggers by @oferchen
CI/CD
- ci: expand benchmark to cover SSH, daemon, and local copy modes by @oferchen
- ci: add SVG benchmark chart generation and 10k file scaling by @oferchen
- ci: switch benchmark chart to PNG release asset by @oferchen
- ci: use release template in release-cross workflow by @oferchen
- ci: expand benchmark to cover all transfer modes by @oferchen in #2351
Documentation
- docs: add release notes template and auto-categorization config by @oferchen
Other Changes
- style: align benchmark chart colors with GitHub dark theme by @oferchen
- style: remove section divider comments across codebase by @oferchen
- style: fix cargo fmt formatting in disk_commit and transfer_ops by @oferchen
- chore: bump version to 0.5.8 by @oferchen
- chore: release v0.5.8 by @oferchen in #2352
- chore: update Homebrew formulas for v0.5.7 by @oferchen in #2334
Full Changelog: v0.5.7...v0.5.8
Benchmark Results
Test data: 148.3MB (10000 files)
Local Copy
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.342s | 0.219s | faster 0.64x |
| No-change sync | 0.099s | 0.103s | ~same 1.04x |
| Checksum sync | 0.626s | 0.325s | faster 0.52x |
SSH Pull
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.686s | 0.546s | faster 0.79x |
| No-change sync | 0.333s | 0.327s | ~same 0.98x |
SSH Push
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.638s | 0.655s | ~same 1.03x |
| No-change sync | 0.360s | 0.348s | ~same 0.97x |
Daemon Pull
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.430s | 0.298s | faster 0.69x |
| No-change sync | 0.169s | 0.110s | faster 0.65x |
Daemon Push
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync | 0.390s | 0.313s | faster 0.80x |
| No-change sync | 0.149s | 0.068s | faster 0.46x |
Checksum: OpenSSL vs Pure Rust
| Test | Pure Rust | OpenSSL | Ratio |
|---|---|---|---|
| Initial checksum sync | 0.390s | 0.391s | ~same 1.00x |
| No-change checksum sync | 0.325s | 0.325s | ~same 1.00x |
Summary
Overall: 0.81x average ratio
(best 0.46x, worst 1.04x)
| Mode | Avg Ratio |
|---|---|
| Local Copy | 0.73x |
| SSH Pull | 0.89x |
| SSH Push | 1.00x |
| Daemon Pull | 0.67x |
| Daemon Push | 0.63x |
Ratio < 1.0 = oc-rsync faster, > 1.0 = upstream faster
Internal Optimization Benchmarks
Buffer Pool Performance
Benchmarking buffer_allocation/direct_alloc
Benchmarking buffer_allocation/direct_alloc: Warming up for 3.0000 s
Benchmarking buffer_allocation/direct_alloc: Collecting 100 samples in estimated 5.0061 s (1.7M iterations)
Benchmarking buffer_allocation/direct_alloc: Analyzing
buffer_allocation/direct_alloc
time: [2.9307 µs 2.9530 µs 2.9808 µs]
--
Benchmarking buffer_allocation/pool_acquire_cold
Benchmarking buffer_allocation/pool_acquire_cold: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_cold: Collecting 100 samples in estimated 5.0000 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_cold: Analyzing
buffer_allocation/pool_acquire_cold
time: [27.630 ns 27.641 ns 27.654 ns]
--
Benchmarking buffer_allocation/pool_acquire_warm
Benchmarking buffer_allocation/pool_acquire_warm: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_warm: Collecting 100 samples in estimated 5.0001 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_warm: Analyzing
buffer_allocation/pool_acquire_warm
time: [27.628 ns 27.637 ns 27.645 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/10
Benchmarking sequential_buffer_ops/direct_alloc/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/10: Collecting 100 samples in estimated 5.0304 s (172k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/10: Analyzing
sequential_buffer_ops/direct_alloc/10
time: [29.222 µs 29.236 µs 29.254 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/10
Benchmarking sequential_buffer_ops/pool_reuse/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/10: Collecting 100 samples in estimated 5.0008 s (22M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/10: Analyzing
sequential_buffer_ops/pool_reuse/10
time: [229.93 ns 230.09 ns 230.24 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/100
Benchmarking sequential_buffer_ops/direct_alloc/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/100: Collecting 100 samples in estimated 5.9046 s (20k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/100: Analyzing
sequential_buffer_ops/direct_alloc/100
time: [292.14 µs 292.28 µs 292.44 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/100
Benchmarking sequential_buffer_ops/pool_reuse/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/100: Collecting 100 samples in estimated 5.0068 s (2.2M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/100: Analyzing
sequential_buffer_ops/pool_reuse/100
time: [2.2952 µs 2.2965 µs 2.2980 µs]
--
Benchmarking sequential_buffer_ops/direct_alloc/1000
v0.5.7
What's Changed
- Stream whole-file transfers in a single pass, eliminating per-file buffer allocations.
- Fix push-to-daemon protocol (MultiplexWriter optimizations, correct sender-side framing).
- Reduce per-file allocation overhead: stack-based checksum finalization, PathBuf ownership transfer, Vec pre-allocation.
- Increase daemon integration test timeout for nightly CI stability.
Full Changelog: v0.5.5...v0.5.7
Benchmark Results
Test data: 110.7MB (1110 files)
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync (-av) | 0.128s | 0.041s | faster 0.32x |
| No-change sync (-av) | 0.050s | 0.014s | faster 0.28x |
| Checksum sync (-avc) | 0.434s | 0.156s | faster 0.36x |
| Dry-run (-avn) | 0.050s | 0.018s | faster 0.35x |
| Delete sync (--delete) | 0.053s | 0.015s | faster 0.28x |
| Large files (100MB) | 0.096s | 0.017s | faster 0.18x |
| Small files (1000x1KB) | 0.066s | 0.022s | faster 0.34x |
Summary: Average ratio: 0.3x
- Best: 0.18x
- Worst: 0.36x
Ratio < 1.0 = oc-rsync faster, > 1.0 = upstream faster
Internal Optimization Benchmarks
Buffer Pool Performance
Benchmarking buffer_allocation/direct_alloc
Benchmarking buffer_allocation/direct_alloc: Warming up for 3.0000 s
Benchmarking buffer_allocation/direct_alloc: Collecting 100 samples in estimated 5.0068 s (1.7M iterations)
Benchmarking buffer_allocation/direct_alloc: Analyzing
buffer_allocation/direct_alloc
time: [2.9249 µs 2.9314 µs 2.9404 µs]
--
Benchmarking buffer_allocation/pool_acquire_cold
Benchmarking buffer_allocation/pool_acquire_cold: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_cold: Collecting 100 samples in estimated 5.0000 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_cold: Analyzing
buffer_allocation/pool_acquire_cold
time: [27.588 ns 27.593 ns 27.598 ns]
--
Benchmarking buffer_allocation/pool_acquire_warm
Benchmarking buffer_allocation/pool_acquire_warm: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_warm: Collecting 100 samples in estimated 5.0001 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_warm: Analyzing
buffer_allocation/pool_acquire_warm
time: [27.583 ns 27.591 ns 27.602 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/10
Benchmarking sequential_buffer_ops/direct_alloc/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/10: Collecting 100 samples in estimated 5.0251 s (172k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/10: Analyzing
sequential_buffer_ops/direct_alloc/10
time: [29.278 µs 29.303 µs 29.335 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/10
Benchmarking sequential_buffer_ops/pool_reuse/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/10: Collecting 100 samples in estimated 5.0009 s (22M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/10: Analyzing
sequential_buffer_ops/pool_reuse/10
time: [229.59 ns 229.64 ns 229.72 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/100
Benchmarking sequential_buffer_ops/direct_alloc/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/100: Collecting 100 samples in estimated 5.9096 s (20k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/100: Analyzing
sequential_buffer_ops/direct_alloc/100
time: [292.50 µs 292.79 µs 293.27 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/100
Benchmarking sequential_buffer_ops/pool_reuse/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/100: Collecting 100 samples in estimated 5.0091 s (2.2M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/100: Analyzing
sequential_buffer_ops/pool_reuse/100
time: [2.2959 µs 2.2965 µs 2.2973 µs]
--
Benchmarking sequential_buffer_ops/direct_alloc/1000
v0.5.5
What's Changed
- More speed optimizations.
- Fix of speed regression when using --delete.
- Added --direct-write to bypass temporary file creation and rename on initial copy.
- SSH process management improvements.
- io_uring improvements.
Full Changelog: v0.5.4...v0.5.5
Benchmark Results
Test data: 110.7MB (1110 files)
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync (-av) | 0.128s | 0.040s | faster 0.32x |
| No-change sync (-av) | 0.050s | 0.014s | faster 0.28x |
| Checksum sync (-avc) | 0.434s | 0.156s | faster 0.36x |
| Dry-run (-avn) | 0.050s | 0.017s | faster 0.35x |
| Delete sync (--delete) | 0.053s | 0.014s | faster 0.27x |
| Large files (100MB) | 0.096s | 0.017s | faster 0.18x |
| Small files (1000x1KB) | 0.065s | 0.022s | faster 0.34x |
Summary: Average ratio: 0.3x
- Best: 0.18x
- Worst: 0.36x
Ratio < 1.0 = oc-rsync faster, > 1.0 = upstream faster
Internal Optimization Benchmarks
Buffer Pool Performance
Benchmarking buffer_allocation/direct_alloc
Benchmarking buffer_allocation/direct_alloc: Warming up for 3.0000 s
Benchmarking buffer_allocation/direct_alloc: Collecting 100 samples in estimated 5.0008 s (1.7M iterations)
Benchmarking buffer_allocation/direct_alloc: Analyzing
buffer_allocation/direct_alloc
time: [2.9112 µs 2.9121 µs 2.9131 µs]
--
Benchmarking buffer_allocation/pool_acquire_cold
Benchmarking buffer_allocation/pool_acquire_cold: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_cold: Collecting 100 samples in estimated 5.0001 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_cold: Analyzing
buffer_allocation/pool_acquire_cold
time: [27.562 ns 27.568 ns 27.574 ns]
--
Benchmarking buffer_allocation/pool_acquire_warm
Benchmarking buffer_allocation/pool_acquire_warm: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_warm: Collecting 100 samples in estimated 5.0001 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_warm: Analyzing
buffer_allocation/pool_acquire_warm
time: [27.556 ns 27.565 ns 27.575 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/10
Benchmarking sequential_buffer_ops/direct_alloc/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/10: Collecting 100 samples in estimated 5.0082 s (172k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/10: Analyzing
sequential_buffer_ops/direct_alloc/10
time: [29.159 µs 29.225 µs 29.352 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/10
Benchmarking sequential_buffer_ops/pool_reuse/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/10: Collecting 100 samples in estimated 5.0004 s (22M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/10: Analyzing
sequential_buffer_ops/pool_reuse/10
time: [229.65 ns 229.71 ns 229.77 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/100
Benchmarking sequential_buffer_ops/direct_alloc/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/100: Collecting 100 samples in estimated 5.8847 s (20k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/100: Analyzing
sequential_buffer_ops/direct_alloc/100
time: [291.31 µs 291.52 µs 291.80 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/100
Benchmarking sequential_buffer_ops/pool_reuse/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/100: Collecting 100 samples in estimated 5.0099 s (2.2M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/100: Analyzing
sequential_buffer_ops/pool_reuse/100
time: [2.2957 µs 2.2964 µs 2.2973 µs]
--
Benchmarking sequential_buffer_ops/direct_alloc/1000
v0.5.4
What's Changed
This release is all about performance optimizations.
I added performance benchmark vs upstream rsync using Linux to the release to track performance regressions better.
While I do track and optimize performance metrics on other platforms my focus is Linux performance.
A container image based on Alpine Linux is now available at https://github.com/oferchen/rsync/pkgs/container/oc-rsync
Full Changelog: v0.5.3...v0.5.4
Benchmark Results
Test data: 110.7MB (1110 files)
| Test | Upstream | oc-rsync | Ratio |
|---|---|---|---|
| Initial sync (-av) | 0.128s | 0.060s | faster 0.47x |
| No-change sync (-av) | 0.052s | 0.027s | faster 0.53x |
| Checksum sync (-avc) | 0.438s | 0.171s | faster 0.39x |
| Dry-run (-avn) | 0.052s | 0.019s | faster 0.38x |
| Delete sync (--delete) | 0.055s | 0.028s | faster 0.51x |
| Large files (100MB) | 0.098s | 0.018s | faster 0.18x |
| Small files (1000x1KB) | 0.067s | 0.041s | faster 0.62x |
Summary: Average ratio: 0.44x
- Best: 0.18x
- Worst: 0.62x
Ratio < 1.0 = oc-rsync faster, > 1.0 = upstream faster
Internal Optimization Benchmarks
Buffer Pool Performance
Benchmarking buffer_allocation/direct_alloc
Benchmarking buffer_allocation/direct_alloc: Warming up for 3.0000 s
Benchmarking buffer_allocation/direct_alloc: Collecting 100 samples in estimated 5.0032 s (1.7M iterations)
Benchmarking buffer_allocation/direct_alloc: Analyzing
buffer_allocation/direct_alloc
time: [2.9286 µs 2.9311 µs 2.9343 µs]
--
Benchmarking buffer_allocation/pool_acquire_cold
Benchmarking buffer_allocation/pool_acquire_cold: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_cold: Collecting 100 samples in estimated 5.0001 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_cold: Analyzing
buffer_allocation/pool_acquire_cold
time: [27.584 ns 27.592 ns 27.600 ns]
--
Benchmarking buffer_allocation/pool_acquire_warm
Benchmarking buffer_allocation/pool_acquire_warm: Warming up for 3.0000 s
Benchmarking buffer_allocation/pool_acquire_warm: Collecting 100 samples in estimated 5.0001 s (181M iterations)
Benchmarking buffer_allocation/pool_acquire_warm: Analyzing
buffer_allocation/pool_acquire_warm
time: [27.584 ns 27.594 ns 27.605 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/10
Benchmarking sequential_buffer_ops/direct_alloc/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/10: Collecting 100 samples in estimated 5.0350 s (172k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/10: Analyzing
sequential_buffer_ops/direct_alloc/10
time: [29.285 µs 29.303 µs 29.324 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/10
Benchmarking sequential_buffer_ops/pool_reuse/10: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/10: Collecting 100 samples in estimated 5.0008 s (22M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/10: Analyzing
sequential_buffer_ops/pool_reuse/10
time: [231.91 ns 232.04 ns 232.21 ns]
--
Benchmarking sequential_buffer_ops/direct_alloc/100
Benchmarking sequential_buffer_ops/direct_alloc/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/direct_alloc/100: Collecting 100 samples in estimated 5.9188 s (20k iterations)
Benchmarking sequential_buffer_ops/direct_alloc/100: Analyzing
sequential_buffer_ops/direct_alloc/100
time: [292.87 µs 293.05 µs 293.31 µs]
--
Benchmarking sequential_buffer_ops/pool_reuse/100
Benchmarking sequential_buffer_ops/pool_reuse/100: Warming up for 3.0000 s
Benchmarking sequential_buffer_ops/pool_reuse/100: Collecting 100 samples in estimated 5.0115 s (2.2M iterations)
Benchmarking sequential_buffer_ops/pool_reuse/100: Analyzing
sequential_buffer_ops/pool_reuse/100
time: [2.3180 µs 2.3188 µs 2.3197 µs]
--
Benchmarking sequential_buffer_ops/direct_alloc/1000
v0.5.3
What's Changed
- This release delivers improved compatibility with upstream rsync 3.4.1 across the CLI, protocol, and documentation.
- Introduces thousands of new tests.
- Expands multi-toolchain builds (stable, beta, nightly) across multiple Homebrew taps.
- Complete CI refactor.
Full Changelog: v0.5.2...v0.5.3
v0.5.2
What's Changed
I modified the *_focal builds to use MUSL and Alpine Linux instead it is cleaner, faster and more efficient.
basic benchmarks slighly faster speed comparing to https://rsync.samba.org with the same feature set.
Full Changelog: v0.5.1...v0.5.2
v0.5.1
added packages compatible with Ubuntu 20.04 Focal glibc (and probably other as well)
What's New
- Add
--treeflag for task decomposition visualization in xtask - Shows task hierarchies with Unicode box-drawing and ANSI colors
- Displays task names, descriptions, and estimated durations
Usage
cargo xtask --tree package
cargo xtask --tree releaseWhat's Changed
- chore: update Homebrew formula for v0.5.0 by @oferchen in #2280
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2282
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2283
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2284
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2285
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2286
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2287
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2288
- chore: update Homebrew formula for v0.5.1 by @oferchen in #2289
Full Changelog: v0.5.0...v0.5.1
v0.5.0
- This release is equivalent in functionalities to upstream Rsync v3.4.1 https://rsync.samba.org.
- I added interoperability tests with upstream rsync to validate proper functionality across binaries.
- Optimization phase is ongoing to decouple functionalities and parallelize and offload some operations to CPU instructions.
Cheers,
Ofer
Full Changelog: v0.5.1...v0.5.0