2 minutes
Speed Up slow PHP_CodeSniffer execution on Windows
As projects grow, tool performance can silently degrade until it becomes unbearable. I recently hit a wall where phpcs
(PHP_CodeSniffer) took over 41 minutes to run on a Windows machine. For a local feedback loop, this is a
productivity killer.
After a few optimizations, I managed to get the execution time down to under 1 minute (cold) and ~3.3 seconds (cached). Here is how.
The Analysis
The project consists of about 3,549 files and roughly 176k lines of code (LOC). While substantial, it should not justify a 41-minute wait.
Performance Benchmarks
- Initial state: 41:23 min
- After optimization (no cache): 53.79 sec
- After optimization (with cache): 3.3 sec
The massive gap between the initial state and the optimized cached state suggested that not only was the execution itself slow, but the caching mechanism was failing entirely on Windows.
Applied Solutions
To fix this, I implemented a multi-layered approach involving OS configuration, tool settings, and shell aliases.
1. Windows Defender Exception
Background processes (like Windows Defender) lock files during the high-I/O scan of phpcs which slows down execution
due to process interference.
Excluding source directory from real-time scanning. Beyond phpcs, this significantly boosts performance when using
JetBrains IDEs (like PhpStorm). It speeds up file indexing, reduces “Scanning files to index” wait times, and makes the
entire UI feel more responsive since the IDE and Defender are not fighting for file handles.
- Path:
C:\source(my sources root).
2. Fix the Cache File
There were issues with the default hidden file .phpcs-cache not being reused correctly. While the cache was created on
the initial run, phpcs was unable to reuse it in subsequent runs, forcing a full scan every time. Renaming it to a
standard file name resolved this.
- Action: Change the cache config in
phpcs.xml(orphpcs.xml.dist) tophpcs-cache.<arg name="cache" value="phpcs-cache"/> - Git: Add
phpcs-cacheto global~/.gitignoreto avoid committing local cache state.
3. Disable Xdebug for CLI Tools
Even if not actively debugging, the Xdebug extension adds significant overhead to PHP execution. Xdebug should be off by
default for static analysis. This is achieved using the -d flag.
php -d xdebug.mode=off vendor/bin/phpcs
4. PowerShell Alias for Speed
To make this permanent and easy to use, I updated my PowerShell profile with an aliases for phpcs. The alias ensures
Xdebug is always off and parameters are passed through.
function s { php -d xdebug.mode=off vendor/bin/phpcs $args }
Now, running s triggers a lightning-fast, cached phpcs check.