Skip to content

Releases: oferchen/rsync

v0.6.0

06 Apr 14:50
6a4e2a9

Choose a tag to compare

oc-rsync 0.6.0

Wire-compatible with upstream rsync 3.4.1 (protocol 32).

Install

Homebrew:

brew install oferchen/rsync/oc-rsync

Binary: 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...
Read more

v0.5.9

16 Mar 11:18
4a696c8

Choose a tag to compare

oc-rsync 0.5.9

Wire-compatible with upstream rsync 3.4.1 (protocol 32).

Install

Homebrew:

brew install oferchen/rsync/oc-rsync

Binary: 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 .tmp subdirectory 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...
Read more

v0.5.8

19 Feb 16:19

Choose a tag to compare

oc-rsync 0.5.8

Wire-compatible with upstream rsync 3.4.1 (protocol 32).

Install

Homebrew:

brew install oferchen/rsync/oc-rsync

Binary: 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

17 Feb 16:12
b9fdf5e

Choose a tag to compare

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

15 Feb 12:35

Choose a tag to compare

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

13 Feb 10:12

Choose a tag to compare

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

23 Jan 04:26

Choose a tag to compare

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

16 Jan 09:56

Choose a tag to compare

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

05 Jan 15:34

Choose a tag to compare

added packages compatible with Ubuntu 20.04 Focal glibc (and probably other as well)

What's New

  • Add --tree flag 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 release

What's Changed

Full Changelog: v0.5.0...v0.5.1

v0.5.0

29 Dec 19:24

Choose a tag to compare

  • 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