Fix: Oh-my-posh Slow Startup On Windows
Hey everyone,
I wanted to share my experience and a potential fix for a major performance issue I encountered while using oh-my-posh on Windows. I've been a long-time user of oh-my-posh across various systems like Windows, Linux, and macOS, and it's generally been smooth sailing. However, recently I ran into some serious slowdowns on a fresh Windows 11 install, and I wanted to share my findings in case it helps others.
The Problem: Slow PowerShell Startup and Prompt Delays
After a fresh install of Windows 11, I noticed that my PowerShell 7 startup time ballooned to around 5-8 seconds! Even after the initial startup, there were noticeable delays of a few seconds after each prompt. As someone who relies on the terminal for a significant portion of my workflow, this was incredibly frustrating.
I tried numerous troubleshooting steps to resolve this issue. These included adding exceptions to Windows Defender, disabling it entirely, reinstalling the operating system, and even testing on a different PC. I even went as far as trying scripts that completely remove Windows Defender modules to ensure it wasn't some weird interaction with the Defender. Unfortunately, none of these steps provided a solution. I was still facing 5-8 second delays for the first prompt after a reboot and 3-5 second delays after subsequent prompts.
Digging Deeper: Identifying the Culprit
Frustrated, I decided to dive deep into oh-my-posh to understand what was causing these delays. Using trace logging, I noticed that the commands related to Git were taking an unexpectedly long time, often exceeding 150ms. What was even more concerning was that these commands weren't directly calling Git; instead, they were invoking bash and then using bash to call Git. Specifically, I observed the following:
[TRACE] 21:20:44.993 terminal.go:RunCommand(bash -c git log --pretty=format:%cr -1) - 32.9452ms
[TRACE] 21:20:44.993 terminal.go:RunShellCommand() - 32.9452ms
[DEBUG] 21:20:45.022 terminal.go:RunCommand:280 → 21:20:45
[TRACE] 21:20:45.022 terminal.go:RunCommand(bash -c date +%H:%M:%S) - 29.5391ms
[TRACE] 21:20:45.022 terminal.go:RunShellCommand() - 29.5391ms
This revealed that oh-my-posh was attempting to use the first available WSL "bash" instance to execute Git commands, even when those commands were operating on files within the Windows file system (mounted under /mnt/c/). This reliance on bash created a dependency on WSL, and if you didn't have a bash executable readily available (e.g., from Git GUI or another source), the commands would fail or take an excessively long time.
The Solution: Ensuring bash is in Your Path
As an initial workaround, I added the bash executable from Git GUI to my system's PATH environment variable. This simple change resulted in an immediate and noticeable performance improvement. However, I knew this wasn't the ideal solution.
Root Cause: Theme Configuration and Inefficient Git Calls
Further investigation revealed that the theme I was using, the default tokyonight_storm theme, was the primary culprit. Instead of using dedicated modules to display Git information, the theme relied on custom "script" blocks that explicitly called Git commands through bash. This approach was inefficient and introduced the unnecessary dependency on WSL.
Here's an example of the problematic code within the theme configuration:
{
"type": "command",
"style": "plain",
"foreground": "p:white-blue",
"properties": {
"command": "git log --pretty=format:%cr -1 || date +%H:%M:%S",
"shell": "bash"
}
Recommendation: Update Themes to Use Dedicated Git Modules
I believe the best solution is to update themes like tokyonight_storm to utilize dedicated Git modules for displaying Git information. This would eliminate the need to call bash directly and improve performance, especially for users who don't have WSL enabled or don't have bash in their PATH.
Who This Helps
If you're experiencing long startup times with PowerShell and oh-my-posh on Windows, especially after a fresh installation, check if your theme is calling bash to execute Git commands. If it is, ensure that you have a bash.exe in your PATH, particularly if you have WSL enabled.
Impact: Significant Performance Improvement
By addressing this issue, I was able to reduce my PowerShell 7 startup time from a frustrating 5-8 seconds to a much more acceptable 1 second!
Theme Details
The problematic theme is the default tokyonight_storm theme, located here:
https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/themes/tokyonight_storm.omp.json
Operating System
This issue was observed on Windows.
Shell
The shell used was PowerShell.
Additional Information
I don't believe a log is necessary here, but I want to emphasize the significant improvement in PowerShell 7 startup time, from 5-8 seconds to approximately 1 second, after implementing the fix.
Optimize Your PowerShell Experience with oh-my-posh
oh-my-posh is a fantastic tool for customizing your terminal, but inefficient theme configurations can lead to performance bottlenecks. By understanding how your theme interacts with external commands like Git and bash, you can optimize your PowerShell experience and enjoy faster startup times.
Understanding the Role of Git in Shell Performance
Git integration is crucial for developers, but excessive or inefficient Git calls can significantly impact shell performance. oh-my-posh themes that rely on frequent Git status updates or complex Git commands should be carefully evaluated for their performance impact.
Leveraging PowerShell Modules for Enhanced Performance
PowerShell modules offer a more efficient and reliable way to access system information and execute commands. oh-my-posh themes should prioritize PowerShell modules over external commands like bash whenever possible.
Troubleshooting Slow PowerShell Startup Times
If you're experiencing slow PowerShell startup times, consider the following troubleshooting steps:
- Profile Your Startup: Use PowerShell's built-in profiling tools to identify the specific commands or scripts that are causing delays.
- Optimize Your PowerShell Profile: Remove unnecessary commands or scripts from your PowerShell profile.
- Review Your oh-my-posh Theme: Examine your oh-my-posh theme for inefficient commands or dependencies on external tools like bash.
- Update Your Modules: Ensure that all of your PowerShell modules are up to date.
- Disable Unnecessary Modules: Disable any PowerShell modules that you don't need.
Conclusion: A Faster, More Efficient PowerShell Experience
By addressing the performance issues related to bash calls in oh-my-posh themes, you can significantly improve your PowerShell startup time and overall terminal experience. Remember to prioritize PowerShell modules, optimize your theme configuration, and regularly troubleshoot performance bottlenecks to maintain a fast and efficient workflow.