Skip to content

Allow opt-in command concurrency via environment variables (high-latency storage) - #46

Open
sebclark wants to merge 1 commit into
Chaptarr:developfrom
sebclark:opt-in-concurrency
Open

Allow opt-in command concurrency via environment variables (high-latency storage)#46
sebclark wants to merge 1 commit into
Chaptarr:developfrom
sebclark:opt-in-concurrency

Conversation

@sebclark

@sebclark sebclark commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Problem

Two hardcoded ceilings serialize all disk-bound work, inherited from Readarr:

  1. CommandQueueManager constructs new CommandQueue() with no limit function, so the disk-access group limit falls back to 1 — every RequiresDiskAccess command runs strictly serially.
  2. CommandExecutor has THREAD_LIMIT = 3 — the hard ceiling on total command concurrency, which silently caps whatever the queue would otherwise allow.

On libraries held on high-latency storage (FUSE / network mounts — mergerfs, rclone, NFS are common in this community) per-file latency dominates, and serial scanning is pathological: threads spend nearly all their time blocked on I/O for one file at a time.

Change

Both ceilings become configurable via environment variables:

  • CHAPTARR_DISK_ACCESS_LIMIT (default 1, unchanged)
  • CHAPTARR_COMMAND_THREADS (default 3, unchanged)

Defaults preserve current behaviour exactly — nothing changes unless a user opts in. Doc comments explain the pairing (raising the disk limit alone does nothing without threads to run the extra commands).

Measurements

Large audiobook library (six-figure file count) on a mergerfs-over-SFTP mount: sequential file access measured ~418ms/file; at 8-way it fell to ~67ms effective. Raising both variables to 8 made metadata operations roughly 5.7× faster. We have been running these settings in production for several days across a range of values.

One practical note from that experience: past ~2–3× the host's core count the returns invert on CPU-bound stages, so the docs deliberately frame this as for high-latency storage rather than a general "make it faster" knob.

Two hardcoded ceilings serialize all disk-bound work:

- CommandQueue's disk-access limit function defaults to 1, so every
  RequiresDiskAccess command runs strictly serially
- CommandExecutor's THREAD_LIMIT of 3 caps total command concurrency

Both are now configurable via CHAPTARR_DISK_ACCESS_LIMIT and
CHAPTARR_COMMAND_THREADS. Defaults are unchanged (1 and 3), so behaviour
is identical unless a user opts in.

On libraries held on high-latency storage (FUSE/network mounts) the
per-file latency dominates and serial scanning is pathological: measured
on a large library on a mergerfs/SFTP mount, raising both made metadata
operations roughly 5.7x faster.
@sebclark
sebclark force-pushed the opt-in-concurrency branch from 796055b to 7266cfd Compare August 15, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant