Skip to content

perf(sftp): honour --parallel up to 16 connections, and say when a provider ceiling binds - #761

Open
axpnet wants to merge 1 commit into
mainfrom
perf/sftp-parallel-ceiling
Open

perf(sftp): honour --parallel up to 16 connections, and say when a provider ceiling binds#761
axpnet wants to merge 1 commit into
mainfrom
perf/sftp-parallel-ceiling

Conversation

@axpnet

@axpnet axpnet commented Sep 8, 2026

Copy link
Copy Markdown
Member

Summary

Finding 1 of the DAG engine review's before/after battery (test station, Hetzner lab over wired gigabit, 5000 x 4 KiB files). The SFTP transfer pool ceiling was a literal 4, so --parallel 16 delivered 4 connections without a word. The comment above the constant asked for a live benchmark on the target server before raising it; this battery is that benchmark, on two binaries.

Measured, from --parallel 4 to --parallel 16 on the same cell:

binary tool upload p4 p16 gain download p4 p16 gain
before #735 (3417fcb) rclone 687.47 s 366.92 s 47% 421.92 s 115.86 s 73%
before #735 AeroFTP 1391.20 s 1383.41 s 0.6% 1294.21 s 1293.45 s 0.1%
after #735 (38d5c0b) rclone 643.64 s 344.00 s 47% 431.57 s 109.89 s 75%
after #735 AeroFTP 330.52 s 316.02 s 4% 272.76 s 264.41 s 3%

#735 made every leg about four times faster (connection reuse), and the slope did not move: rclone keeps gaining from the step, AeroFTP does not, because the cap silently bound the flag. After this change on SFTP the first-pass sync is already ahead of rclone (313.60 s against 649.91 s) while get -r at p16 is still behind (264.41 against 109.89): one door still closed, this PR opens it.

Change.

  • SFTP_POOL_MAX_SESSIONS = 16, the same range as --sftp-concurrency; the effective count stays the lower of the ceiling and --parallel, so the default of 4 connections is unchanged. The list pool follows the transfer pool (it reads the same constant), so --checkers on SFTP is bounded by 16 too.
  • On every provider, put -r and get -r print a note when the provider ceiling is lower than the requested --parallel (text mode only; quiet, JSON and machine output stay silent). A flag that accepts 32 and delivers 4 without a word is worse than a lower documented limit.
  • CLI guide: the --parallel row names each provider's ceiling.

Tests

  • providers::sftp::tests::sftp_pool_ceiling_matches_the_intra_file_stream_range: the constant equals the intra-file stream range.
  • transfer_dag_batch::tests::sftp_pool_delivers_the_requested_parallelism_up_to_the_provider_ceiling: the door, not the guard. A pool-backed counting provider with the ceiling SftpProvider advertises, driven through the real ProviderDownloadExecutor and the batch DAG, resolved the way the CLI and the GUI resolve it, with a rendezvous that only opens when 8 downloads hold 8 sessions at once: --parallel 8 delivers 8, --parallel 32 delivers 16. With the literal 4 put back the test fails with left: 4, right: 8 after the rendezvous times out (seen, then restored).

The step measured from outside (rclone gains, AeroFTP does not) and this test from inside are independent measurements of the same door.

Verified: cargo fmt --all -- --check, cargo clippy --all-targets -- -D warnings (rc 0), the two tests above plus the existing SFTP scan-pool test, on the branch rebased onto 53ed27ce8.

Numbers to expect

The test station re-measures tree-small-p16-labsftp on the squash: expected, AeroFTP gains from p4 to p16 like rclone does; the p4 rows do not move (default unchanged).

Summary by CodeRabbit

  • New Features

    • Multi-file SFTP transfers can now use up to 16 concurrent connections when requested with --parallel.
    • Recursive transfers display a note when the provider limits concurrency below the requested value. This message is shown only in text mode.
  • Documentation

    • Updated CLI guidance to clarify parallelism defaults, maximums, and provider-specific limits.

…ovider ceiling binds

The SFTP pool ceiling was a literal 4, so --parallel 16 delivered 4 connections without a word. The comment above it asked for a live benchmark on the target server before raising it; the DAG engine review battery on the Hetzner lab (wired gigabit, 5000 x 4 KiB files, 2026-09-08) is that benchmark, on two binaries. From --parallel 4 to 16 rclone gained 47% on upload (687 s to 367 s) and 73% on download (422 s to 116 s); AeroFTP moved under 1% (1391 s to 1383 s, 1294 s to 1293 s) because the cap silently bound the flag. After the SFTP connection reuse of #735 made every leg four times faster the slope was unchanged: rclone still gained 47% and 75% from the same step, AeroFTP 4% and 3% (331 s to 316 s, 273 s to 264 s). The ceiling is now 16, the same range as --sftp-concurrency; the effective count stays the lower of the ceiling and --parallel, so the default of 4 connections is unchanged.

On every provider, put -r and get -r now print a note when the provider ceiling is lower than the requested --parallel (text mode; quiet, JSON and machine stay silent): a flag that accepts 32 and delivers 4 without a word is worse than a lower documented limit.

Tests: the SFTP ceiling equals the intra-file stream range; and the door itself, a pool-backed counting provider with the ceiling SftpProvider advertises, driven through the real provider executor and the batch DAG with a rendezvous that only opens when 8 downloads hold 8 sessions at once: --parallel 8 delivers 8, --parallel 32 delivers 16, and with the literal 4 put back the test fails with 4 against 8.
Signed-off-by: axpnet <45786925+axpnet@users.noreply.github.com>
@snyk-io

snyk-io Bot commented Sep 8, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 592c188d-7ddf-4319-8db8-7597cd54acaa

📥 Commits

Reviewing files that changed from the base of the PR and between 53ed27c and e18eacf.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • docs/CLI-GUIDE.md
  • src-tauri/src/bin/aeroftp_cli.rs
  • src-tauri/src/providers/sftp.rs
  • src-tauri/src/transfer_dag_batch.rs

Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The SFTP transfer pool ceiling increases from 4 to 16 sessions. The CLI reports lower provider ceilings in text mode. Tests verify requested parallelism and ceiling enforcement.

Changes

SFTP parallel transfers

Layer / File(s) Summary
Raise the SFTP pool ceiling
src-tauri/src/providers/sftp.rs
The SFTP executor ceiling is 16 sessions. The default remains 4 through min(ceiling, --parallel). A unit test verifies the ceiling.
Report provider parallelism limits
src-tauri/src/bin/aeroftp_cli.rs, docs/CLI-GUIDE.md, CHANGELOG.md
The CLI prints a stderr note when the resolved provider ceiling is below --parallel. Quiet, JSON, and machine modes remain silent. Documentation records the new behavior.
Validate delivered session concurrency
src-tauri/src/transfer_dag_batch.rs
A counting provider measures active sessions. Integration coverage verifies requests of 8 sessions and requests above the SFTP ceiling.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to e18ea

The SFTP concurrency increase and provider-capacity notice preserve the documented limits and output-mode behavior. No actionable merge risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant TransferSettings
  participant SFTPProvider
  participant ProviderDownloadExecutor
  participant StorageSessions
  CLI->>TransferSettings: resolve --parallel and provider ceiling
  TransferSettings->>SFTPProvider: get maximum sessions
  SFTPProvider-->>TransferSettings: return ceiling 16
  TransferSettings-->>CLI: return effective concurrency
  CLI->>ProviderDownloadExecutor: execute batch
  ProviderDownloadExecutor->>StorageSessions: open effective number of sessions
  StorageSessions-->>ProviderDownloadExecutor: complete transfers
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 2 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: raising SFTP parallelism to 16 connections and reporting when a provider ceiling limits the requested value.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 2 files. (3 skipped: 2 unsupported, 1 too large.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/sftp-parallel-ceiling

Warning

Some tools did not complete. Review the errors below.

🔧 ast-grep (0.45.2)
src-tauri/src/bin/aeroftp_cli.rs

ast-grep timed out on this file


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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