diff --git a/services/qbittorrent.nix b/services/qbittorrent.nix index a4274a5..3fdb3d6 100644 --- a/services/qbittorrent.nix +++ b/services/qbittorrent.nix @@ -125,9 +125,22 @@ in FilePoolSize = 500; # keep more files open to reduce open/close overhead AioThreads = 24; # 6 cores * 4; better disk I/O parallelism + # Send buffer watermarks control how much upload data qBittorrent pre-reads + # from disk per peer. Pushed well above libtorrent defaults (and above + # high_performance_seed's 3 MiB) to let the disk I/O thread issue larger, + # less-frequent preadv() calls. Larger watermarks give ZFS's vdev aggregator + # (4 MiB limit, 128 KiB gap) more contiguous requests to merge per sweep. + # Memory cost is roughly watermark × active-peer-count; 6 MiB × a few hundred + # peers is well within muffin's RAM budget. SendBufferLowWatermark = 512; # 512 KiB -- trigger reads sooner to prevent upload stalls - SendBufferWatermark = 3072; # 3 MiB -- matches high_performance_seed - SendBufferWatermarkFactor = 150; # percent -- matches high_performance_seed + SendBufferWatermark = 6144; # 6 MiB -- bigger pre-reads per peer than high_performance_seed's 3 MiB + SendBufferWatermarkFactor = 200; # percent -- scale watermark more aggressively with upload rate + + # Maximum outstanding block requests per peer (libtorrent max_out_request_queue). + # Default 500. Tripled so libtorrent's disk I/O thread sees deeper per-peer + # request queues, giving it more contiguous blocks to coalesce into single + # preadv() calls before issuing them to the kernel. + RequestQueueSize = 1500; }; Network = {