๐ ZSHAND Profile Report Guideยถ
Overviewยถ
The ZSHAND Profile Report turns raw timing data into an actionable performance dashboard. It shows where shell startup time is spent and suggests optimizations.
๐ Related documentsยถ
| Run profile | Performance (ZSHAND_PROFILE_BUNDLE=1, zprofile) |
| Context | Architecture ยท Build System |
| Index | Documentation Index |
Grades at a glanceยถ
| Grade | Time | Meaning |
|---|---|---|
| A | < 50ms | Excellent |
| B | 50โ150ms | Good |
| C | 150โ250ms | Acceptable |
| D | 250โ500ms | Slow โ optimize |
| F | > 500ms | Very slow |
Async (deferred) time does not count toward the grade. Full scale: Performance Grading.
Table of Contentsยถ
- Generating a Profile Report
- Understanding the Report
- Performance Grading
- Configuring Exceptions
- Interpreting Recommendations
- Troubleshooting
Generating a Profile Reportยถ
Prerequisitesยถ
You must first run a profile session to collect timing data:
# Option 1: Profile current session (collects data on next shell start)
zprofile
# Option 2: Run full profiling bundle
zfull
Running the Reportยถ
Once profiling data is available, generate the report:
# Generate report (reads from default cache location)
zsh build/profile_bundle_report.zsh
# Or specify custom cache directory
zsh build/profile_bundle_report.zsh ~/.cache/zshand
The report will display:
- Executive performance summary
- Visual load timeline
- Smart insights with traffic light indicators
- Detailed breakdowns by component
- Actionable optimization opportunities
Understanding the Reportยถ
The report is organized into several sections, presented in order of importance:
1. Executive Summary ๐ยถ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ STARTUP PERFORMANCE SUMMARY โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ โ
โ Total Startup Time: 154.2ms Grade: C โญโญ โ
โ Async Operations: 221.6ms (deferred) โ
โ โ
โ Performance: โโโโโโโโโโโโโโโโโโ 1 ACCEPTABLE โ
โ โ
โ Bottleneck: Directory: core (71.1ms, 46.1) โ
โ Opportunity: Consider lazy loading 10-you-should-use plugin โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
What it shows:
- Total Startup Time: Actual blocking time before prompt appears
- Grade: A-F rating (see Performance Grading)
- Async Operations: Time saved by deferred/lazy loading
- Performance Bar: Visual representation (relative to 100ms ideal)
- Bottleneck: The slowest component identified
- Opportunity: Primary optimization recommendation
2. Load Timeline โฑ๏ธยถ
โ 0ms โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค 154.2ms โ
โ โ โ โ
โ โโ Core (71.1ms) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ 46% โ
โ โโ Plugins (30.4ms) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ 20% โ
Visual timeline showing:
- Proportional bars for each major component
- Percentage of total time
- Async operations listed separately ("AFTER PROMPT")
3. Smart Insights ๐กยถ
โ ๐ข Core system: Good (71.1ms) โ
โ Good - typical for feature-rich frameworks โ
โ โ
โ ๐ก Plugin ecosystem: Acceptable (30.4ms) โ
โ 10-you-should-use takes 16.3ms - consider lazy loading โ
Indicators:
- ๐ข Green: Excellent performance, no action needed
- ๐ก Yellow: Acceptable but could be optimized
- ๐ด Red: Slow, optimization recommended
Context-aware messages explain:
- Whether performance is normal for the component type
- Comparisons to typical setups
- Time savings from current optimizations
4. Section Deep Diveยถ
Detailed breakdowns for major sections (Core, Plugins, Hooks):
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ ๐ PLUGINS 30.4ms 19.7% of total โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 1. 10-you-should-use.zsh 16.3ms โโโโโโโโโโโโโโโโโโโโ 54% / 11% โ
โ 2. 99-zsh-syntax-highlighting.zsh 4.9ms โโโโโโโโโโโโโโโโโโโโ 16% / 3% โ
โ โ
โ Analysis: Acceptable - consider lazy loading heavy plugins โ
โ Action: Plugins are well-optimized โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
For each section:
- Shows top 5-8 slowest files
- Two percentages:
% of section/% of total - Visual bar scaled to slowest in section
- Analysis and recommended action
5. Optimization Opportunities ๐ฏยถ
โ Priority 1: HIGH IMPACT ๐ฐ๐ฐ๐ฐ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โข Lazy load 10-you-should-use plugin โ
โ Current: 16.3ms blocking Potential: ~14ms saved โ
โ How: Move to deferred loading or lazy widget โ
Priority levels:
- HIGH IMPACT ๐ฐ๐ฐ๐ฐ: Save >10ms
- MEDIUM IMPACT ๐ฐ๐ฐ: Save 5-10ms
- LOW IMPACT ๐ฐ: Save <5ms
WINS section shows what's already optimized:
โ ๐ WINS: You're already doing these right! โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Deferred operations save ~226.0ms from startup โ
โ โ 42 widgets use lazy loading (saves ~50-100ms) โ
Performance Gradingยถ
The report assigns an overall grade based on total startup time:
| Grade | Time Range | Stars | Meaning |
|---|---|---|---|
| A | < 50ms | ๐๐๐๐ | Excellent - lightning fast |
| B | 50-150ms | โญโญโญ | Good - smooth experience |
| C | 150-250ms | โญโญ | Acceptable - room for improvement |
| D | 250-500ms | โญ | Slow - optimization needed |
| F | > 500ms | ๐ | Very slow - significant issues |
Note: Async operations (deferred/lazy) don't count against your grade since they run after the prompt appears.
Configuring Exceptionsยถ
Sometimes a slow operation is acceptable because its value outweighs the cost. Use the exceptions configuration to suppress recommendations for these cases.
Exception File Locationยถ
config/profile-exceptions.conf
Formatยถ
- pattern: Glob pattern matching filename (e.g.,
*.zsh,exact-name.zsh) - max_time_ms: Maximum acceptable time in milliseconds
- reason: Documentation for why this is acceptable
Examplesยถ
# Allow you-should-use plugin up to 20ms
10-you-should-use.zsh|20|Command suggestions feature is worth the cost
# Allow any syntax highlighting plugin up to 10ms
*-syntax-highlighting.zsh|10|Syntax highlighting requires processing
# Allow atuin history search up to 15ms
02_atuin.zsh|15|Advanced history search integration justified
How It Worksยถ
- Report loads exceptions during startup
- When identifying slow operations, checks if they match exception patterns
- If time is within exception threshold, operation is filtered from recommendations
- Report shows "๐ NOTE: Exceptions Applied" with count
When to Use Exceptionsยถ
Good reasons:
- Feature provides significant value (e.g., advanced history search)
- Optimization would reduce functionality
- Plugin has no lazy-loading alternative
- Already at optimal speed for that type of operation
Bad reasons:
- Too lazy to investigate optimization
- Accepting poor performance as "normal"
- Not understanding the actual impact
Interpreting Recommendationsยถ
Plugin Optimizationยถ
Recommendation: "Lazy load {plugin} plugin"
What it means:
- Plugin loads during startup (blocking)
- Could be deferred until after prompt or first use
- Would save X milliseconds from perceived startup time
How to implement:
- Move plugin to deferred loading (loads after prompt):
- Or convert to lazy widget (loads on first use):
Core File Optimizationยถ
Recommendation: "Consider caching in core files"
What it means:
- Core initialization does expensive operations every startup
- Results could be cached and validated instead of regenerated
Example optimizations:
- Cache command existence checks
- Cache path validations
- Cache environment variable processing
Hook Optimizationยถ
Recommendation: "Review hook implementations"
What it means:
- Hooks run during startup and can accumulate time
- Some hook logic could be deferred or lazy-loaded
Common issues:
- Expensive API calls during startup
- Unnecessary file system operations
- Complex calculations that could be cached
Troubleshootingยถ
Problem: "No timing data found"ยถ
Cause: Profile data hasn't been collected
Solution:
# Run profiling first
zprofile # Or zfull
# Then restart shell and generate report
exec zsh
zsh build/profile_bundle_report.zsh
Problem: "No valid timing data found (total_time=0)"ยถ
Cause: Profile log exists but contains no valid measurements
Possible reasons:
- Profile was interrupted
- Log file is corrupted
- Using incompatible profiling mode
Solution:
# Clear old profile data
rm ~/.cache/zshand/profile-timing.log
# Run fresh profile
zprofile
exec zsh
Problem: Report shows strange formattingยถ
Cause: Terminal doesn't support box drawing characters or colors
Solutions:
- Use a modern terminal (kitty, alacritty, iTerm2, Windows Terminal)
- Ensure UTF-8 locale:
Problem: Exceptions not workingยถ
Possible causes:
- Pattern doesn't match
# Wrong: Using full path
/plugins/10-you-should-use.zsh|20|reason
# Right: Using basename only
10-you-should-use.zsh|20|reason
- Time threshold too low
# If plugin takes 16ms but threshold is 10ms
10-you-should-use.zsh|10|reason # Won't work
# Increase threshold
10-you-should-use.zsh|20|reason # Will work
- Syntax error in config
# Wrong: Missing delimiter
10-you-should-use.zsh 20 reason
# Right: Pipe-delimited
10-you-should-use.zsh|20|reason
Debug:
# Check if exceptions file is found
grep "exceptions_file=" build/profile_bundle_report.zsh
# Verify file content
cat config/profile-exceptions.conf
# Test pattern matching manually
pattern="10-you-should-use.zsh"
filename="/path/to/plugins/10-you-should-use.zsh"
[[ "${filename:t}" == ${~pattern} ]] && echo "Match!" || echo "No match"
Problem: Report takes too long to generateยถ
Cause: Large profile log with many entries
Solutions:
- Profile log contains multiple sessions - this is normal
- Report processes all data but only shows latest
- To speed up, clear old data periodically:
# Keep only last 50 lines
tail -50 ~/.cache/zshand/profile-timing.log > /tmp/profile-timing.log
mv /tmp/profile-timing.log ~/.cache/zshand/profile-timing.log
Advanced Usageยถ
Custom Cache Directoryยถ
# Profile with custom cache
ZSHAND_CACHE_DIR=/tmp/my-cache zprofile
# Generate report from custom cache
zsh build/profile_bundle_report.zsh /tmp/my-cache
Comparing Before/After Optimizationยถ
# 1. Generate baseline report
zprofile && exec zsh
zsh build/profile_bundle_report.zsh > before.txt
# 2. Make optimizations
# (edit configs, enable lazy loading, etc.)
# 3. Generate comparison report
rm ~/.cache/zshand/profile-timing.log
zprofile && exec zsh
zsh build/profile_bundle_report.zsh > after.txt
# 4. Compare
diff before.txt after.txt
# Or use: vimdiff before.txt after.txt
Continuous Monitoringยถ
Set up periodic profiling to track performance over time:
# Add to your cron or systemd timer
# Profile weekly and save reports
0 0 * * 0 cd ~/code/zshand && zprofile
Best Practicesยถ
1. Profile Regularlyยถ
- After installing new plugins
- After major configuration changes
- Monthly for maintenance
2. Focus on High-Impact Itemsยถ
- Optimize items marked HIGH IMPACT first
- Don't over-optimize items < 5ms
- Consider value vs. speed tradeoff
3. Document Exceptionsยถ
- Always include clear reasons in exception config
- Review exceptions periodically
- Remove exceptions when optimizations become available
4. Celebrate Winsยถ
- The WINS section shows what's working well
- Don't feel pressure to optimize everything
- 100-150ms startup is excellent for feature-rich shells
5. Understand Contextยถ
- Async operations don't impact user experience
- First startup vs. subsequent startups may differ
- Some "slow" operations provide significant value
๐ Related Documentsยถ
| Document | Purpose |
|---|---|
| โก Performance | Profiling pipeline and running zprofile |
| ๐๏ธ Architecture | Loading modes and boot sequence |
| ๐๏ธ Build System | Profile bundle compilation |
| ๐ Documentation Index | Full doc nav |
Supportยถ
For issues or questions:
- Check Troubleshooting section above
- Review existing documentation
- Open an issue with:
- Your report output (or relevant sections)
- Your exception config (if using)
- Your shell environment (
echo $SHELL,zsh --version)