---
title: How PhotoStructure copies your files
url: https://photostructure.com/guide/file-copy-strategies/
description: How PhotoStructure copies files to your library, and how to troubleshoot copy failures on TrueNAS/ZFS and other NAS systems.
date: 2026-01-21
keywords: file-copy-strategies, library, NAS, settings, permissions, troubleshooting
---


If you have [automatic library
organization](/getting-started/automatic-library-organization/) enabled,
PhotoStructure copies photos and videos from your source directories into your
library. Your photos are irreplaceable, so PhotoStructure takes extra care to
make sure copies succeed:

- **Automatic strategy detection**: Different filesystems have different quirks.
  PhotoStructure tests several copy methods and picks the one that works for
  your setup.
- **Error handling**: Common permission errors (especially on NAS
  devices like TrueNAS) are automatically retried with more compatible settings.
- **Checksum verification**: After each copy, PhotoStructure compares SHA
  checksums to confirm the file arrived intact.

_TL;DR: The defaults work for most users. If file copies are failing or you want
to understand what is happening, read on._

## ❓ What is a file copy strategy?

A "file copy strategy" is the method PhotoStructure uses to copy files. Each
strategy has different trade-offs:

- **Speed**: Some methods are faster than others
- **Atomicity**: Whether a partial copy can leave a corrupt file behind
- **Metadata preservation**: Whether file permissions and timestamps are copied
- **Compatibility**: Whether the method works on all filesystems

## 🔧 Available strategies

PhotoStructure supports six file copy strategies, controlled by the
`fileCopyStrategy` setting:

### ⚙️ `auto` (default)

PhotoStructure automatically tests each strategy when you open your library and
selects the first one that works. This is the recommended setting for most
users.

The test runs once per hour and creates small temporary files in your library's
originals directory to verify that copying and renaming work correctly.

### ⚡ `builtin-reflink`

Uses Node.js with "reflink" support (also called "copy-on-write" or "CoW").

**What's a reflink?** On modern filesystems like
[ZFS](https://en.wikipedia.org/wiki/ZFS),
[btrfs](https://en.wikipedia.org/wiki/Btrfs), and
[APFS](https://en.wikipedia.org/wiki/Apple_File_System), a reflink creates an
instant "copy" that doesn't actually duplicate the data on disk. Instead, both
files point to the same underlying data blocks. The filesystem only creates new
blocks when one of the files is modified. This saves time and disk space.

If your filesystem doesn't support reflinks, this strategy automatically falls
back to a traditional copy with negligible overhead.

### 🔨 `builtin`

Uses Node.js without reflink support. This is essentially the same as
`builtin-reflink` on filesystems that don't support copy-on-write.

### 🚀 `builtin-no-wip`

Uses Node.js but skips the "work-in-progress" (`.wip`) pattern.

**What's the `.wip` pattern?** Normally, PhotoStructure copies files to a
temporary name (like `.WIP-abc123-photo.jpg`) and then renames it to the final
name. This ensures that if PhotoStructure crashes mid-copy, you won't have a
partial, corrupt file in your library.

Some filesystems (particularly certain network filesystems) have trouble with
file renames. If you see errors about rename operations failing, try this
strategy.

### 💾 `native-preserve`

Uses your operating system's native copy command (`cp -a` on Linux, `ditto` on
macOS, `Copy-Item` on Windows) with full metadata preservation.

**What's metadata preservation?** This copies not just the file contents, but
also permissions, ownership, extended attributes, and other filesystem metadata.

This strategy can fail on some NAS systems (see [TrueNAS/ZFS
troubleshooting](#truenaszfs-permission-errors) below).

### 📦 `native`

Uses the native copy command without metadata preservation (`cp -f` on Linux,
`ditto --norsrc` on macOS). This is the most compatible option but doesn't
preserve file permissions.

## 🤔 When to change from `auto`

The `auto` setting works well for most users. You might need to change it if:

1. **You want to force reflinks**: Set `builtin-reflink` if you know your
   filesystem supports copy-on-write and want to ensure reflinks are used.

2. **You're having rename errors**: Set `builtin-no-wip` if file renames fail on
   your network filesystem.

3. **You need metadata preservation**: Set `native-preserve` if you specifically
   need file permissions copied (and your filesystem supports it).

4. **Nothing else works**: Set `native` as a last resort for maximum
   compatibility.

## ⚙️ How to change the strategy

You can set the strategy in your `settings.toml` file:

```toml
fileCopyStrategy = "builtin-reflink"
```

Or via environment variable:

```bash
PS_FILE_COPY_STRATEGY="builtin-reflink"
```

Valid values: `auto`, `builtin-reflink`, `builtin`, `builtin-no-wip`,
`native-preserve`, `native`

## 🚨 TrueNAS/ZFS permission errors

If you're running PhotoStructure on [TrueNAS](https://www.truenas.com/) (formerly
FreeNAS) and file copies are failing with "permission denied" or "operation not
permitted" errors, you may be hitting a ZFS ACL restriction.

### ❌ The problem

TrueNAS defaults SMB (Windows file sharing) datasets to
`aclmode=restricted`. This setting rejects attempts to change file permissions
on files that have non-trivial
[ACLs](https://en.wikipedia.org/wiki/Access-control_list) (Access Control
Lists).

When PhotoStructure (or any application) tries to copy a file with `cp -a`
(which preserves permissions), ZFS rejects the permission-setting operation with
an `EPERM` (operation not permitted) error.

### ✨ PhotoStructure's automatic fix

When PhotoStructure detects this permission error, it automatically retries the
copy without the permission-preservation flags. This means your copied files
will have default permissions rather than preserving the source file's
permissions.

For most photo libraries, this is perfectly fine: you typically want all photos
readable by the same user anyway.

### 🔧 TrueNAS fix (optional)

If you want to preserve file permissions, you can change the ZFS ACL mode:

```bash
zfs set aclmode=passthrough poolname/dataset
```

Replace `poolname/dataset` with your actual pool and dataset path.

**Caution**: This changes how ZFS handles ACLs for the entire dataset. Review
the [TrueNAS documentation](https://www.truenas.com/docs/) and understand the
implications before making this change, especially on production systems.

For more details on `aclmode`, see this [TrueNAS community
discussion](https://www.truenas.com/community/threads/who-can-explain-aclmode-discard-passthrough-and-restricted-with-example.116509/).

## 📊 Strategy comparison table

| Strategy          | Speed     | Atomic | Reflink | Preserves metadata |
| ----------------- | --------- | ------ | ------- | ------------------ |
| `auto`            | Varies    | Yes    | Maybe   | No                 |
| `builtin-reflink` | Fastest\* | Yes    | Yes     | No                 |
| `builtin`         | Fast      | Yes    | No      | No                 |
| `builtin-no-wip`  | Fast      | No     | No      | No                 |
| `native-preserve` | Slower    | Yes    | No      | Yes                |
| `native`          | Slower    | Yes    | No      | No                 |

\* On copy-on-write filesystems (ZFS, btrfs, APFS); same speed as `builtin` on
other filesystems.

**Atomic**: Whether a crash during copy can leave a corrupt file. "Yes" means
PhotoStructure uses a temporary file and rename, so crashes are safe.

**Reflink**: Whether the strategy can use copy-on-write for instant,
space-saving copies.

**Preserves metadata**: Whether file permissions and extended attributes are
copied.

## ⚡ Why "builtin" strategies are faster

The `builtin` strategies use Node.js's built-in file copying, which runs
entirely within the PhotoStructure process. The `native` strategies spawn a
separate process (`cp`, `ditto`, or PowerShell), which has overhead from:

- Process creation (forking)
- Security scanners (like Windows Defender or macOS Gatekeeper) checking the
  spawned process
- Inter-process communication

For copying many small files, this overhead adds up significantly.

## 👴 Deprecated settings

Previous versions of PhotoStructure used two boolean settings:

- `fileCopyOnlyNative` - forced use of native copy commands
- `fileCopyWithReflink` - enabled reflink support

These settings are now deprecated. If you have them in your `settings.toml`,
PhotoStructure will automatically migrate them:

- `fileCopyOnlyNative = true` becomes `fileCopyStrategy = "native-preserve"`
- `fileCopyWithReflink = true` becomes `fileCopyStrategy = "builtin-reflink"`
- Otherwise becomes `fileCopyStrategy = "builtin"`

You can safely remove the old settings from your configuration files.

## ✅ Verifying file copies

PhotoStructure can verify that copied files match their originals by comparing
[SHA](https://en.wikipedia.org/wiki/SHA-1) checksums (cryptographic
fingerprints). This catches rare but serious problems like:

- Silent data corruption during transfer
- Network glitches on NAS systems
- Filesystem bugs
- Failing storage hardware

### 🔍 How verification works

1. Before copying, PhotoStructure computes the SHA checksum of the source file
2. After copying, it computes the SHA of the destination file
3. If the checksums don't match, the copy is considered failed
4. PhotoStructure retries the comparison briefly to handle network filesystems
   where writes may not be immediately visible

### ⚙️ The `fileCopyVerify` setting

Copy verification is controlled by the `fileCopyVerify` setting:

```toml
fileCopyVerify = true
```

Or via environment variable:

```bash
PS_FILE_COPY_VERIFY="true"
```

**Default**: `true` (verification enabled)

### 🤔 Should I disable verification?

Verification is enabled by default because data integrity is critical for
irreplaceable photos and videos. However, you might consider disabling it if:

- You're doing a large initial import and want maximum speed
- Your storage is already protected by checksumming (ZFS, btrfs with scrubbing)
- You've verified your hardware and network are reliable

**We recommend**: Leave it enabled. The performance cost is one extra file read
per copy. If a copy fails verification, you'll know immediately rather than
discovering corruption months or years later.

## 🔨 Troubleshooting

### ⚠️ "File copy test failed" in health check

If you see this error on the PhotoStructure health page:

1. Check that PhotoStructure has write permission to your library directory
2. Check that your filesystem isn't full
3. Try setting `fileCopyStrategy` to `native` as a fallback
4. Check your system logs for more detailed error messages

### 🐢 Copies are very slow

If file copies are slower than expected:

1. Make sure you're using a `builtin` strategy (not `native`)
2. If using a NAS, check your network connection speed
3. Consider whether your source or destination drives are the bottleneck

### 🔐 Files have wrong permissions after copy

The `builtin` strategies don't preserve file permissions. If you need
permissions preserved:

1. Set `fileCopyStrategy = "native-preserve"`
2. On TrueNAS/ZFS, you may need to set `aclmode=passthrough` (see above)

## See also

- [How do I safely store my files?](/faq/how-do-i-safely-store-files/) - NAS
  recommendations and backup strategies
- [What is a volume?](/faq/what-is-a-volume/) - Understanding how PhotoStructure
  sees your storage
- [Using environment variables](/faq/environment-variables/) - How to configure
  PhotoStructure via environment variables

