WSL peut donner l’impression d’un super pouvoir : les outils Linux avec un bureau Windows, changement de contexte instantané, sans taxe de redémarrage. Puis un jour vous ouvrez votre distribution et… vous attendez. Et vous attendez. Un terminal vide vous regarde comme s’il négociait son contrat.
La plupart des plaintes « WSL est lent » ne concernent pas le CPU. Elles concernent des timeouts, des scripts d’init de shell qui font trop de choses, des montages cassés et des hypothèses réseau vraies sur un portable en 2019 et fausses sur un VPN d’entreprise en 2026. La correction n’est rarement une astuce magique. C’est un diagnostic discipliné et une taille impitoyable.
Faits intéressants et contexte
- WSL 1 vs WSL 2, ce sont deux univers différents. WSL 1 traduit les appels système Linux en appels Windows ; WSL 2 exécute un vrai noyau Linux dans une VM légère. Les modes de panne au démarrage changent en conséquence.
- WSL 2 utilise un disque virtuel (VHDX) par distribution. Cela signifie que les performances de stockage sont façonnées par le VHDX, le comportement du système de fichiers hôte, l’analyse antivirus, et l’emplacement du VHDX (ex. HDD lent vs NVMe).
- Le support de systemd est arrivé tard et a changé les attentes. Pendant des années, les gens bricolaient autour de « pas d’init » avec des scripts personnalisés. Quand systemd est devenu supporté, ces bricolages ne se sont pas retirés magiquement.
- /mnt/c n’est pas « juste un dossier ». C’est une frontière de système de fichiers inter-OS avec des sémantiques et un surcoût différents. Des builds lourds là-bas peuvent ressembler à courir dans la boue.
- Les VPN d’entreprise aiment casser la résolution de noms. Un shell WSL qui fait une requête DNS par prompt peut passer de « OK » à « bloque pendant 8 secondes » du jour au lendemain.
- Beaucoup de problèmes de démarrage lent WSL sont auto-infligés. Frameworks de prompt, gestionnaires de plugins et scripts « utiles » qui appellent git, kubectl ou des CLI cloud au démarrage sont les coupables habituels.
- Le démarrage WSL n’est pas une seule chose. Il y a l’initialisation de la distribution, la configuration des montages, la mise en place du réseau, puis le démarrage du shell, puis ce que vos scripts de shell décident de faire.
- Windows Defender peut compter plus que votre CPU. L’analyse en temps réel sur les répertoires de dépôt (surtout node_modules et artefacts de build) peut dominer la latence perçue.
- PATH peut être un problème de performance. Importer un énorme PATH Windows dans WSL rend les recherches de commandes plus lentes et casse les outils de manières créatives.
Comment fonctionne réellement le démarrage de WSL (pour arrêter de deviner)
Quand vous lancez une distribution WSL, vous ne « bootiez pas Linux » de la même manière que vous démarrez une VM dans une interface d’hyperviseur. Mais vous ne lancez pas non plus simplement un processus comme WSL 1 pouvait le donner à croire. WSL 2 démarre (ou reprend) une VM légère hébergeant un noyau Linux, attache le VHDX de la distribution, configure le réseau virtuel, puis exécute la commande demandée — généralement votre shell par défaut.
Du point de vue latence il y a quatre couches, et chacune a sa signature quand elle échoue :
1) Mise en route / reprise de la VM
Si WSL est inactif, il peut s’être arrêté. Votre prochain lancement doit démarrer la VM WSL. C’est généralement rapide, mais cela peut traîner quand l’hôte est sous pression mémoire, quand le stockage est lent, ou quand quelque chose force du travail supplémentaire (comme une protection d’endpoints agressive).
2) Initialisation de la distribution (et systemd, si activé)
WSL moderne peut exécuter systemd. C’est bien — les services se comportent normalement — mais cela ajoute un comportement type boot. Si une unité est lente, échoue ou attend le réseau, vous paierez ce coût pendant le « démarrage ». Si systemd n’est pas activé, vous pouvez quand même avoir des scripts d’init hérités ou des hacks au moment de la connexion qui tentent de l’émuler.
3) Montages et câblage d’interop
WSL connecte les disques Windows, configure /mnt, et importe éventuellement des variables d’environnement Windows comme PATH. Le comportement des montages est configurable dans /etc/wsl.conf. Quand les montages sont erronés, vous verrez des blocages qui ressemblent à « le shell ne s’ouvre pas », mais le vrai coupable est un montage bloquant ou une sonde de système de fichiers.
4) Initialisation du shell
C’est la partie que vous contrôlez. Bash lit /etc/profile et vos dotfiles personnels. Zsh lit d’autres fichiers. Fish a son propre monde. Si votre prompt exécute git status sur un dépôt massif, ou si votre profil appelle une CLI cloud qui attend un proxy, le terminal paraîtra « coincé » même si WSL va bien.
Une citation à garder au mur, parce que les performances de démarrage attendent principalement des dépendances :
idée paraphrasée — Werner Vogels : « Tout échoue, tout le temps ; concevez des systèmes qui s’y attendent. »
En terre WSL, « échec » signifie souvent « timeout », qui porte un costume.
Playbook de diagnostic rapide (premier/deuxième/troisième)
Si vous voulez que WSL démarre rapidement, vous devez identifier quelle couche est lente. Ne commencez pas par réécrire les dotfiles. Ne commencez pas par réinstaller la distribution. Commencez par mesurer de manière à isoler le goulot.
Premier : isoler l’init du shell vs le reste
- Lancez WSL avec une commande qui évite l’init interactif de votre shell.
- Si cela est rapide, votre problème est dans les dotfiles / le prompt / les plugins.
- Si c’est encore lent, votre problème est WSL / distribution / systemd / montages / réseau.
Deuxième : vérifier systemd et les services (si activé)
- Demandez à systemd combien de temps il a pris.
- Cherchez des unités qui attendent le réseau, le DNS ou des montages.
- Désactivez tout ce qui n’est pas nécessaire pour les shells de développement.
Troisième : réseau/DNS et montages
- Les timeouts DNS sont le coupable numéro 1 des « 5–10 secondes aléatoires ».
- L’accès /mnt/c et l’import du PATH Windows sont des coupables fréquents de « mort par mille coupures ».
- Si tout le reste semble propre, alors attaquez le placement du stockage/VHDX et les exclusions antivirus.
Blague #1 : Si votre prompt lance trois appels réseau, ce n’est pas un prompt. C’est un système distribué avec des sentiments.
Tâches pratiques : commandes, sorties et décisions
Vous réparerez cela plus vite si vous le traitez comme un incident : rassemblez des preuves, isolez les variables, faites un changement à la fois et gardez un chemin de retour. Ci‑dessous des tâches réelles avec commandes, sorties exemples et ce que vous décidez à partir d’elles.
Task 1: Measure the time to start WSL without your interactive shell
cr0x@server:~$ /usr/bin/time -p wsl.exe -d Ubuntu-22.04 -- bash -lc 'true'
real 0.62
user 0.00
sys 0.00
Ce que signifie la sortie : Le nombre real est le temps en horloge murale. Cela contourne la logique de prompt interactive et la plupart des drames de dotfiles.
Décision : Si c’est rapide (<1–2s) mais que votre terminal normal est lent, allez directement déboguer l’initialisation du shell. Si c’est lent, continuez à creuser systemd/montages/réseau/stockage.
Task 2: Compare interactive shell startup time
cr0x@server:~$ /usr/bin/time -p bash -lic 'exit'
real 2.87
user 0.19
sys 0.08
Ce que signifie la sortie : Cela mesure le démarrage login + interactif. Si real est bien plus grand que user et sys, vous attendez de l’I/O, du réseau ou des sous-processus bloquants.
Décision : Si l’interactif est lent mais le non-interactif est rapide, les dotfiles / prompt / plugins sont vos principaux suspects.
Task 3: See what shell you’re actually running and how it’s invoked
cr0x@server:~$ echo "$0"; ps -p $$ -o pid,ppid,cmd
-bash
PID PPID CMD
812 799 -bash
Ce que signifie la sortie : Un tiret en tête indique un login shell. Cela change les fichiers sourcés (/etc/profile, ~/.bash_profile, etc.).
Décision : Si vous lancez accidentellement un login shell alors que ce n’est pas nécessaire, corrigez le profil de votre terminal (Windows Terminal / VS Code) pour démarrer un shell non-login pour la vitesse.
Task 4: Trace what your shell is sourcing (bash)
cr0x@server:~$ bash -lic 'set -o posix; shopt -po login_shell; echo "BASH_VERSION=$BASH_VERSION"; exit'
set -o posix
shopt -s login_shell
BASH_VERSION=5.1.16(1)-release
Ce que signifie la sortie : Confirme que vous êtes dans un login shell et montre la version de bash (pertinent pour les fonctionnalités de démarrage et la compatibilité).
Décision : Si les login shells sont lents, déplacez les choses lourdes hors des fichiers seulement-login et mettez-les en fonctions à la demande, ou arrêtez d’utiliser des login shells pour les sessions interactives.
Task 5: Use bash xtrace to find the slow line
cr0x@server:~$ bash -lic 'PS4="+\t\D{%s}\t"; set -x; source ~/.bashrc; exit' 2> /tmp/bashrc.trace
...output...
Ce que signifie la sortie : Le fichier de trace a des timestamps par ligne exécutée. Cherchez de gros écarts entre les timestamps.
Décision : Supprimez, différez ou protégez les commandes lentes. Si l’écart correspond à l’appel de git, kubectl, gcloud, npm ou d’outils DNS, vous avez trouvé votre ancre.
Task 6: Zsh profiling (if you use zsh)
cr0x@server:~$ zsh -lic 'zmodload zsh/zprof; source ~/.zshrc; zprof' | head -n 12
num calls time self name
-----------------------------------------------------------------------------------
1) 1 189.22 189.22 38.51% 189.22 189.22 compinit
2) 1 121.77 121.77 24.78% 121.77 121.77 gitstatus_init
Ce que signifie la sortie : Elle classe les fonctions par temps. compinit et les helpers de prompt git sophistiqués dominent souvent.
Décision : Mettez en cache la complétion, réduisez les plugins ou passez à un prompt plus simple. Dans WSL, « réactif » bat « mignon ».
Task 7: Check whether systemd is enabled and if it’s slow
cr0x@server:~$ ps -p 1 -o pid,comm,args
PID COMMAND COMMAND
1 systemd /sbin/init
Ce que signifie la sortie : Si PID 1 est systemd, alors le démarrage WSL inclut le travail des unités systemd.
Décision : Si systemd est activé et que vous n’avez pas besoin de services, envisagez de le désactiver. Si vous en avez besoin, mesurez et ajustez les unités.
Task 8: Measure systemd boot time and find slow units
cr0x@server:~$ systemd-analyze time
Startup finished in 2.103s (kernel) + 5.882s (userspace) = 7.985s
graphical.target reached after 5.841s in userspace
Ce que signifie la sortie : Le temps userspace est l’endroit où vivent les services lents.
Décision : Si userspace prend plusieurs secondes, listez le blâme.
cr0x@server:~$ systemd-analyze blame | head -n 10
3.214s systemd-networkd-wait-online.service
1.102s snapd.service
0.688s apt-daily.service
0.512s systemd-resolved.service
Ce que signifie la sortie : Ces unités ont consommé le plus de temps. wait-online est la classique « pourquoi j’attends un réseau qui n’existe pas ? » unité.
Décision : Masquez ou reconfigurez les services qui n’ont pas leur place dans un environnement de développement shell.
Task 9: Check mounts and whether you’re paying extra for Windows drives
cr0x@server:~$ mount | grep -E '/mnt/|drvfs' | head -n 5
C: on /mnt/c type drvfs (rw,noatime,uid=1000,gid=1000,metadata,case=off)
D: on /mnt/d type drvfs (rw,noatime,uid=1000,gid=1000,metadata,case=off)
Ce que signifie la sortie : Les disques Windows sont montés comme drvfs. Des options comme metadata et case affectent compatibilité et performances.
Décision : Si votre flux de travail utilise fortement les permissions Linux, gardez metadata. Sinon, vous pouvez simplifier. Mais le gain plus important est de déplacer les dépôts « chauds » sur le système de fichiers Linux.
Task 10: Detect if you’re working in /mnt/c (performance trap)
cr0x@server:~$ pwd
/mnt/c/Users/alex/source/mega-repo
Ce que signifie la sortie : Vous êtes sur le stockage Windows. Les builds, installations de paquets et opérations git seront souvent plus lentes.
Décision : Clonez le dépôt sous ~ (système de fichiers Linux) et utilisez un éditeur qui peut y accéder (VS Code Remote – WSL est conçu pour ça).
Task 11: Check DNS behavior (fast fail vs slow hang)
cr0x@server:~$ getent hosts github.com
140.82.121.4 github.com
Ce que signifie la sortie : La résolution DNS a réussi rapidement. Si elle bloque, c’est votre preuve fumante.
Décision : Si lent/bloquant, inspectez /etc/resolv.conf et les paramètres DNS de WSL. Si c’est rapide, votre lenteur est ailleurs.
Task 12: Confirm whether /etc/resolv.conf is auto-generated and what nameserver you’re using
cr0x@server:~$ ls -l /etc/resolv.conf; head -n 10 /etc/resolv.conf
-rw-r--r-- 1 root root 235 Jan 12 09:14 /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation...
nameserver 172.24.64.1
search corp.example
Ce que signifie la sortie : WSL génère resolv.conf et pointe vers une IP de gateway virtuelle. Sur les VPN, cela peut être correct ou cela peut être une fête de timeouts.
Décision : Si le DNS est instable/lent, désactivez la génération automatique et définissez une stratégie de résolveur stable pour votre environnement (détails dans la section réseau).
Task 13: Check if Windows PATH import is bloating command lookup
cr0x@server:~$ echo "$PATH" | tr ':' '\n' | wc -l
142
Ce que signifie la sortie : 142 entrées PATH, ce n’est pas une preuve de vigueur. C’est une responsabilité. Beaucoup sont des chemins Windows qui provoquent des vérifications de système de fichiers supplémentaires.
Décision : Envisagez de désactiver appendWindowsPath dans /etc/wsl.conf et d’ajouter explicitement uniquement ce dont vous avez besoin.
Task 14: Identify whether your prompt is doing expensive git work
cr0x@server:~$ PS1='\u@\h:\w\$ ' bash --noprofile --norc
cr0x@server:~$ exit
exit
Ce que signifie la sortie : Cela lance un bash propre avec un prompt simple. Si c’est instantané, votre prompt sophistiqué est le problème.
Décision : Remplacez les frameworks de prompt ou configurez-les pour éviter d’appeler git à chaque rafraîchissement du prompt (ou ne le faire que dans les dépôts git, avec mise en cache).
Task 15: Quick check for hanging commands in dotfiles by running them with a timeout
cr0x@server:~$ timeout 2s bash -lc 'source ~/.bashrc; echo ok' || echo "bashrc exceeded 2s"
bashrc exceeded 2s
Ce que signifie la sortie : Votre bashrc ne peut pas se terminer en deux secondes dans un run non-interactif. Quelque chose bloque à l’intérieur.
Décision : Utilisez l’approche de traçage (Task 5) et supprimez/protégez les éléments lents.
Task 16: Check whether Windows interop is on and whether it’s hurting you
cr0x@server:~$ cat /proc/sys/fs/binfmt_misc/WSLInterop 2>/dev/null | head -n 5
enabled
interpreter /init
flags: P
offset 0
magic 4d5a
Ce que signifie la sortie : L’interop est activée, donc exécuter des exécutables Windows depuis Linux fonctionne. C’est pratique — et parfois lent quand des scripts invoquent accidentellement des outils Windows.
Décision : Si vous voyez des commandes lentes et découvrez qu’elles résolvent vers des binaires Windows (comme git.exe), corrigez l’ordre du PATH ou désactivez l’interop pour ce flux de travail.
Arrêter les shells lents : scripts de profil, frameworks de prompt et pièges PATH
Le démarrage du shell est l’endroit où la performance vient mourir parce que c’est « juste un script ». Les scripts poussent comme la moisissure : lentement, puis soudainement vous sourcez cinq gestionnaires de plugins et un moteur de thème pour afficher votre nom en italique.
WSL amplifie ça parce qu’une grande partie de la « douceur » du shell suppose des ressources locales à faible latence. Mais dans WSL vous pouvez traverser /mnt/c, invoquer des binaires Windows par accident, ou déclencher des requêtes DNS via un tunnel VPN à moitié endormi.
Sachez quels fichiers s’exécutent, et évitez le double-sourcing
Bash source couramment :
/etc/profile(login shells)~/.bash_profileou~/.profile(login shells)~/.bashrc(shells interactifs)
Un ralentissement classique est ~/.bash_profile qui source ~/.profile qui source ~/.bashrc et ensuite le terminal lance un login shell interactif qui source aussi ~/.bashrc. Vous venez d’exécuter votre code lent deux fois. Personne ne le remarque jusqu’à ce que le dépôt grossisse et que git status devienne coûteux.
Frameworks de prompt : choisissez-en un, configurez-le sérieusement
Starship, oh-my-zsh themes, powerlevel10k, helpers de prompt git personnalisés — ces outils sont excellents. Ils sont aussi parfaitement heureux d’exécuter des commandes externes de façon répétée. Dans WSL, les commandes externes peuvent traverser des frontières et appeler des exécutables Windows, ou toucher des couches de système de fichiers qui ne mettent pas en cache comme vous le supposez.
Règles que j’applique au sein des équipes :
- Pas d’appels réseau pendant le rendu du prompt. Cela inclut les CLI cloud, les récupérations de contexte kube qui touchent des APIs, ou les vérifications de version « utiles ».
- Pas de git status récursif sur des gros dépôts par défaut. Préférez des vérifications rapides ou un statut mis en cache ; évitez
git statusdans le prompt si vous ne pouvez pas en borner le coût. - Différez les initialisations lourdes. Les systèmes de complétion, gestionnaires de versions de langage et outils type direnv devraient se charger paresseusement quand c’est possible.
PATH : gardez-le court, déterministe et prioritaire pour Linux
WSL peut importer des entrées PATH Windows. Cela semble utile jusqu’à ce que votre shell doive vérifier 140 répertoires pour résoudre python, et la moitié de ces répertoires sont sur /mnt/c. Pire : parfois vous exécutez git.exe alors que vous pensiez exécuter git Linux. Maintenant vos opérations de dépôt rebondissent à travers la frontière.
Conseils pratiques :
- Désactivez l’append du PATH Windows sauf si vous en avez vraiment besoin.
- Si vous avez besoin de quelques outils Windows, ajoutez-les explicitement et placez-les en dernier.
- Quand vous déboguez des « commandes lentes », vérifiez quel binaire est utilisé avec
type -aoucommand -v.
Protégez tout outil optionnel par des vérifications rapides
Si votre init de shell exécute un outil qui peut ne pas exister, ne l’appelez pas aveuglément et n’attendez pas l’échec. Vérifiez d’abord :
command -v tool >/dev/nullest peu coûteux.- Appeler
tool --versionn’est pas toujours bon marché (certaines CLI initialisent des plugins et de la config).
Arrêtez aussi les « vérifications de mise à jour automatiques » au démarrage du shell. Si vous en avez vraiment besoin, planifiez-les en arrière-plan après l’affichage du prompt.
Scripts d’init cassés et systemd : quand « boot » n’est pas boot
Historiquement, WSL a appris aux gens à traiter le démarrage de la distribution comme « exécuter un shell et espérer le meilleur ». Puis le support systemd est arrivé et tout le monde a commencé à activer des services. C’est bien — jusqu’à ce que ça ne le soit plus.
Décidez si vous avez vraiment besoin de systemd
Si votre flux de travail nécessite Docker à l’intérieur de WSL, des démons en arrière-plan, des timers ou de la supervision de services, systemd peut être la bonne solution. Si vous compilez principalement et utilisez des outils en ligne de commande, systemd est souvent une surcharge optionnelle.
Même avec systemd activé, soyez sélectif. WSL n’est pas un serveur chouchouté. C’est un environnement de dev qui doit démarrer instantanément et être jetable.
Unités systématiques lentes courantes dans WSL
- systemd-networkd-wait-online.service : attend la disponibilité du réseau ; souvent inutile dans WSL où le réseau arrive différemment.
- snapd.service : peut ajouter une latence notable au démarrage ; snap n’en vaut pas toujours la peine dans WSL.
- apt-daily.service et timers : les mises à jour en arrière-plan peuvent faire monter l’utilisation disque au moment où vous ouvrez un shell.
- Intégration resolved : peut interagir mal avec le resolv.conf généré par WSL selon la configuration.
Masquer vs désactiver : choisissez le bon marteau
Si une unité est activement nuisible au démarrage, masquez-la pour qu’elle ne puisse pas démarrer accidentellement. Si vous ne voulez juste pas qu’elle soit activée par défaut, désactivez-la. Pour la performance de démarrage WSL, masquer « wait-online » est une victoire fréquente.
Et oui : parfois un « script d’init cassé » est votre propre ~/.profile qui se prend pour un système d’init. Si vous avez des scripts démarrant des daemons, exportant l’environnement et touchant des montages, vous avez construit un mini-init. Il réunit tous les inconvénients de systemd et aucun des diagnostics.
Montages et E/S fichiers : la taxe /mnt/c, options d’automount et où se trouve votre dépôt
La plupart des histoires d’horreur de performance WSL impliquent le système de fichiers Windows. Pas parce qu’il est mauvais, mais parce qu’il est différent. Les outils Linux supposent des sémantiques POSIX. Les sémantiques Windows ne sont pas POSIX. WSL camoufle la différence. Le camouflage n’est pas gratuit.
Mettez le code chaud sur le système de fichiers Linux
Si vous tenez à la réactivité au démarrage et en interactif, vos dépôts principaux et les sorties de build devraient se trouver sous /home dans la distribution. Cela signifie cloner dans WSL, pas éditer un clone sur C:\. Vous pouvez toujours éditer depuis Windows avec des outils compatibles WSL.
Ce changement unique corrige :
- git status lent, git diff lent
- installations de dépendances lentes (caches npm/pip/gradle)
- Comportement de permissions de fichiers étrange
- Surcharge d’analyse des endpoints (souvent moins pénible à l’intérieur du VHDX)
Ajustez automount, mais ne faites pas de cargo-cult
/etc/wsl.conf peut contrôler le comportement d’automount. Les gens aiment coller une config d’un article et ensuite l’oublier. Six mois plus tard, quelque chose casse et tout le monde blâme WSL.
Idées clés :
- metadata active les permissions POSIX sur les fichiers Windows. Utile, mais peut ajouter du surcoût et de la confusion si vous n’en avez pas besoin.
- case a une importance pour les toolchains et dépôts avec chemins sensibles à la casse.
- appendWindowsPath peut gonfler PATH et ralentir la recherche de commandes.
Soyez intentionnel sur ce que vous accédez à travers la frontière
Accéder à quelques fichiers de configuration sur /mnt/c est acceptable. Lancer un build qui fait des millions de petites opérations de fichiers là-bas est un auto-sabotage de performance. Si votre framework de prompt scanne des répertoires sur /mnt/c au démarrage, c’est un shell lent par conception.
Réseau et DNS : la fabrique silencieuse de timeouts
Les problèmes DNS sont la cause la plus courante des « WSL bloque 5–10 secondes parfois ». La raison est ennuyeuse : beaucoup d’outils font une résolution de nom au démarrage, et ils le font souvent de façon synchrone. Votre shell ne paraît pas lent ; il paraît gelé.
D’où vient la douleur DNS dans WSL :
- WSL génère automatiquement
/etc/resolv.confà partir du réseau Windows. - Les VPN d’entreprise modifient le DNS et le routage Windows à la volée.
- Certaines organisations poussent des serveurs DNS accessibles seulement quand on est connecté au VPN.
- Des outils comme git, plugins kubectl, gestionnaires de paquets de langage et scripts de prompt peuvent déclencher du DNS.
Détectez-le rapidement
Si getent hosts some-domain bloque, vous avez trouvé un coupable principal. Ensuite vous décidez de corriger le DNS au niveau WSL (comportement de resolv.conf) ou au niveau dotfile/outillage (empêcher les outils de faire du DNS au démarrage).
Rendez le comportement DNS déterministe
Pour beaucoup d’environnements d’entreprise, la configuration la plus stable est :
- Désactiver la génération automatique de
/etc/resolv.conf. - Écrire un resolv.conf qui fonctionne on/off VPN, ou le générer via un script lié à l’état du VPN.
- Éviter de se fier à « ce que Windows pense aujourd’hui ».
Mais attention : si vous codez en dur des résolveurs publics dans une organisation verrouillée, les domaines internes casseront. L’approche correcte dépend de l’environnement. L’ingénierie de la fiabilité est l’art de respecter la réalité, pas de se disputer avec elle.
Réalité du stockage/VHDX : ce que signifie « disque lent » dans WSL2
Quand WSL2 semble lent, les gens blâment « la VM ». Quand il semble vraiment lent, ils blâment « Windows ». En pratique c’est plus spécifique : c’est votre disque virtuel, son emplacement et le pipeline de stockage de l’hôte.
Comprenez les implications du VHDX
Votre système de fichiers Linux vit dans un fichier VHDX. Les schémas d’E/S aléatoires, l’usure de petits fichiers et les charges de travail riches en métadonnées (bonjour, node_modules) sont sensibles aux performances du stockage hôte. Si votre profil utilisateur Windows vit sur un disque chiffré ou redirigé, votre VHDX WSL peut se trouver quelque part désagréable.
La protection d’endpoints est une variable de performance
L’analyse en temps réel peut rendre les opérations lourdes en fichiers lentes. Si des scripts de démarrage touchent beaucoup de fichiers (reconstruction de cache de complétion, scans de prompt, gestionnaires de version), vous pouvez le ressentir pendant le « démarrage WSL » même si le vrai travail est l’analyse de fichiers.
Travaillez avec la sécurité plutôt que contre elle. La pratique ennuyeuse et correcte est d’établir des exclusions sanctionnées pour l’emplacement du VHDX WSL ou des répertoires spécifiques qui produisent un fort taux de churn. Si votre organisation n’autorise pas d’exclusions, alors votre meilleur levier est de minimiser le churn de fichiers au démarrage et de garder les dépôts à l’intérieur du système de fichiers Linux pour éviter le surcoût drvfs.
Blague #2 : L’antivirus est comme un détecteur de fumée qui critique aussi votre technique culinaire — utile, mais il ruine absolument une soirée tranquille.
Trois mini-histoires d’entreprise (ce qui casse réellement dans les organisations)
Incident causé par une mauvaise hypothèse : « le DNS est local, donc rapide »
Une équipe plateforme a déployé un environnement WSL standardisé pour les ingénieurs : Ubuntu, zsh, un prompt brillant, quelques scripts d’aide et le contexte kubectl dans le prompt parce que « c’est utile ». Ça a bien fonctionné au bureau. À la maison, la moitié de l’équipe s’est plainte que WSL « accroche aléatoirement » à l’ouverture d’un nouveau terminal.
L’hypothèse erronée était subtile : ils supposaient que le coût de résolution DNS est négligeable. Sur le Wi‑Fi d’entreprise, ça l’était. Sur les réseaux domestiques plus un VPN split-tunnel, les requêtes DNS pour des domaines internes expiraient avant de retomber en arrière. Le script de prompt ne se contentait pas de lire un fichier de config ; il invoquait kubectl, qui invoquait un plugin, qui tentait de résoudre un hostname API interne. Chaque nouveau shell payait le prix du timeout.
Le débogage a été du travail SRE classique : reproduire avec un prompt propre, puis ajouter des composants. getent hosts bloquait exactement quand le prompt bloquait. Ils ont corrigé ça de deux façons : (1) retiré les appels kubectl du rendu du prompt ; (2) rendu le DNS déterministe en désactivant la génération automatique de resolv.conf et en gérant les résolveurs selon l’état du VPN.
La leçon retenue : les chemins de démarrage doivent être exempts de dépendance réseau. Si vous avez besoin de contexte dynamique, calculez-le de façon asynchrone après l’apparition du prompt et mettez-le en cache avec un TTL.
Optimisation qui s’est retournée contre eux : « Mettons les dépôts sur C: pour l’accès facile »
Un groupe de productivité dev voulait une règle simple : garder le code dans C:\src pour que les outils Windows et WSL puissent tous le voir. Tout le monde aimait la commodité. Ça fonctionnait bien pour de petits services.
Puis est arrivé un monorepo avec de lourds builds TypeScript et des arbres de dépendances massifs. Soudainement les mêmes portables qui étaient « assez rapides » ont commencé à brûler des minutes sur les installs, et les shells mettaient plusieurs secondes à s’afficher parce que les prompts et systèmes de complétion parcouraient le dépôt pour inférer le contexte.
Ils ont essayé d’optimiser les options de montage drvfs, désactivé metadata, ajouté noatime et bidouillé tout ce qu’ils pouvaient. Des gains marginaux. Le désaccord fondamental est resté : les toolchains Linux effectuant des millions d’opérations de fichiers sur un pont de système de fichiers Windows.
La vraie correction était ennuyeuse et légèrement contraignante : placer le dépôt sous ~/src dans le système de fichiers Linux et utiliser des éditeurs compatibles WSL. Ils ont gardé un petit ensemble de fichiers visibles par Windows sur /mnt/c quand nécessaire, mais le chemin chaud a migré vers ext4 à l’intérieur du VHDX. Les temps de démarrage et de build sont revenus raisonnables.
Pratique ennuyeuse mais correcte qui a sauvé la journée : « Les scripts de profil sont du code de production »
Une entreprise régulée avait beaucoup d’ingénieurs sur WSL, et ils traitaient les dotfiles comme un projet artistique personnel. Puis est arrivé une mise à jour de durcissement de la sécurité : nouveaux paramètres proxy, bundles de certificats mis à jour et un changement dans le routage DNS interne. Le lendemain matin, une partie de l’organisation ne pouvait plus ouvrir rapidement des terminaux WSL. Certains ne pouvaient même pas les ouvrir.
Une équipe n’a pas paniqué parce qu’elle avait une pratique qui sonne peu sexy : ils gardaient la logique d’init minimale, versionnée et révisée. Leurs dotfiles étaient séparés en « critique au démarrage » et « agréable à avoir », avec des timeouts autour de tout ce qui pouvait bloquer. Ils avaient aussi une procédure d’urgence documentée : démarrer avec --noprofile --norc pour récupérer un shell cassé.
Pendant que d’autres équipes réinstallaient des distributions et accusaient les mises à jour Windows, cette équipe avait un terminal fonctionnel, pouvait lancer des diagnostics et aider les autres. La correction pour l’organisation a fini par être un alignement DNS/proxy simple, mais les équipes aux dotfiles disciplinés ont perdu moins de temps et ont produit des données d’incident plus propres.
La morale : ce qui s’exécute au démarrage fait partie de votre plateforme. Traitez-le avec le même respect que vous accordez aux scripts d’init en production — car c’est ce dont vous avez besoin quand tout le reste brûle.
Erreurs courantes : symptôme → cause racine → correction
1) Symptom: Terminal opens, stays blank for 5–15 seconds, then prompt appears
Cause racine : Une commande bloquante dans l’init du shell (souvent liée au DNS) ou un framework de prompt lançant des sous-processus lents.
Correction : Démarrez un shell propre (bash --noprofile --norc), confirmez qu’il est instantané, puis tracez vos fichiers d’init (bash xtrace ou zsh zprof). Retirez les appels réseau du rendu du prompt. Ajoutez des timeouts autour des helpers optionnels.
2) Symptom: Only slow when on VPN (or only slow when off VPN)
Cause racine : Les résolveurs DNS dans /etc/resolv.conf ne sont joignables que dans un état ; les requêtes expirent.
Correction : Désactivez le resolv.conf auto-généré et gérez intentionnellement les résolveurs pour votre environnement, ou corrigez la configuration DNS/VPN côté Windows pour que WSL hérite du comportement correct.
3) Symptom: cd into a repo is fine, but every new prompt takes 1–2 seconds
Cause racine : Le prompt exécute git status ou équivalent à chaque rendu ; le dépôt est large ou sur drvfs.
Correction : Simplifiez le prompt ou activez la mise en cache ; évitez le scan à chaque prompt ; déplacez le dépôt sur le filesystem Linux.
4) Symptom: WSL startup slow after enabling systemd
Cause racine : Unités systemd lentes (wait-online, snapd, timers apt) ralentissant le démarrage userspace.
Correction : Utilisez systemd-analyze blame et masquez/désactivez les unités inutiles. Si vous n’avez pas besoin de systemd, désactivez-le.
5) Symptom: Commands feel “laggy,” even simple ones like python or node
Cause racine : PATH est énorme ; la résolution de commande vérifie de nombreux répertoires Windows ; ou vous invoquez des binaires Windows par inadvertance.
Correction : Réduisez le PATH, désactivez l’append du PATH Windows, vérifiez type -a pour les binaires, corrigez l’ordre du PATH.
6) Symptom: Only slow in one distro; other distros are fast
Cause racine : Dotfiles spécifiques à la distribution, unités systemd, ou caches corrompus (caches de complétion, shims des gestionnaires de version).
Correction : Comparez le blame systemd, comparez les dotfiles, renommez temporairement ~/.bashrc/~/.zshrc, reconstruisez les caches.
7) Symptom: Startup time worsened after “tuning” /etc/wsl.conf
Cause racine : Paramètres d’automount/interop copiés-collés provoquant du travail supplémentaire ou des reculs de compatibilité.
Correction : Revenez à une configuration minimale, puis réappliquez les changements un par un en mesurant. Gardez ce qui fait une vraie différence ; supprimez le reste.
8) Symptom: Random pauses during shell startup, more common on large repos
Cause racine : L’analyse par la protection d’endpoints des opérations lourdes en fichiers déclenchées par des scripts d’init (reconstructions de cache, scans de prompt).
Correction : Réduisez le churn de fichiers au démarrage ; envisagez des exclusions sanctionnées ; gardez les dépôts dans le filesystem Linux ; évitez de reconstruire des caches à chaque lancement.
Listes de contrôle / plan étape par étape
Étape par étape : ramener le démarrage de WSL sous 1 seconde (ou aussi proche que possible)
- Mesurez la ligne de base sans init interactif. Utilisez Task 1. Si c’est lent, ne touchez pas encore aux dotfiles.
- Mesurez le temps du shell interactif. Utilisez Task 2. Si l’interactif est le delta, profilez les dotfiles et tuez le nonsense prompt/réseau.
- Ouvrez un shell propre. Utilisez Task 14 (
--noprofile --norc) pour prouver que l’environnement peut être rapide. - Profilez votre init de shell. Bash xtrace (Task 5) ou zsh zprof (Task 6).
- Retirez les dépendances réseau du démarrage. Pas de DNS, pas de CLI cloud, pas d’appels kube dans le rendu du prompt.
- Déplacez les dépôts chauds hors de /mnt/c. Si vous build sur drvfs, vous payez un surcoût par conception.
- Taillez le PATH. Réduisez les entrées, désactivez l’import du PATH Windows si possible.
- Vérifiez systemd uniquement si pertinent. Si PID 1 est systemd, exécutez
systemd-analyze blameet masquez les unités lentes dont vous n’avez pas besoin. - Validez la vitesse DNS.
getent hostsdoit être instantané. Sinon, corrigez la stratégie resolv.conf. - Remesurez après chaque changement. Ne cumulez pas des ajustements en espérant ; mesurez, gardez, répétez.
Checklist opérationnelle : garder ça rapide dans le temps
- Les dotfiles sont du code revu, pas du folklore.
- Le prompt ne doit pas exécuter d’opérations non bornées (réseau, scans profonds du fs).
- Tout helper optionnel a un timeout ou un mécanisme de chargement paresseux.
- Les dépôts vivent par défaut dans le filesystem Linux ; drvfs sert au partage occasionnel, pas aux builds lourds.
- En activant systemd, auditez et minimisez les unités activées.
- Sur les réseaux corporate, décidez explicitement d’une stratégie DNS ; ne comptez pas sur « auto ».
FAQ
1) Pourquoi WSL est-il parfois rapide et parfois terriblement lent ?
Parce que vous attendez souvent des timeouts : DNS, disponibilité réseau, ou une commande dans l’init du shell qui bloque selon certaines conditions (état du VPN, proxy, domaine inaccessible).
2) Comment savoir si le problème vient de WSL lui-même ou de ma configuration de shell ?
Exécutez WSL avec une commande triviale (Task 1). Si c’est rapide mais qu’un shell interactif est lent (Task 2), les dotfiles / prompt / plugins sont le problème.
3) Est-ce une mauvaise idée d’activer systemd dans WSL ?
Pas intrinsèquement. C’est approprié si vous avez besoin de services gérés. C’est aussi une source de latence au démarrage si vous activez des unités qui attendent le réseau ou exécutent des maintenances en arrière-plan. Mesurez avec systemd-analyze et taillez.
4) Pourquoi travailler sous /mnt/c rend tout plus lent ?
Parce que drvfs fait le pont entre deux modèles de système de fichiers. Les outils Linux effectuent beaucoup d’opérations de métadonnées qui sont plus coûteuses à travers cette frontière. Placez les dépôts lourds sous ~ dans la distribution.
5) Quelle est la correction la plus rapide sur les dotfiles qui aide généralement ?
Arrêtez d’exécuter des commandes coûteuses dans le prompt. Retirez git status de PS1 ou configurez une mise en cache. Si vous devez afficher des infos git, gardez-le léger et borné.
6) Comment savoir si le DNS est le coupable ?
Si getent hosts some-domain bloque ou prend des secondes, le DNS est impliqué. Vérifiez aussi si la lenteur corrèle avec le VPN activé/désactivé.
7) Dois-je désactiver l’intégration du PATH Windows ?
Si votre PATH est énorme ou si vous exécutez accidentellement des binaires Windows, oui. Désactivez-la et ajoutez des chemins Windows spécifiques uniquement si nécessaire, de préférence en dernier.
8) J’utilise VS Code avec WSL. Est-ce que ça change quelque chose ?
Non, cela devient encore plus important. VS Code va lancer des shells et des helpers. Un init de shell lent rend l’éditeur lent et instable. Gardez le démarrage minimal et déterministe.
9) J’ai corrigé mon prompt, mais WSL prend toujours ~5 secondes à s’ouvrir la première fois chaque jour
Cela vient probablement de la mise en route/reprise de la VM plus systemd (si activé) plus le warm-up du stockage. Mesurez avec Task 1 et les outils systemd. Si la ligne de base est lente, regardez systemd, les montages et le stockage hôte/antivirus.
10) Quel est le moyen le plus sûr pour « sortir » quand mon shell est cassé et ne démarre pas ?
Démarrez un shell propre : bash --noprofile --norc ou zsh -f, puis corrigez ou renommez temporairement vos fichiers rc.
Conclusion : prochaines étapes pratiques
La vitesse de démarrage de WSL n’est pas un mystère. C’est une chaîne d’approvisionnement : état de la VM, services système, montages, réseau, puis vos scripts de shell. La dépendance la plus lente gagne. Si vous voulez que ce soit rapide, arrêtez de deviner et commencez à isoler.
Faites ceci ensuite, dans l’ordre :
- Mesurez la ligne de base sans init interactif du shell.
- Mesurez le démarrage du shell interactif ; si c’est le delta, profilez les dotfiles et tuez les absurdités prompt/réseau.
- Si la ligne de base est lente, vérifiez le temps de boot systemd et les unités lentes ; puis les montages et le DNS.
- Déplacez les dépôts lourds vers le système de fichiers Linux et gardez /mnt/c pour le partage léger.
- Réduisez le PATH et arrêtez d’importer tout l’écosystème Windows sauf si vous en avez vraiment besoin.
Quand vous y parvenez, WSL ressemblera à ce qu’il a toujours été censé être : un espace de travail Linux rapide et jetable qui démarre en temps que vous pensez à la commande suivante.