WSL lent ? Corrigez les E/S de fichiers avec cette règle

Cet article vous a aidé ?

Quand WSL est rapide, c’est ennuyeux : vos builds s’exécutent, vos tests se terminent, les ventilateurs de l’ordinateur portable font semblant de ne pas travailler à plein régime. Quand WSL est lent, c’est personnel. Un git status prend des secondes. npm install donne l’impression d’emmener chaque fichier sur le disque à la main. On commence à accuser « WSL » en général, ce qui revient à blâmer « les routes » pour les embouteillages.

La plupart des problèmes d’E/S de WSL proviennent d’une blessure auto‑infligée : vous faites des charges de travail à la manière Linux sur le système de fichiers Windows. Corrigez cela, et beaucoup de « WSL est lent » disparaissent.

La règle unique : ne traversez pas la frontière des systèmes de fichiers

Règle : Faites le travail de développement Linux sur le système de fichiers Linux (/home, /, le ext4 VHDX de WSL). Faites le travail Windows sur le système de fichiers Windows (C:\, D:\). Ne faites pas effectuer d’E/S intensives d’un OS vers le système de fichiers de l’autre.

Concrètement au quotidien :

  • Clonez les dépôts dans ~/src à l’intérieur de WSL, pas dans /mnt/c/Users/you/src.
  • Gardez node_modules, les virtualenv Python, les dossiers target Rust, les caches de build Go, les caches Gradle, et tout ce qui génère des milliers de petits fichiers à l’intérieur de WSL.
  • Si un éditeur est natif Windows (Visual Studio, Windows Git GUI, Windows Node, etc.), pointez‑le vers des chemins Windows. Si l’outil s’exécute dans WSL, pointez‑le vers des chemins WSL.
  • Utilisez VS Code Remote – WSL (ou équivalent) pour que l’éditeur parle aux fichiers là où tournent les outils Linux.

Ce n’est pas de l’idéologie. C’est de la mécanique. Traverser la frontière impose des couches de traduction, du mappage de permissions, de l’émulation de métadonnées, et parfois un scan antivirus exactement dans le pire schéma possible : beaucoup de petits fichiers et des appels fréquents à stat.

Une petite blague, parce qu’on est amis : WSL n’est pas lent — vos fichiers font simplement la navette en heure de pointe.

Pourquoi la frontière fait mal : ce qui se passe réellement de chaque côté

WSL2 est un vrai noyau Linux dans une VM légère

WSL2 exécute un vrai noyau Linux. C’est bon pour la compatibilité et pour les performances à l’intérieur de Linux. Mais cela signifie aussi que Linux possède son propre système de fichiers natif (ext4) stocké dans un disque virtuel (un fichier VHDX) côté Windows.

Dans WSL, quand vous lisez ~/src/app, vous utilisez la pile de fichiers normale de Linux : page cache, métadonnées ext4, recherches d’inodes, mise en cache des entrées de répertoire, etc. C’est le type de chemin d’E/S que Linux a passé des décennies à optimiser.

/mnt/c n’est pas « juste un dossier »

Quand vous accédez aux fichiers Windows depuis WSL, vous le faites généralement via /mnt/c (ou /mnt/d, etc.). Ce chemin est soutenu par un système de fichiers Windows (typiquement NTFS) et présenté à Linux via une couche d’intégration spéciale. Cette couche doit traduire :

  • les permissions Linux en quelque chose que NTFS peut représenter (et inversement)
  • les attentes de sensibilité à la casse
  • le comportement des liens symboliques et leurs métadonnées
  • les notifications de fichiers (inotify vs événements de changement Windows)
  • la sémantique des chemins et les caractères interdits

Le vrai tueur est la forme des charges de travail des développeurs. Les builds et les gestionnaires de paquets ne font pas une grosse lecture séquentielle. Ils réalisent des millions de petites opérations : stat(), open(), close(), balayages de répertoires, créations de fichiers, changements de permissions. Chacun de ces appels peut traverser la frontière.

Antivirus et indexation aiment « aider » au pire moment

Quand les fichiers résident sur le système de fichiers Windows, Windows Defender (ou une autre suite endpoint) peut les scanner à la création/ouverture/modification. Ce n’est pas une erreur morale ; c’est leur travail. Mais les charges de travail des développeurs ressemblent mécaniquement à du malware : des milliers de fichiers éphémères, créés, modifiés et exécutés rapidement.

Dans le ext4 VHDX de WSL, Defender ne peut pas intercepter chaque syscall Linux de la même façon. Le modèle de scan change, et le surcoût diminue souvent considérablement.

Docker et les bind mounts peuvent doubler votre douleur

Si vous utilisez Docker Desktop intégré à WSL, monter en bind un chemin Windows dans un conteneur Linux fait rebondir les E/S à travers plusieurs couches : conteneur → VM Linux → système de fichiers Windows → retour. Si vous montez un chemin WSL (ext4 Linux) dans le conteneur, vous restez majoritairement dans la pile Linux.

Deuxième petite blague (et c’est tout) : si vous bind‑montez /mnt/c dans un conteneur, vous venez d’inventer un nouveau benchmark appelé « temps pour le regret ».

Faits et historique intéressants qui expliquent les bizarreries d’aujourd’hui

  • WSL1 vs WSL2 n’est pas une simple mise à jour. WSL1 traduisait les appels système Linux en appels Windows ; WSL2 exécute un vrai noyau dans une VM, changeant le comportement I/O et la compatibilité.
  • Le système de fichiers Linux de WSL2 vit à l’intérieur d’un VHDX. C’est un fichier de disque virtuel stocké sur Windows, typiquement sous votre profil utilisateur. Le système de fichiers ext4 Linux se trouve à l’intérieur de ce fichier.
  • La métadonnée cross‑filesystem coûte cher. Les outils Linux appellent stat() constamment ; mapper les métadonnées Windows aux sémantiques Linux n’est pas gratuit, surtout à travers une frontière VM.
  • La sensibilité à la casse a une histoire différente. NTFS supporte des fonctionnalités de sensibilité à la casse, mais les outils Windows ont historiquement supposé des chemins insensibles à la casse. Linux suppose la sensibilité à la casse. Le glue de compatibilité doit arbitrer.
  • Inotify est central pour les stacks modernes. Webpack, Jest, serveurs de langage — beaucoup dépendent des événements du système de fichiers Linux. Mapper ces notifications entre Windows et Linux est notoirement délicat et parfois lent.
  • Les charges de petits fichiers sont le pire cas pour les couches frontières. Bases de données, gestionnaires de paquets et systèmes de build réalisent beaucoup de fsync, de renommages, de fichiers temporaires et de churn de répertoires — exactement ce que les « systèmes de fichiers d’interop » détestent.
  • La protection endpoint en entreprise a changé la donne. À mesure que la sécurité en entreprise s’est renforcée, le surcoût des scans côté Windows est devenu plus visible. Le même PC peut « sembler rapide » ou « sembler cassé » simplement en déplaçant un dépôt.
  • Le montage drvfs de WSL a des options sensibles aux performances. Des réglages comme la gestion des métadonnées peuvent modifier la justesse et la vitesse quand on utilise /mnt/c.

Recette de diagnostic rapide (trouver le goulet en minutes)

Si quelqu’un dit « WSL est lent », ne commencez pas par tweaker des sysctls obscurs. Commencez par déterminer de quel côté de la frontière ils se trouvent et quelle est la forme des I/O.

Première étape : identifiez où se trouve le dépôt

  • Si le chemin commence par /mnt/, supposez un surcoût de frontière jusqu’à preuve du contraire.
  • Si le chemin est sous /home (ou un autre chemin natif Linux), le ralentissement provient probablement d’ailleurs : contention CPU, pression mémoire, scan antivirus du fichier VHDX, schémas de montage Docker, ou un problème pathologique dans la chaîne d’outils.

Deuxième étape : identifiez le type de charge

  • Beaucoup de petits fichiers (node_modules, site‑packages Python, Git status, ripgrep, indexation serveur de langage) : la frontière domine.
  • Fichiers séquentiels volumineux (traitement média, checkpoints de modèles) : vous êtes plus probablement limité par le débit disque brut ou le CPU.
  • Beaucoup de fsync/rename (bases de données, gestionnaires de paquets) : les couches de cohérence et la sémantique de sync dominent.

Troisième étape : vérifiez les schémas de « double traduction »

  • Exécuter des outils Linux sur des fichiers Windows (/mnt/c)
  • Exécuter des outils Windows sur des fichiers Linux (\\wsl$ accès intensif par des applis Windows)
  • Conteneurs qui bind‑montent des chemins Windows dans des conteneurs Linux

Quatrième étape : mesurez, ne supposez pas

Choisissez un micro‑benchmark qui correspond à la charge : parcours de répertoire, créations de fichiers, git status, ou une étape de build. Comparez chemin Linux vs chemin Windows. Si vous voyez un grand écart, la décision est simple : déplacez les fichiers ou changez la stratégie de montage.

Tâches pratiques : commandes, sorties et décisions à prendre

Ce sont des commandes réelles que vous pouvez exécuter dans WSL. Chaque tâche inclut ce que signifie la sortie et ce que vous devez faire ensuite.

Task 1: Confirm which WSL version you’re using

cr0x@server:~$ wsl.exe -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Running         2

Signification : VERSION 2 signifie que vous êtes sur WSL2 (bon choix par défaut). VERSION 1 se comporte différemment, spécialement pour l’interop des systèmes de fichiers.

Décision : Si vous êtes sur WSL1 et avez besoin d’une meilleure compatibilité Linux ou d’un meilleur comportement du système de fichiers natif, migrez vers WSL2. Si votre flux de travail concerne surtout l’accès au système de fichiers Windows, WSL1 peut parfois paraître moins mauvais sur /mnt/c — mais c’est un compromis de niche.

Task 2: See where you are (WSL path vs Windows mount)

cr0x@server:~$ pwd
/mnt/c/Users/alex/projects/myapp

Signification : Vous êtes sur le système de fichiers Windows via /mnt/c.

Décision : Si ce dépôt contient beaucoup de petits fichiers (la plupart en contiennent), déplacez‑le dans ~/src et relancez l’opération lente. Attendez‑vous à un changement radical.

Task 3: Identify the filesystem type backing your current directory

cr0x@server:~$ df -T .
Filesystem     Type  1K-blocks      Used Available Use% Mounted on
C:             9p    487531516 214221812 273309704  44% /mnt/c

Signification : Le Type 9p indique un mécanisme de partage de fichiers paravirtualisé. C’est le chemin frontière ; les charges de travail lourdes en métadonnées en souffrent souvent.

Décision : Si vous voyez ext4 sous / ou /home, vous êtes sur le système de fichiers natif WSL. Si vous voyez 9p (ou similaire), évitez d’exécuter des builds ici.

Task 4: Compare “stat storm” behavior on Windows vs Linux paths

cr0x@server:~$ time bash -lc 'for i in {1..2000}; do stat /mnt/c/Windows/notepad.exe >/dev/null; done'

real    0m3.214s
user    0m0.103s
sys     0m0.521s

Signification : Des milliers d’opérations de métadonnées sur /mnt/c coûtent des secondes.

Décision : Si votre charge ressemble à ceci (Git, Node, Python), ne laissez pas le dépôt sur /mnt/c.

Task 5: Run the same metadata loop on the Linux filesystem

cr0x@server:~$ time bash -lc 'for i in {1..2000}; do stat /bin/bash >/dev/null; done'

real    0m0.152s
user    0m0.092s
sys     0m0.054s

Signification : Même motif d’appel système, beaucoup plus rapide sur des chemins Linux natifs.

Décision : Utilisez ce test avant/après le déplacement d’un dépôt pour prouver que le problème est le surcoût de frontière, pas « WSL est lent ».

Task 6: Check mount options for /mnt/c (they matter)

cr0x@server:~$ mount | grep " /mnt/c "
C: on /mnt/c type 9p (rw,relatime,dirsync,aname=drvfs;path=C:\;uid=1000;gid=1000;metadata,umask=22,fmask=11)

Signification : Des options comme metadata influencent la façon dont les permissions Linux sont stockées/émulées sur des fichiers Windows. Certaines options améliorent la justesse mais peuvent coûter en performances.

Décision : Si vous devez travailler sur /mnt/c, soyez intentionnel concernant les options de montage via /etc/wsl.conf. Si vous n’avez pas de raison forte, n’optimisez pas ça — déplacez le dépôt à la place.

Task 7: Confirm your WSL distro filesystem is ext4

cr0x@server:~$ df -T /
Filesystem     Type  1K-blocks     Used Available Use% Mounted on
/dev/sdc       ext4  263174212 73488328 176211952  30% /

Signification : ext4 est le système de fichiers Linux natif dans WSL2. C’est là que vous voulez vos dépôts et artefacts de build.

Décision : Si / est ext4, vous avez déjà la voie rapide. Placez vos projets ici.

Task 8: Find top I/O offenders during a slow command

cr0x@server:~$ sudo apt-get update -y >/dev/null 2>&1; sudo apt-get install -y strace >/dev/null 2>&1
cr0x@server:~$ strace -f -tt -T -o /tmp/trace.log git status >/dev/null 2>&1
cr0x@server:~$ tail -n 3 /tmp/trace.log
12:01:11.402033 stat("/mnt/c/Users/alex/projects/myapp/.git/index", {st_mode=S_IFREG|0644, st_size=112394, ...}) = 0 <0.011224>
12:01:11.413901 openat(AT_FDCWD, "/mnt/c/Users/alex/projects/myapp/node_modules", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 <0.019887>
12:01:11.434022 getdents64(3, /* 256 entries */, 32768) = 8192 <0.028441>

Signification : Les appels touchant /mnt/c prennent des dizaines de millisecondes chacun. Multipliez par des milliers et vous obtenez de la tristesse.

Décision : Déplacez le dépôt. Si vous ne pouvez pas, réduisez le nombre de fichiers (vendoring, élagage de node_modules) ou changez le workflow pour éviter les opérations lourdes en métadonnées.

Task 9: Check memory pressure (paging turns I/O into molasses)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           7.7Gi       6.9Gi       214Mi       118Mi       630Mi       356Mi
Swap:          2.0Gi       1.8Gi       220Mi

Signification : Vous êtes sous pression mémoire et utilisez du swap. Chaque opération de fichier concurrence le paging.

Décision : Fermez la ferme d’onglets du navigateur, réduisez le parallélisme, ou ajustez les limites mémoire de WSL (via .wslconfig sous Windows) si votre charge a réellement besoin de RAM.

Task 10: Measure directory traversal speed where your repo lives

cr0x@server:~$ time bash -lc 'find . -type f >/dev/null'

real    0m7.842s
user    0m0.231s
sys     0m1.104s

Signification : Un simple parcours de répertoire prenant ~8 secondes est un grand drapeau rouge pour un surcoût de frontière (ou un dépôt énorme, mais vous le sauriez).

Décision : Lancez le même find après avoir déplacé le dépôt dans ~/src. Si le temps diminue de façon significative, vous avez trouvé le goulet.

Task 11: Check whether your repo accidentally lives on Windows via symlink/path confusion

cr0x@server:~$ readlink -f .
/mnt/c/Users/alex/projects/myapp

Signification : Même si votre invite de commande paraît « Linux », ceci confirme le véritable chemin de stockage.

Décision : Si cela résout en /mnt/*, considérez‑le comme un accès au système de fichiers Windows et attendez‑vous à des I/O métadonnées plus lentes.

Task 12: Validate that Git is doing extra work due to filesystem semantics

cr0x@server:~$ git config --show-origin --get core.fscache
file:/home/cr0x/.gitconfig    true
cr0x@server:~$ git config --show-origin --get core.preloadindex
file:/home/cr0x/.gitconfig    true

Signification : Le cache de système de fichiers de Git et le preload index peuvent aider, mais ce n’est pas magique si vous êtes sur /mnt/c. Ils réduisent certains appels système ; ils n’éliminent pas la frontière.

Décision : Gardez ces options activées pour les gros dépôts, mais ne les utilisez pas comme excuse pour garder le dépôt sur Windows. Déplacez le dépôt d’abord.

Task 13: Check whether your slow path is a container bind mount from Windows

cr0x@server:~$ docker info 2>/dev/null | sed -n '1,12p'
Client:
 Version:           26.1.0
Server:
 Containers: 3
  Running: 1
  Paused: 0
  Stopped: 2
 Storage Driver: overlay2

Signification : Docker est présent et probablement intégré à WSL. Maintenant la question est : vers où pointent vos bind mounts.

Décision : Si votre docker run -v utilise des chemins /mnt/c, changez‑les pour un chemin WSL (pour des conteneurs Linux) et retestez.

Task 14: Observe mount sources inside a running container

cr0x@server:~$ docker run --rm -v /mnt/c/Users/alex/projects/myapp:/work alpine sh -lc 'mount | head -n 5'
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/...,upperdir=/var/lib/docker/overlay2/...,workdir=/var/lib/docker/overlay2/...)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
9p on /work type 9p (rw,relatime,trans=fd,rfdno=...,wfdno=...)

Signification : Le conteneur voit le bind mount comme 9p. C’est encore la frontière, maintenant à l’intérieur du conteneur.

Décision : Pour des conteneurs Linux, bind‑montez un chemin sous /home dans WSL à la place. Le conteneur le verra typiquement comme un système de fichiers Linux natif et se comportera mieux.

Trois mini‑histoires d’entreprise issues du terrain

1) Incident causé par une fausse hypothèse : « C’est le réseau »

Le ticket arrivait comme un classique : « CI est OK, mais les builds locaux sont aléatoirement lents. » L’équipe utilisait des laptops Windows avec WSL2. Le dépôt était énorme, un monorepo avec un système de build qui aimait scanner le monde pour décider ce qui a changé. On a accusé le Wi‑Fi, le VPN, le DNS — tout ce qui ressemblait à une dépendance réseau partagée.

Un ingénieur a même escaladé comme un « incident réseau » parce que le pull des dépendances semblait lent et que git status était lent. C’était la mauvaise hypothèse, mais plausible. En entreprise, la plausibilité suffit souvent à perdre une semaine.

Nous avons fait ce que font les SRE quand ils en ont assez des narrations : nous avons mesuré. Un strace a montré que le build n’attendait pas des sockets ; il attendait des stat() et getdents64() contre /mnt/c. Le dépôt avait été cloné dans un répertoire Windows pour qu’un IDE Windows « le voie facilement ». Chaque build incrémental parcourait des dizaines de milliers de fichiers à travers la frontière.

La correction fut terriblement ennuyeuse : cloner dans ~/src, utiliser Remote WSL pour l’éditeur, et cesser d’essayer de faire vivre un même répertoire pour deux systèmes d’exploitation. Les temps de build se sont stabilisés. L’« aléatoire » a disparu parce qu’il n’avait jamais été aléatoire ; c’était juste des effets de cache et des scans en arrière‑plan amplifiant un chemin fondamentalement lent.

La leçon du postmortem ne portait pas sur WSL. Elle portait sur les hypothèses. Si vous traitez la performance locale par défaut comme un problème réseau, vous continuerez à « réparer » les VPN pendant que vos fichiers prennent le chemin pittoresque.

2) Optimisation qui s’est retournée contre eux : « Gardons sur C: pour les sauvegardes »

Une autre organisation avait une directive de conformité : les postes développeurs doivent sauvegarder « le travail » quotidiennement. Quelqu’un a décidé que la façon la plus simple d’assurer la conformité était d’exiger que les dépôts vivent sous le profil Windows de l’utilisateur. Ainsi l’agent de sauvegarde Windows existant capturerait tout sans cas particuliers.

Sur le papier, c’était propre. En pratique, c’était une politique anti‑performance. Les projets Node et Python ramèrent. Les conteneurs avec des bind mounts vers ces répertoires tournaient comme s’ils utilisaient un lecteur réseau de 1998. Les développeurs ont commencé à contourner : copier les dépôts ailleurs, désactiver des contrôles de sécurité quand ils le pouvaient, ou travailler temporairement sur des disques non sauvegardés.

L’optimisation tentée — simplifier les sauvegardes — a créé un nouveau risque. L’équipe sécurité a vu proliférer des exceptions. L’équipe dev a vu la productivité chuter. Tout le monde est devenu grognon, ce qui est le métrique le plus fiable en opérations.

Le compromis final fut plus intelligent : garder les sources dans WSL pour la performance, et sauvegarder via un mécanisme approuvé capable de gérer le VHDX WSL ou exporter les dépôts critiques selon un planning. Cela a demandé coordination et un peu d’effort d’ingénierie, ce qui explique que ce ne fut pas la première solution adoptée.

C’est le pattern : une optimisation qui ignore la forme des I/O du développement se retournera contre vous. Vous ne pouvez pas régler les appels système par politique.

3) Pratique ennuyeuse mais correcte qui a sauvé la mise : « Standardiser l’emplacement du code »

Une équipe plateforme en eut assez que chaque session d’onboarding se transforme en atelier de debug performance sur mesure. Ils ne voulaient pas d’héroïsme ; ils voulaient un défaut qui marche. Ils ont donc standardisé un petit ensemble de pratiques : le code va dans ~/src à l’intérieur de WSL, les devcontainers montent depuis là, et les éditeurs se connectent via WSL remote.

Ils ont aussi codifié deux diagnostics dans le document d’onboarding : exécuter df -T . pour confirmer que vous êtes sur ext4, et lancer un petit test de timing find. Si l’un des deux tests échouait, la configuration n’était pas « terminée », peu importe si l’app compilait une fois.

Puis vint le jour où un nouveau rollout d’un agent de sécurité Windows causa un surcoût notable sur les opérations de fichiers des répertoires utilisateurs Windows. Cela aurait pu être le chaos : équipes manquant des livrables, centaine de messages « WSL est cassé », et la balle entre IT et ingénierie.

Mais les équipes qui suivaient la règle ennuyeuse l’ont à peine remarqué. Leurs chemins chauds vivaient dans ext4 de WSL, à l’écart des nouveaux hooks de scan. Les tickets de support sont quand même arrivés, mais ils se sont concentrés sur les personnes qui avaient dévié de la norme. C’est une belle propriété opérationnelle : le rayon d’explosion corrèle avec la non‑conformité.

La pratique n’était pas ingénieuse. Elle était correcte. Et le correct s’échelonne mieux que l’ingénieux, à chaque fois.

Erreurs courantes : symptôme → cause racine → fix

Voici ce que je vois régulièrement : mêmes symptômes, mêmes causes, mêmes correctifs. Si vous reconnaissez votre douleur ici, arrêtez d’expérimenter et appliquez le correctif.

1) « git status prend une éternité »

  • Symptôme : git status prend 2–20 secondes sur un dépôt moyen.
  • Cause racine : Dépôt sur /mnt/c et Git parcourt beaucoup de fichiers + surcoût métadonnées frontière.
  • Fix : Déplacez le dépôt dans ~/src. Gardez les opérations Git dans WSL. Utilisez VS Code Remote – WSL si vous voulez une UI Windows.

2) « npm install est insupportablement lent »

  • Symptôme : Le CPU n’est pas saturé, mais le temps d’installation est énorme ; beaucoup de temps « à rien faire ».
  • Cause racine : Des milliers de petites créations de fichiers sur le système de fichiers Windows ; possible scan antivirus à chaque écriture.
  • Fix : Gardez le projet et le cache de paquets dans le ext4 de WSL. Évitez d’installer node_modules sur /mnt/c. Si la politique d’entreprise impose des chemins Windows, négociez des exclusions Defender pour le répertoire pertinent (soigneusement et avec validation sécurité).

3) « Le hot reload de mon appli ne détecte pas les changements, alors je mets le code sur /mnt/c »

  • Symptôme : Les watchers de fichiers ratent des événements dans WSL, donc quelqu’un a déplacé le dépôt vers Windows pour « réparer ».
  • Cause racine : Limites de watchers mal configurées ou problèmes spécifiques aux outils ; déplacer vers Windows a échangé la justesse contre des problèmes de performance.
  • Fix : Corrigez les watchers dans WSL (augmentez les limites inotify, ajustez l’outil pour polling si nécessaire). Gardez le dépôt dans WSL ; ne le déplacez pas vers Windows comme réponse initiale.

4) « Les builds Docker sont lents quand je monte ma source »

  • Symptôme : Les builds conteneurisés traînent ; les builds natifs sont moins mauvais.
  • Cause racine : Bind mount depuis /mnt/c dans un conteneur Linux ; le conteneur voit un montage 9p et en souffre.
  • Fix : Bind‑montez depuis des chemins ext4 de WSL. Ou copiez la source dans l’image pour les étapes de build intensives en I/O (et acceptez le compromis).

5) « C’était rapide hier »

  • Symptôme : Même dépôt, mêmes commandes, ralentissement soudain.
  • Cause racine : Pression mémoire, mise à jour Windows/Defender modifiant le comportement de scan, VM WSL dans un mauvais état, ou le dépôt déplacé silencieusement (décompression zip dans un dossier Windows, etc.).
  • Fix : Reconfirmez le type de chemin (df -T .), vérifiez la mémoire (free -h), et essayez wsl.exe --shutdown depuis Windows pour réinitialiser l’état de la VM.

6) « Mon éditeur est lent, pas le build »

  • Symptôme : Recherche, indexation et fonctionnalités du serveur de langage laguent.
  • Cause racine : L’éditeur est natif Windows et scanne intensément \\wsl$, ou l’éditeur est dans WSL et scanne /mnt/c. Dans les deux cas : la frontière.
  • Fix : Alignez éditeur et système de fichiers. Éditeur Windows + fichiers Windows, ou outils WSL + fichiers WSL avec intégration distante.

Listes de contrôle / plan étape par étape

Checklist A: Le plan « rendre rapide » (le défaut à suivre)

  1. Créez un emplacement pour les dépôts à l’intérieur de WSL :
    cr0x@server:~$ mkdir -p ~/src
    
  2. Clonez votre dépôt dans WSL :
    cr0x@server:~$ cd ~/src
    cr0x@server:~$ git clone git@github.com:example/acme-app.git
    Cloning into 'acme-app'...
    remote: Enumerating objects: 12453, done.
    Receiving objects: 100% (12453/12453), 22.3 MiB | 18.2 MiB/s, done.

    Décision : Si cloner ici est rapide mais que les builds étaient lents sur /mnt/c, vous avez validé la règle.

  3. Exécutez votre commande lente à nouveau (build/test/install) et mesurez :
    cr0x@server:~$ cd ~/src/acme-app
    cr0x@server:~$ time git status
    On branch main
    Your branch is up to date with 'origin/main'.
    
    real    0m0.187s
    user    0m0.090s
    sys     0m0.070s

    Décision : Si le temps est passé de secondes à sous‑seconde, arrêtez de déboguer et adoptez la règle définitivement.

  4. Gardez aussi les artefacts de build à l’intérieur de WSL. N’écrivez pas vers /mnt/c « par commodité ». La commodité est la façon dont la latence s’invite.

Checklist B: Si vous devez utiliser /mnt/c quand même (faites‑le en connaissance de cause)

  1. Confirmez que vous êtes sur /mnt/c :
    cr0x@server:~$ df -T .
    Filesystem     Type  1K-blocks      Used Available Use% Mounted on
    C:             9p    487531516 214221812 273309704  44% /mnt/c

    Décision : Attendez‑vous à ce que les opérations riches en métadonnées soient plus lentes. Planifiez des mesures d’atténuation.

  2. Réduisez le churn de fichiers : évitez de gros arbres de dépendances quand possible, utilisez des lockfiles, taillez les dépendances de dev, et conservez les caches dans WSL si l’outil le permet.
  3. Méfiez‑vous des ajustements d’options de montage. Ils peuvent échanger vitesse contre justesse. Si votre environnement dépend des permissions Unix, désactiver metadata peut casser des builds de façon subtile.

Checklist C: Workflows conteneurs (Docker/Podman) qui ne vous sabordent pas

  1. Gardez la source sur ext4 (~/src).
  2. Bind‑montez depuis un chemin WSL :
    cr0x@server:~$ docker run --rm -v /home/cr0x/src/acme-app:/work -w /work node:20-bullseye bash -lc 'node -v'
    v20.11.1

    Décision : Si le montage apparaît comme un système de fichiers Linux natif dans le conteneur (pas 9p), vous êtes sur la bonne voie.

  3. Si les builds traînent toujours, évitez les bind mounts pour l’étape de build : copiez la source dans le Dockerfile et build‑ez dans l’image. C’est généralement plus rapide pour les I/O lourdes et meilleur pour la reproductibilité, mais moins bon pour la vitesse d’itération. Choisissez consciemment.

Une citation (idée paraphrasée) importante

Werner Vogels (idée paraphrasée) : « Tout échoue, tout le temps — concevez et opérez les systèmes en tenant compte de cette réalité. »

Ceci est un article sur la performance, mais aussi sur l’exploitation : supposez que la frontière vous trahira sous charge, parce que c’est un point d’intégration complexe. Placez votre chemin chaud quelque part d’ennuyeux et natif.

FAQ

1) Qu’est‑ce que « la frontière du système de fichiers » dans WSL ?

C’est la ligne entre le stockage natif Linux à l’intérieur de WSL (ext4 dans le VHDX de WSL) et le stockage Windows monté dans WSL (typiquement /mnt/c). La traverser force la traduction et souvent des scans supplémentaires.

2) WSL2 est‑il toujours plus rapide que WSL1 ?

Non. WSL2 est généralement plus rapide pour l’accès natif au système de fichiers Linux et pour la compatibilité. WSL1 peut parfois sembler moins pénible lorsqu’on opère directement sur des fichiers Windows parce qu’il n’implique pas le même chemin de partage de fichiers VM. La plupart des configurations de dev modernes bénéficient cependant de WSL2 si vous suivez la règle et gardez le code sur ext4.

3) Puis‑je garder mon dépôt sur Windows et simplement « tuner » WSL ?

Vous pouvez améliorer les choses en marge, mais vous luttez contre la physique : beaucoup d’opérations métadonnées à travers une couche de traduction. Si la performance compte, déplacez le dépôt. Le tuning sert les contraintes, pas les préférences.

4) Qu’en est‑il de l’accès aux fichiers WSL depuis des applis Windows via \\wsl$ ?

Un accès occasionnel est acceptable. L’accès intensif Windows‑side, l’indexation ou la construction contre des chemins \\wsl$ peut réintroduire la douleur de frontière dans l’autre sens. Gardez l’outil « lourd » du même côté que les fichiers.

5) Pourquoi Node.js (et node_modules) pose‑t‑il souvent problème ?

Parce que c’est une usine à petits fichiers. Les installateurs et bundlers créent et parcourent d’énormes arbres de répertoires, touchant constamment les métadonnées. Les systèmes de fichiers frontières sont au pire sur ce motif exact.

6) L’antivirus compte‑t‑il vraiment autant ?

Oui, souvent. L’antivirus est optimisé pour la sécurité, pas pour votre graphe de build. Lorsqu’il intercepte les événements open/create sur des chemins Windows, il peut ajouter une latence notable par opération. Des milliers d’opérations plus tard, votre café est refroidi.

7) Si je déplace mon dépôt dans WSL, comment le sauvegarder ?

Utilisez des remotes Git comme source de vérité et considérez les clones locaux comme jetables quand c’est possible. Si vous avez besoin de sauvegardes de poste, utilisez une approche approuvée qui capture les données WSL (ou exportez périodiquement les dépôts). Ne « résolvez » pas les sauvegardes en forçant des chemins lents pour le développement quotidien.

8) Mon entreprise exige des dépôts sous mon répertoire Windows. Quelle est la moins mauvaise option ?

Argumentez avec des mesures : montrez les timings avant/après et les sorties df -T. Proposez une alternative conforme (sauvegarde des données WSL ou mirroring des sources). Si vous ne pouvez pas changer la politique, réduisez le churn de fichiers, évitez les conteneurs qui bind‑montent des chemins Windows, et conservez les caches dans WSL quand c’est permis.

9) Est‑il sûr de stocker des données importantes dans le VHDX ext4 de WSL ?

C’est aussi sûr que n’importe quelle donnée locale — ce qui signifie que vous avez toujours besoin de sauvegardes. Ce n’est pas intrinsèquement dangereux, mais ce n’est pas magique non plus. Si votre portable meurt, votre VHDX meurt avec lui à moins d’un plan.

10) Quel est le meilleur test unique pour prouver que le problème vient des I/O frontière ?

Exécutez la même opération dans le même dépôt une fois sur /mnt/c et une fois après l’avoir cloné dans ~/src. Si le temps change par multiples, c’est un surcoût de frontière. Pas de débat nécessaire.

Conclusion : étapes pratiques suivantes

Si vous ne retenez qu’une chose : gardez les charges Linux sur des systèmes de fichiers Linux. Clonez dans ~/src. Build là. Exécutez les conteneurs depuis là. Utilisez l’intégration distante de l’éditeur pour ne pas avoir l’impression d’abandonner l’UI Windows.

Prochaines étapes réalisables aujourd’hui :

  1. Exécutez pwd et df -T . dans votre dépôt. Si vous voyez /mnt/c et 9p, vous avez trouvé le problème.
  2. Clonez le dépôt dans ~/src et relancez votre commande lente avec time. Conservez les chiffres.
  3. Si Docker est impliqué, cessez de bind‑monter des chemins Windows pour des conteneurs Linux.
  4. Standardisez la règle dans votre équipe. Les problèmes de performance aiment l’incohérence.

WSL n’est pas un mystère. C’est une interface entre deux systèmes d’exploitation avec des hypothèses différentes. Respectez la frontière, et WSL arrêtera de se comporter comme s’il avait mieux à faire.

← Précédent
Dock USB‑C : scintillements et déconnexions — ordre de firmware et pilotes qui fonctionne
Suivant →
Stockage : iSCSI vs NFS vs NVMe-oF — Lequel l’emporte vraiment et pourquoi

Laisser un commentaire