Skip to content

Releases: oferchen/rsync

v0.6.3

Choose a tag to compare

@oferchen oferchen released this 05 Jun 19:31
565938f

oc-rsync 0.6.3

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


Security

See SECURITY.md for the canonical mitigation roster and docs/design/sec-1-completion-summary-2026-05-22.md for the SEC-1 sub-task (.a-.p) ship state.

Active mitigations

CVE Description Status Cite
CVE-2024-12084 Heap overflow in checksum parsing Not vulnerable Rust Vec<u8> handles dynamic sizing
CVE-2024-12085 Uninitialized stack buffer leak Not vulnerable Rust requires initialization
CVE-2024-12086 Server leaks client files Not vulnerable Strict path validation
CVE-2024-12087 Path traversal via --inc-recursive Not vulnerable Path sanitization
CVE-2024-12088 --safe-links bypass Mitigated Rust path handling
CVE-2024-12747 Symlink race condition Mitigated TOCTOU is OS-level
CVE-2026-29518 TOCTOU symlink race in daemon receiver Fixed SEC-1.a-q2, SECURITY.md
CVE-2026-43617 Reverse-DNS lookup after daemon chroot Not vulnerable Hostname ACL runs before chroot
CVE-2026-43618 Integer overflow in compressed-token decoder Fixed Typed CompressedToken enum, SECURITY.md
CVE-2026-43619 Symlink races on chmod/lchown/utimes/rename/unlink/mkdir Fixed SEC-1.a-q2, SECURITY.md
CVE-2026-43620 OOB read via negative parent_ndx Not vulnerable Option<usize> + bounds-checked Vec
CVE-2026-45232 Off-by-one stack write in HTTP CONNECT proxy Fixed SEC-2.a-b, SECURITY.md

Defense-in-depth. This release ships the SEC-1 *at syscall chain (fstatat, unlinkat, mkdirat, symlinkat, linkat, fchmodat, fchownat, utimensat, renameat) routed through a per-transfer DirSandbox carrier with openat2(RESOLVE_BENEATH | RESOLVE_NO_SYMLINKS) runtime detection. The optional landlock Cargo feature (Linux 5.13+) layers kernel-enforced PathBeneath allowlisting on top; daemons on older kernels run with the *at chain as the sole TOCTOU defense, which is itself sufficient against CVE-2026-29518 / CVE-2026-43619.

Kernel / platform compatibility

Layer Minimum Notes
io_uring data path Linux 5.6+ Runtime-probed; falls back to standard buffered I/O.
Provided buffer rings (PBUF_RING) Linux 5.19+ Runtime-probed; falls back to standard buffered I/O.
Landlock LSM (landlock feature) Linux 5.13+ Best-effort ABI downgrade; no-op on older kernels.
IORING_OP_SEND_ZC (iouring-send-zc feature) Linux 6.0+ recommended Opt-in; default builds use plain IORING_OP_SEND.
macOS *at chain macOS 10.10+ BSD *at family verified at parity with Linux (SEC-1.k).
Windows IOCP Windows 10 1809+ NTFS handle-based APIs sidestep path TOCTOU structurally (SEC-1.l).

Distro packagers: see docs/packaging/landlock-feature-guidance.md for the per-distro --features landlock recommendation, runtime ABI matrix, and build-time dependency notes.

Supported rsync protocol versions

Protocol versions 28-32 (upstream rsync 2.6.x-3.4.x). Protocols <= 27 unsupported. Per-opcode kernel floor: docs/audit/iouring-opcode-kernel-floor.md.


What's Changed

Features

  • feat(version): list compiled-in Cargo features in --version output by @oferchen in #4522
  • feat(engine): expose force_insert counter on DeltaConsumer::stats by @oferchen in #4552
  • feat(match): zsync-inspired sequential-match lookahead (ZSO-2) by @oferchen in #4624
  • feat(engine): plumb negotiated checksum strategy into ParallelDeltaApplier by @oferchen in #4616
  • feat(engine): implement real verify_chunk in ParallelDeltaApplier (BR-3i.c) by @oferchen in #4640
  • feat(fast_io): add secure_open_dir helper for SEC-1 dirfd sandbox by @oferchen in #4618
  • feat(transfer): honour source-side user.rsync.%stat in --fake-super sender by @oferchen in #4578
  • feat(fast_io): expose openat2_supported() probe helper (SEC-1.d) by @oferchen in #4643
  • feat(transfer): populate DeltaChunk.expected_strong from basis signature (BR-3i.d) by @oferchen in #4646
  • feat(fast_io): add DirSandbox + thread through receiver pipeline (SEC-1.e) by @oferchen in #4650
  • feat(match): zsync-inspired hash-chain pruning via consumed-bitset (ZSO-3) by @oferchen in #4654
  • feat(fast_io,engine): replace lstat/symlink_metadata with fstatat(AT_SYMLINK_NOFOLLOW) (SEC-1.f) by @oferchen in #4668
  • feat(rsync_io): warn on SSH stderr socketpair-to-pipe fallback (SSF-2) by @oferchen in #4663
  • feat(fast_io,transfer): replace remove_file/remove_dir with unlinkat (SEC-1.g) by @oferchen in #4671
  • feat(core): warn on double-compression when rsync --compress meets SSH -C (SSC-1) by @oferchen in #4667
  • feat(fast_io): mkdirat/symlinkat/linkat sandbox helpers (SEC-1.h) by @oferchen in #4683
  • feat(fast_io): renameat sandbox helper (SEC-1.j) by @oferchen in #4693
  • feat(transfer): wire renameat sandbox into deferred SEC-1.j receiver callers by @oferchen in #4697
  • feat(fast_io): add openat_via_sandbox_or_fallback + readlinkat_via_sandbox helpers (closes 16+ SEC-1 GAPs) by @oferchen in #4716
  • feat(fast_io,daemon): Landlock LSM defense-in-depth for daemon receiver (SEC-1.p) by @oferchen in #4702
  • feat(transfer): force-parallel env override + interop scenario crossing parallel threshold (PIP-4) by @oferchen in #4720
  • feat(transfer): thread DirSandbox through temp_guard/temp_cleanup (SEC-1.r) by @oferchen in #4723
  • feat(fast_io): recursive_unlinkat sandbox helper for SEC-1.q (SEC-1.s) by @oferchen in #4726
  • feat(transfer): thread DirSandbox through receiver --delete path (SEC-1.q2) by @oferchen in #4732
  • feat(engine): add DeltaWork -> DeltaChunk shape adapter (PIP-9.a) by @oferchen in #4737
  • feat(rsync_io): wire ssh_config Compression detection (SSC-3) by @oferchen in #4739
  • feat(engine): SpillError::PriorSpillsLost typed variant + consumer wiring (SPL-35..37) by @oferchen in #4749
  • feat(transport): add ssh_config Match condition evaluator (SSC-4.b) by @oferchen in #4790
  • feat(engine): add delete reorder buffer per DEL-1.b design (DEL-2.a) by @oferchen in #4792
  • feat(rsync_io): wire Host pattern matching into compression lookup (SSC-5.b) by @oferchen in #4797
  • feat(fast_io): add per-thread io_uring ring primitive (IUR-3.a) by @oferchen in #4793
  • feat(fast_io): mlock mmap'd basis window for SQPOLL safety (SQM-3) by @oferchen in #4796
  • feat(fast_io): migrate file_writer to per-thread io_uring ring (IUR-3.b) by @oferchen in #4804
  • feat(rsync_io): honour ssh_config Match blocks in compression lookup by @oferchen in #4803
  • feat(core): add sender-inc-recurse feature flag for INC_RECURSE interop by @oferchen in #4802
  • feat(fast_io): migrate socket_writer to per-thread io_uring ring (IUR-3.d) by @oferchen in #4806
  • feat(fast_io): migrate file_reader to per-thread io_uring ring (IUR-3.c) by @oferchen in #4807
  • feat(fast_io): lease per-thread BGID slice from BGE-4 pool (IUR-3.e) by @oferchen in #4811
  • feat(rsync_io): bounded timeout on SSH goodbye phase (SSR-4) by @oferchen in #4820
  • feat(daemon): per-module max connections directive (DMC-6) by @oferchen in #4816
  • feat(engine): add BarrierState + SlotData types per DG-2.a spec (DG-3.a) by @oferchen in #4826
  • feat(daemon): log when --max-co...
Read more

v0.6.2

Choose a tag to compare

@oferchen oferchen released this 16 May 14:50
c99bbbc

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

Choose a tag to compare

@github-actions github-actions released this 03 May 10:55

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

Choose a tag to compare

@github-actions github-actions released this 06 Apr 14:50

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

Choose a tag to compare

@oferchen oferchen released this 16 Mar 11:18

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

Choose a tag to compare

@github-actions github-actions released this 19 Feb 16:19

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

Choose a tag to compare

@github-actions github-actions released this 17 Feb 16:12

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

Choose a tag to compare

@oferchen oferchen released this 15 Feb 12:35

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

Choose a tag to compare

@github-actions github-actions released this 13 Feb 10:12

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

Choose a tag to compare

@github-actions github-actions released this 23 Jan 04:26

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