rsync is often described as the command that "only sends the differences," which is accurate and still too vague. That slogan hides the part that makes the tool durable. rsync is not one clever checksum trick wrapped in a Unix command. It is a narrow update machine with three separate layers that happen in sequence: first a file-list comparison that tries hard to skip work, then a block-matching phase that reuses bytes from the existing destination file, and finally a process pipeline that overlaps file selection, delta construction, and writes.[1][2][3]
The official rsync documentation still points readers back to the original technical report and to a practical implementation overview, which is a good clue about why the tool has lasted.[4] Its staying power comes less from a fashionable transport or a polished UI than from an architecture that remains honest about bandwidth, latency, and disk I/O. If you read rsync that way, a lot of its seemingly odd behavior stops being odd.
Image context: the cover uses a real portrait photograph of Andrew Tridgell rather than a terminal screenshot. That choice fits because the piece is about the original design logic of rsync more than about one command-line example. The architecture is the story: cheap file triage, rolling block search, and a pipeline built to keep a slow link productive.[5]
The first filter is not the rolling checksum
Many people talk about rsync as if it rolls checksums across every file by default. That is not how the utility prefers to work. The project’s implementation overview says the generator process first compares the shared file list against the local directory tree and checks whether each file can be skipped.[2] In the common mode, a file is skipped unless its modification time or size differs; only when --checksum is requested does rsync compute a file-level checksum for the pre-transfer decision.[2][3]
That first layer matters because it keeps the expensive part of rsync from becoming the normal part. The file list itself already contains the pathnames plus ownership, mode, permissions, size, and modification time, and it can also carry checksums when the caller explicitly asks for them.[2] For a large tree where most files are unchanged, rsync wins by deciding not to perform block matching at all on the majority of files.
The man page draws a useful boundary here. It separates the before-transfer “does this file need updating?” check from the after-transfer verification checksum that confirms the rebuilt file arrived correctly.[3] Those two checks are easy to blur together in casual explanations, but they solve different problems. The first is about avoiding unnecessary work. The second is about verifying correctness once work has already been chosen.
This is also why rsync can feel less magical than its reputation suggests. A lot of the time it is behaving like a careful file-list engine before it behaves like a delta engine. The rolling checksum gets the fame; the skip logic does a great deal of the routine labor.
The second layer is a search problem against the basis file
Once a file cannot be skipped, rsync changes modes. The existing destination copy becomes the “basis file,” and the receiver side generates block checksums for that basis file and sends them to the sender.[2] At that point the architecture becomes the one described in the 1996 technical report: update a file across a low-bandwidth, high-latency bidirectional link by identifying pieces of the source that already match pieces of the destination and only shipping what cannot be matched.[1]
The technical report’s key move is to split matching into a cheap weak checksum and a more expensive strong checksum.[1] The weak checksum is “rolling,” which means the sender can update it efficiently as it slides one byte at a time across the source file instead of recalculating each block from scratch.[1] The official practical overview describes the same behavior in operational terms: generate a checksum for the current block, look for it in the set supplied by the generator, and if no match is found, append the unmatched byte to literal data and advance by one byte before trying again.[2]
When a weak checksum matches, rsync does not trust it blindly. The technical report explains that the strong checksum is computed only for the candidate match, because that stronger comparison is more expensive and should be reserved for the cases where the cheap filter says “maybe.”[1] The sender is therefore solving a layered search problem: use the rolling checksum as a fast moving index, use the strong checksum to reject false positives, and then emit a compact description of the new file as literal data plus references to matching blocks in the basis file.[1][2]
Two things follow from this design. First, rsync works best when the files are similar, because similarity increases the number of reusable blocks and makes the search worth the trouble.[1] Second, the utility is not doing content-addressed storage in the modern object-store sense. It is doing localized reuse against one already existing basis file. The destination copy is not just an endpoint. It is part of the algorithm.
The third layer is the part most summaries forget: the pipeline
The original report includes a short section on pipelining, but the practical overview makes the implementation consequence much clearer.[1][2] After the file list is shared, rsync behaves as a pipeline:
generator -> sender -> receiver
The generator manages file-level logic and decides what can be skipped; the sender reads file indexes and block checksum sets, builds the delta stream, and passes it on; the receiver writes the updated data to disk.[2] Each process can continue independently except when it stalls on CPU, disk, or the pipeline itself.[2]
This is easy to miss if you think only in terms of “run rsync once, get a copied tree.” Architecturally, rsync is not one process that alternates between every task. It is a coordinated flow that lets file selection, checksum matching, and writing overlap. The technical report’s pipelining section frames the benefit directly: once several files are involved, latency can be reduced by having one process send checksums while another simultaneously receives and reconstructs file differences, keeping both directions of the link busy for most of the time.[1]
That detail helps explain why rsync often feels sturdier on real links than toy descriptions imply. The algorithm matters, but the process model matters too. Even a good block-matching method would disappoint if every phase had to finish completely before the next one started. rsync gets part of its character from refusing to serialize the whole job.
The transport boundary is narrower than “SSH versus daemon”
The man page describes two basic remote transports: use a remote-shell program such as SSH, or connect directly to an rsync daemon over TCP, usually on port 873.[3] That sounds like a simple either-or choice, but the distinction is more revealing when read as an architectural boundary.
Remote-shell transport treats rsync as an endpoint process spawned inside another secure connection. Daemon mode treats rsync as a service with named modules and socket-level protocol behavior.[2][3] The man page is explicit that “server” does not necessarily mean daemon, because the remote side can just as easily be a process started by the shell transport.[3] The practical overview adds a useful nuance: from rsync’s perspective, a remote-shell session is really a pair of pipes, and the network disappears behind that abstraction.[2]
This split tells you what rsync is willing to own. It owns file lists, basis-file matching, and reconstruction. It does not insist on owning the surrounding trust and access model. Use SSH if you want the shell and host-authentication layer to stay outside rsync. Use daemon mode if you want rsync-native modules and service behavior. There is even a hybrid path where a remote shell spawns a single-use daemon-style server process.[3]
That restraint is also why the delta engine is not always used. The man page notes that --whole-file disables the delta-transfer algorithm and can be faster when link bandwidth is higher than disk bandwidth, especially when the “disk” is itself networked.[3] In other words, rsync is not religious about block matching. It uses the algorithm when the architecture suggests it will help.
What rsync still teaches
The strongest lesson in rsync is not “rolling checksums are clever.” It is that good synchronization starts by narrowing the problem. First decide which files deserve attention. Then do local reuse against a known basis file. Then pipeline the work so the CPUs, disks, and link are not waiting on one another more than necessary.[1][2][3]
That is why rsync still reads as a serious piece of systems design in 2026. The tool keeps its promises by being precise about where it spends effort and by refusing to turn synchronization into a single undifferentiated copy operation. Once you understand those boundaries, rsync stops looking like an old Unix incantation that somehow survived. It starts looking like a carefully staged machine that still knows when not to do work.
Sources
- Andrew Tridgell and Paul Mackerras, "The rsync algorithm" - original technical report on basis-file matching, rolling checksums, strong checksums, and pipelining over low-bandwidth, high-latency links.
- Joe Mack, "How Rsync Works" - official practical overview of rsync roles, file-list construction, generator/sender/receiver pipeline, basis files, and block checksum flow.
- rsync(1) manual page - quick-check behavior, remote-shell versus daemon transports, and the
--whole-fileboundary. - Official rsync documentation index - the project's own entry point linking the man page, technical report, thesis, and implementation overview.
- Wikimedia Commons file page for the portrait used as the article image, "File:Andrew Tridgell.jpg".