Skip to content

perf: lazy imports and session reuse for 93% faster CLI startup#67

Open
Copilot wants to merge 12 commits intomainfrom
copilot/improve-cli-latency-performance
Open

perf: lazy imports and session reuse for 93% faster CLI startup#67
Copilot wants to merge 12 commits intomainfrom
copilot/improve-cli-latency-performance

Conversation

Copy link

Copilot AI commented Feb 24, 2026

📥 Pull Request

✨ Description of new changes

Deferred heavy imports (msal, jwt, cryptography, requests, prompt_toolkit, psutil) that were loaded on every CLI invocation — even for fab --version.

Changes

  • Lazy command loading — new lazy_command() utility in fab_lazy_load.py defers command module imports in all 9 parser files until the command is actually invoked
  • Deferred auth & interactive imports in main.py — auth stack (~160ms) and prompt_toolkit (~64ms) only load when needed
  • Deferred psutil in fab_context.py — moved into _get_context_session_id() with TYPE_CHECKING guard for mypy
  • Config write optimization in fab_state_config.pyinit_defaults() skips file write when nothing changed
  • HTTP session reuse in fab_api_client.py — shared requests.Session with retry adapter for connection pooling
  • Extracted fab_describe_commands.py — separated heavy describe logic from parser registration

Results

Metric Before After
Module import time ~737ms ~54ms
Heavy deps at startup msal, jwt, cryptography, requests, prompt_toolkit None

8 new tests covering lazy loading, startup threshold, session reuse, and config optimization.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits February 24, 2026 12:20
- Defer auth module imports in main.py (~160ms saved)
- Defer interactive mode imports in main.py (~64ms saved)
- Add lazy_command() utility in fab_lazy_load.py for deferred command loading
- Apply lazy command loading to all parser modules (fs, acls, api, auth, config, jobs, labels, tables, describe)
- Defer psutil import in fab_context.py (~9ms saved)
- Optimize init_defaults() to skip config write when unchanged
- Add session reuse in fab_api_client.py for connection pooling
- Move describe_parser command functions to separate module for lazy loading
- Update test mock paths for lazy imports

Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
…ype hint

Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
Copilot AI changed the title [WIP] Analyze and improve CLI latency and performance perf: lazy imports and session reuse for 93% faster CLI startup Feb 24, 2026
Copilot AI requested a review from ayeshurun February 24, 2026 12:27
Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
@ayeshurun
Copy link
Owner

@copilot how can i test your changes and see the perf improvment?

Copy link
Author

Copilot AI commented Feb 24, 2026

@copilot how can i test your changes and see the perf improvment?

You can measure the improvement with Python's -X importtime flag or simple timing:

1. Quick before/after import time:

# On the main branch (before):
git stash && git checkout main
python -c "import time; s=time.perf_counter(); import fabric_cli.main; print(f'{(time.perf_counter()-s)*1000:.0f}ms')"

# On this branch (after):
git checkout copilot/improve-cli-latency-performance
python -c "import time; s=time.perf_counter(); import fabric_cli.main; print(f'{(time.perf_counter()-s)*1000:.0f}ms')"

2. Detailed import profiling:

python -X importtime -c "import fabric_cli.main" 2>&1 | sort -t'|' -k2 -rn | head -20

This shows cumulative import times per module — you'll see msal, jwt, cryptography, requests, and prompt_toolkit are no longer in the top imports.

3. End-to-end CLI timing:

time fab --version
time fab --help

4. Run the automated perf tests included in this PR:

python -m pytest tests/test_utils/test_lazy_load.py -v

This runs 8 tests including test_main_module_import__under_threshold (asserts import < 500ms) and test_heavy_modules_not_imported_at_startup (verifies msal, jwt, cryptography are not loaded at import time).

On the CI environment I measured ~737ms → ~54ms for the module import (93% reduction).

@ayeshurun
Copy link
Owner

@copilot the fab:build type check code failed. fixed it

Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
Alon Yeshurun and others added 2 commits February 26, 2026 13:30
- Add Accept-Encoding gzip/deflate header for compressed responses
- Increase connection pool from 10 to 20 for better connection reuse
- Default GET timeout to 30s (was 240s); writes stay at 240s

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
Copilot AI requested a review from ayeshurun March 1, 2026 10:59
Co-authored-by: ayeshurun <98805507+ayeshurun@users.noreply.github.com>
Copilot AI requested a review from ayeshurun March 1, 2026 11:06
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.

2 participants