Skip to content

Releases: oferchen/rsync

v0.6.2

16 May 14:50
c99bbbc

Choose a tag to compare

oc-rsync 0.6.2

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

Toolchain variants

Each release ships three Rust-toolchain variants of every binary:

Suffix Rust toolchain Recommended use
(none) stable Default. Use this.
-beta Rust beta Early adopters validating the next Rust release.
-nightly Rust nightly Performance experiments and unstable-feature testing.

The -beta / -nightly suffix denotes the Rust toolchain the artifact was built with - it is not an indicator of oc-rsync's own release maturity (that is set in the release title and README.md).


What's Changed

Features

  • feat(ssh): warn when SSH and rsync compression both enabled by @oferchen in #3637
  • feat(match): add zsync-inspired bithash prefilter to MatchIndex by @oferchen in #3737
  • feat(fast_io): add io_uring RENAMEAT2 wrapper and kernel probe by @oferchen in #3739
  • feat(cli): add --cow / --no-cow flag by @oferchen in #3740
  • feat(cli): wire --max-alloc=N memory cap to buffer pool by @oferchen in #3749
  • feat(match): add zsync-inspired seq-match extend-run by @oferchen in #3751
  • feat(cli): add --sparse-detect=[auto|seek|map|none] by @oferchen in #3741
  • feat(match): zsync-inspired matched-block pruning bitmap by @oferchen in #3748
  • feat(fast_io): add io_uring LINKAT wrapper and kernel probe by @oferchen in #3738
  • feat(cli): add --rayon-threads and --tokio-threads tunables by @oferchen in #3747
  • feat(cli): add --zero-copy / --no-zero-copy flag by @oferchen in #3750
  • feat(cli): add --io-uring-depth tunable for SQE batch size by @oferchen in #3742
  • feat(cli): add --simd flag for runtime SIMD level override by @oferchen in #3743
  • feat(fast_io): cache PBUF_RING probe and surface in --version by @oferchen in #3635
  • feat(engine): AIMD concurrency limiter type by @oferchen in #3951
  • feat(engine): adaptive buffer-sizing PID controller (#2095) by @oferchen in #3952
  • feat(engine): add AIMD limiter convergence tests and CLI flag (#2092, #2093) by @oferchen in #3961
  • feat(core): wire missing RERR exit codes (#2114) by @oferchen in #3962
  • feat: wire io_uring RENAMEAT2 and LINKAT into production paths by @oferchen in #3981
  • feat(engine): AIMD limiter convergence tests and CLI flag tests by @oferchen in #3978
  • feat: add buffer recycling to checksum pipeline by @oferchen in #3979
  • feat: bounded-memory spill-to-tempfile for ReorderBuffer by @oferchen in #3982
  • feat: wire adaptive buffer controller into BufferPool by @oferchen in #3980
  • feat(transfer): add ReorderBuffer stall-duration and queue-depth metrics by @oferchen in #3984
  • feat(transfer): bypass ReorderBuffer when delay-updates is off (#1886) by @oferchen in #3988
  • feat(engine): wire adaptive buffer controller into pool acquisition path by @oferchen in #3990
  • feat(fast_io): add splice/vmsplice zero-copy path for network-to-disk transfers by @oferchen in #3993
  • feat(fast_io): add Windows ReFS reflink via FSCTL_DUPLICATE_EXTENTS (#1389) by @oferchen in #3997
  • feat(fast_io): add macOS F_NOCACHE + writev optimized write path (#1657) by @oferchen in #3998
  • feat(fast_io): add IORING_OP_STATX batch chains for parallel directory stat (#1833) by @oferchen in #4001
  • feat(transfer): wire IORING_OP_RENAMEAT2 into remaining temp-file commit paths (#1924) by @oferchen in #4002
  • feat: bound io_uring buffer group ID allocation by @oferchen in #4005
  • feat: adapt parallel delta work queue to workload + core count by @oferchen in #4012
  • feat: wire MacosWriter into the disk-commit dispatcher by @oferchen in #4018
  • feat: reuse io_uring buffer group IDs via free-list by @oferchen in #4019
  • feat: add ParallelOp lookup for per-operation rayon thresholds by @oferchen in #4030
  • feat: daemon accept loop honours --max-connections admission cap by @oferchen in #4042
  • feat: invoke native sendfile(2) on macOS by @oferchen in #4043
  • feat: add top-level cargo-fuzz harness for protocol wire parser by @oferchen in #4046
  • feat: reject --append with --whole-file at config build time by @oferchen in #4049
  • feat: opt-in xxh64 file-dedup heuristic for receiver delta path by @oferchen in #4041
  • feat: accept bare numeric --info=N levels (upstream parity) by @oferchen in #4053
  • feat: server-side tolerance for unknown --info tokens (upstream parity) by @oferchen in #4055
  • feat: wire --debug=send producer emissions to match upstream rsync 3.4.1 by @oferchen in #4062
  • feat: scope --info=no/- negation to internal use only by @oferchen in #4060
  • feat: gate --inplace --partial-dir rejection on CF_INPLACE_PARTIAL_DIR negotiation by @oferchen in #4064
  • feat: distinguish disabled vs failed registration in RegisteredBufferStats by @oferchen in #4065
  • feat(fast_io): apply F_NOCACHE hint on macOS source-file reads by @oferchen in #4068
  • feat(fast_io): refuse SQPOLL when mmap reader is active by @oferchen in #4069
  • feat: promote whole_file=1 when --checksum-choice=none by @oferchen in #4066
  • feat: filter-rule sender-side (s) and receiver-side (r) directive modifiers by @oferchen in #4071
  • feat(progress): sliding-window remaining-time estimate matching upstream by @oferchen in #4072
  • feat(progress): render stalled-transfer remaining-time as upstream by @oferchen in #4076
  • feat: tolerate "directory has vanished" race in walk path (3.4.2 parity) by @oferchen in #4081
  • feat(cli): add --compress-threads=N flag with validation (3.4.2 parity) by @oferchen in #4095
  • feat(progress): overflow sentinel and ir-chk prefix (D9/D10 parity) by @oferchen in #4094
  • feat(logging): wire --info=NAME level 2 emissions in copy/link/del paths by @oferchen in #4099
  • feat: wire --compress-threads=N through to zstd ZSTD_c_nbWorkers (3.4.2 parity) by @oferchen in #4100
  • feat(generator): instrument first-byte latency in send_file_list (INC_RECURSE I1) by @oferchen in #4103
  • feat(transfer): wire --debug=HLINK producer emissions (3.4.1 parity) by @oferchen in #4105
  • feat(cli): restore --info=STATS level 1/2/3 distinction (3.4.1 parity) by @oferchen in #4106
  • feat(transfer): wire --debug=FUZZY producer emissions (3.4.1 parity) by @oferchen in #4109
  • feat(generator): wire --debug=GENR producer emissions (3.4.1 parity) by @oferchen in #4110
  • feat(core): wire --debug=ICONV producer emissions (3.4.1 parity) by @oferchen in #4112
  • feat(transfer): wire --info=NONREG default-on emission (3.4.1 parity) by @oferchen in #4113
  • feat(transfer): wire --info=BACKUP emission (3.4.1 parity) by @oferchen in #4114
  • feat(transfer): wire --info=MOUNT emission (3.4.1 parity) by @oferchen in #4116
  • feat(metadata): wire --debug=ACL producer emissions (3.4.1 parity) by @oferchen in #4117
  • feat(transfer): wire --info=SYMSAFE emission (3.4.1 parity) by @oferchen in #4119
  • feat(transfer): wire --de...
Read more

v0.6.1

03 May 10:55

Choose a tag to compare

oc-rsync 0.6.1

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

Toolchain variants

Each release ships three Rust-toolchain variants of every binary:

Suffix Rust toolchain Recommended use
(none) stable Default. Use this.
-beta Rust beta Early adopters validating the next Rust release.
-nightly Rust nightly Performance experiments and unstable-feature testing.

The -beta / -nightly suffix denotes the Rust toolchain the artifact was built with - it is not an indicator of oc-rsync's own release maturity (that is set in the release title and README.md).


What's Changed

Features

Performance

Bug Fixes

  • fix(transfer): reject Windows drive prefixes from untrusted senders + audit by @oferchen in #3496
  • fix(ci): escape charset backticks in known_failures.conf by @oferchen in #3532
  • fix(metadata): wire fake-super through receiver and gate mknod by @oferchen in #3530
  • fix(metadata): import ACCESS_ALLOWED_ACE_TYPE from SystemServices (#1866) by @oferchen in #3544
  • fix(metadata): add Win32_System_SystemServices feature for ACL build (#1866) by @oferchen in #3549
  • fix(metadata): force am_root=false under fake-super (#1926) by @oferchen in #3547
  • fix(fast_io): prevent io_uring SEND deadlock under TCP backpressure (#1872) by @oferchen in #3551
  • fix(checksums): rolling checksum sign-extends bytes to match upstream schar by @oferchen in #3560
  • fix(logging-sink): replace libc syslog FFI with safe syslog crate by @oferchen in #3562
  • fix(client): forward --iconv to remote rsync server args by @oferchen in #3565
  • fix(cli): wire --iconv and recognise --timeout= in server-mode flag parser by @oferchen in #3566
  • fix(workspace): expose embedded-ssh facade feature on root crate by @oferchen in #3569
  • fix(fast_io): skip criterion io_uring bench on RLIMIT_MEMLOCK failure by @oferchen in #3572

CI/CD

Documentation

Read more

v0.6.0

06 Apr 14:50

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

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

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