CLI tool
Svetlitski/fcp avatar
Svetlitski/fcp

fcp: a parallel file copier that beats cp on SSDs

A significantly faster alternative to the classic Unix cp(1) command, copying large files and directories in a fraction of the time.

861 stars26 forksRustBSD-3-Clause

At a glance

What is it?
fcp is a Rust reimplementation of the Unix copy command for data-heavy copies: it walks directories and copies their contents across all cores at once, and on macOS it uses copy-on-write. The README is candid about the limits.
Who is it for?
Adopt fcp when you copy large trees on an SSD and the bottleneck is single-threaded traversal rather than the disk itself, and you need nothing beyond the basic source-and-destination semantics. Do not expect cp compatibility, since the tool covers only the common cases, and do not use it on spinning disks.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What fcp is and what it deliberately leaves out

fcp is described as a significantly faster alternative to the classic Unix cp(1) command, and the README is direct about its scope in the second sentence. It aims to handle the most common use cases of cp with much higher performance, and it does not aim to completely replace cp with its myriad options.

That framing matters more than it sounds. A copy command that reimplements cp faithfully would need every option: preserving attributes, sparse file handling, symbolic link semantics, device files, interactive prompts, reflink behaviour per filesystem. fcp instead implements the narrow path that most people use, and does it fast.

The usage text shows exactly how narrow that is:

code
fcp 0.2.1

USAGE:
    fcp [OPTIONS] SOURCE DESTINATION_FILE
    Copy SOURCE to DESTINATION_FILE, overwriting DESTINATION_FILE if it exists

    fcp [OPTIONS] SOURCE ... DESTINATION_DIRECTORY
    Copy each SOURCE into DESTINATION_DIRECTORY

OPTIONS:
    -h, --help
            Output this usage information and exit.

    -V, --version
            Output version information and exit.

Two usage forms, a help flag and a version flag. There is no recursive flag, because copying a directory is the expected behaviour rather than an option, and there is no preserve flag. The README notes that the listed options come from running fcp --help, which is a sign the tool expects to be self-describing rather than documented elsewhere.

The implementation is Rust, edition 2021, with a binary target at src/main.rs. The dependency list is short: nix for the platform layer and rayon for the parallelism. The dev dependencies add criterion for benchmarking and a local dev_utils package.

The repository layout has benches/ for the criterion benchmarks, fixtures/ for test data, dev_utils/ for the helper package, tests/ and src/.

Why parallelism is the whole idea

The Methodology section explains the performance claim, and the explanation is worth reading because it generalises beyond this tool.

The high performance is attributed to several factors but primarily to leveraging parallelism, distributing the work of walking directories and copying their contents across all of your machine's cores. The consequence, on a system with an SSD, is that more I/O requests are issued over the same period of time compared to a single-threaded approach, resulting in a higher-average queue depth, thus allowing higher utilization of the SSD as a function of its maximum IOPS, and correspondingly higher throughput.

That is a precise description of why single-threaded tools leave SSDs half idle. A modern NVMe drive can service thousands of requests in flight; a copy loop that reads one file, waits, writes it, and moves on keeps the queue nearly empty. Adding threads fills the queue, and the drive does the rest. The gain comes from the device being saturated, not from the CPU doing less work.

This is also why the tool's own caveat about hard disks matters. On a spinning disk, seeks are the bottleneck and more parallel requests do not help, they can hurt, because a queue of concurrent reads turns a sequential read into a random one. The README says fcp is optimized for systems with an SSD and that on systems with a HDD it may exhibit poor performance.

The second factor is macOS-specific. On macOS, and perhaps in the future on other operating systems, fcp uses the system's underlying copy-on-write capability, dramatically reducing the time needed to copy large files. The footnote to the macOS benchmark attributes the massive difference in that specific case to fcp using fclonefileat and fcopyfile under the hood.

Those are the two mechanisms: saturate the device with concurrent requests, and on APFS use the filesystem's own clone primitive instead of reading and rewriting bytes.

The benchmarks, and what the numbers actually say

The README's benchmarking section is unusually complete for a small tool, with the same tests run on macOS and Linux and a methodology note explaining the hardware.

The macOS runs were on a 2018 MacBook Pro with a 2.9 GHz six-core Intel Core i9, 16 GiB of RAM and an SSD, with APFS as the filesystem. The Linux runs were on a bare-metal AWS EC2 a1.metal instance with 16 CPUs, 32 GiB of RAM and an SSD, with XFS.

The results vary enormously, and the variation is the useful information.

On macOS, copying a directory of thirteen 512 MB files, fcp was approximately 822 times faster on average, with fcp's average time to copy around 4.5 milliseconds against cp's roughly 3.7 seconds. That figure is the copy-on-write path doing its job on a handful of large files, and the footnote attributes it to fclonefileat and fcopyfile. The Linux kernel source tree copy on macOS was about 6 times faster, with fcp at roughly 5.1 seconds against cp at around 30 seconds.

On Linux, the same kernel source copy was about 10 times faster, with fcp at roughly 675 milliseconds against cp at about 6.02 seconds. But the large-files case on Linux was only approximately 1.4 times faster, with fcp at around 8 seconds against cp at around 11.3 seconds.

The pattern is consistent. Many small files is where parallel traversal wins, because there the traversal and per-file overhead dominate. A few enormous files is where the filesystem's own primitives dominate on macOS and where the picture is much closer on Linux. If your workload is the first kind, the difference is dramatic. If it is the second on Linux, it is modest.

The README also includes a footnote on benchmarking on laptops, arguing that although in general you should avoid benchmarking on laptops, fcp is a developer tool and many developers work primarily on laptops, and that unlike Linux you cannot rent AWS EC2 macOS instances by the second.

Installing it across four package managers

fcp supports only Unix-like operating systems, Linux and macOS and the like, and the README offers four installation routes.

Pre-built binaries for some systems are available under the repository's releases. Installing with cargo requires Rust version 1.53.0 or newer:

sh
cargo install fcp

On Arch Linux there is an fcp-bin AUR package. On NixOS, as of version 21.11 fcp is included in the stable channel, with earlier versions available through nixpkgs-unstable, and the install command being:

sh
nix-env -iA unstable.fcp

And on macOS it is available through Homebrew:

sh
brew install fcp

The Rust requirement of 1.53.0 is worth noting because it dates the tool's core dependency set. That version is the release that introduced the IntoIterator changes to the standard library, and requiring it is what lets the code iterate over arrays by value without copying, which matters in a copier that is walking large collections.

The cargo requirement and the release history together give a picture of the project. The versions are v0.2.2 from 2026-04-23, v0.2.1 from 2021-07-21 and v0.2.0 from 2021-07-07. So there was a long gap and then a burst of activity, with the last release and the last push both from April 2026.

The package is on crates.io as fcp, and the README carries a packaging status badge pointing at Repology, which tracks how the tool is packaged across the various Linux distributions.

Limits: a narrow option set, a filesystem assumption, and benchmarks from one machine

The limits are visible in what the README states and in what it does not attempt.

The first is the option set. fcp does not aim to completely replace cp with its myriad options, so anything you rely on beyond copying sources into a destination is missing. Recursion is implicit rather than a flag, and there is no preserve mode. If your copy depends on carrying ownership, timestamps, extended attributes or hard links across, cp or rsync remains the tool.

The second is the storage assumption. The tool is optimized for SSDs and may exhibit poor performance on HDDs. That is a real constraint, not a footnote: a spinning-disk machine is where the parallel strategy is least likely to pay off, and where it is most likely to make the queue depth argument work against you.

The third is that the copy-on-write advantage is platform-specific. The README says macOS, and perhaps in the future on other operating systems. On Linux, the filesystem's own copy range and reflink behaviour, where the filesystem has it, is not being used in the same way, which is visible in the gap between the 822x macOS figure and the 1.4x Linux figure for the same workload.

The fourth is that the benchmarks are from specific machines. A 2018 MacBook Pro with APFS, and a bare-metal a1.metal instance with XFS. The macOS large-file result depends on APFS semantics and on the size of the file set; the Linux kernel source result depends on the source tree being many small files. Neither generalises to your workload without you running the same comparison.

The fifth is release maturity. The version is 0.2.2, the tool is not at 1.0, and the gap between 0.2.1 and 0.2.2 covers five years. A long gap means the dependency versions in a Cargo.lock are old, which is worth a look before you install it, and it means the tool is close to a personal project rather than a widely maintained utility.

fcp against cp, against rsync and against the filesystem tools

Two comparisons make the choice clearer.

The first is against cp itself, which is the comparison the benchmarks are built around. The difference in approach is that cp is a simple, single-threaded, portable program and fcp is a specialised parallel one. On an SSD with many files, the parallel traversal turns a latency-bound workload into a throughput-bound one, and the gain can be an order of magnitude. On a spinning disk or with a handful of enormous files, the two are close, and fcp may be behind. The honest summary is that fcp is a better copy command on modern storage for trees of many files, and nothing else.

The second comparison is against rsync. The two tools answer different questions. cp copies; rsync synchronises, computing what needs transferring and copying only that, optionally over a network, optionally compressed, optionally with deletion on the destination. For a first-time copy of a local tree, which is what fcp does, rsync's advantage mostly disappears, because everything needs copying anyway. For keeping a mirror in step, rsync wins outright and fcp has nothing to say about it.

There is a third family worth naming, the filesystem-native tools. On Btrfs and XFS, cp --reflink can create a copy-on-write clone instead of reading and writing bytes, which is the same trick fcp uses on macOS and achieves a similar effect. On APFS, cp has clonefile. So the copy-on-write win fcp demonstrates is not unique to fcp, it is available to cp on the filesystems that support it, and fcp's contribution there is to use it automatically and to parallelise everything around it.

So the case for fcp is narrow but real: you want a drop-in faster cp on an SSD, you are copying a tree rather than mirroring one, and you want the parallel traversal and the automatic copy-on-write without writing a wrapper yourself.

Editorial conclusion

Adopt fcp when you copy large trees on an SSD and the bottleneck is single-threaded traversal rather than the disk itself, and you need nothing beyond the basic source-and-destination semantics. Do not expect cp compatibility, since the tool covers only the common cases, and do not use it on spinning disks. Verify first that your filesystem is one where parallel reads help, that you accept the reduced option set, and that the version you install corresponds to the release whose benchmarks you are relying on, since the last release before this one was in 2021.

Frequently asked questions

How do I install fcp?

Pre-built binaries for some systems are on the repository's releases page. With cargo you need Rust 1.53.0 or newer and run cargo install fcp. There is also an fcp-bin package in the Arch Linux AUR, fcp is in the NixOS stable channel as of 21.11, and Homebrew provides it on macOS.

Why is fcp faster than cp?

The README attributes it primarily to leveraging parallelism, distributing the work of walking directories and copying their contents across all of your machine's cores. On an SSD that issues more I/O requests in the same period, raising the average queue depth and using more of the drive's maximum IOPS. On macOS it additionally uses the system's copy-on-write capability, with fclonefileat and fcopyfile under the hood.

Does fcp replace cp entirely?

No. The README says fcp does not aim to completely replace cp with all of its many options, and aims to handle the most common use cases with much higher performance. The documented usage is only a source to a destination file, or several sources into a destination directory, plus help and version flags.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. README
  4. Releases
  5. Svetlitski/fcp on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/svetlitski-fcp.svg)](https://hysenlabs.com/projects/svetlitski-fcp)

Was this useful?