WSL puede sentirse como un superpoder: herramientas Linux con escritorio Windows, cambio de contexto instantáneo, sin costo de reinicio. Y luego, un día, abres tu distro y… esperas. Y esperas. Un terminal en blanco te mira como si estuviera negociando su contrato.
La mayoría de las quejas de “WSL está lento” no se deben a la CPU. Son por timeouts, scripts de inicialización de shell que hacen demasiado, montajes rotos y suposiciones de red que eran ciertas en un portátil en 2019 y falsas en una VPN corporativa en 2026. La solución rara vez es un ajuste mágico. Es diagnóstico disciplinado y poda implacable.
Hechos interesantes y contexto
- WSL 1 vs WSL 2 son universos distintos. WSL 1 traduce llamadas al sistema de Linux a llamadas de Windows; WSL 2 ejecuta un kernel Linux real en una VM ligera. Los modos de fallo al iniciar cambian en consecuencia.
- WSL 2 usa un disco virtual (VHDX) por distro. Eso significa que el rendimiento de almacenamiento está determinado por el VHDX, el comportamiento del sistema de archivos del host, el escaneo del antivirus y dónde vive el VHDX (por ejemplo, HDD lento vs NVMe).
- El soporte de systemd llegó tarde y cambió las expectativas. Durante años la gente improvisó “sin init” con scripts personalizados. Cuando systemd se soportó, esas chapuzas no desaparecieron por arte de magia.
- /mnt/c no es “solo una carpeta”. Es una frontera entre sistemas de archivos de dos OS con semánticas y sobrecoste diferentes. Compilar mucho allí puede sentirse como trabajar en el lodo.
- Las VPN corporativas adoran romper la resolución de nombres. Un shell WSL que hace una consulta DNS por prompt puede pasar de “bien” a “cuelga 8 segundos” de la noche a la mañana.
- Muchos problemas de inicio lento en WSL son autoinfligidos. Frameworks de prompt, gestores de plugins y scripts “útiles” que llaman a git, kubectl o CLIs cloud en el arranque son los culpables habituales.
- El inicio de WSL no es una sola cosa. Hay inicialización de la distro, configuración de montajes, configuración de red, luego el inicio del shell, y después lo que decidan hacer tus scripts de shell.
- Windows Defender puede importar más que tu CPU. El escaneo en tiempo real sobre directorios de repos (especialmente node_modules y artefactos de build) puede dominar la latencia percibida.
- PATH puede ser un problema de rendimiento. Importar un PATH enorme de Windows en WSL hace que la búsqueda de comandos sea más lenta y rompe herramientas de maneras creativas.
Cómo funciona realmente el inicio de WSL (para que dejes de adivinar)
Cuando lanzas una distro WSL, no estás “arrancando Linux” de la misma forma que arrancas una VM en una UI de hypervisor. Pero tampoco simplemente lanzas un proceso como podía parecer WSL 1. WSL 2 inicia (o reanuda) una VM ligera que alberga un kernel Linux, adjunta el VHDX de la distro, configura la red virtual y luego ejecuta el comando solicitado—normalmente tu shell por defecto.
Desde la perspectiva de latencia hay cuatro capas, y cada una tiene su firma cuando falla:
1) Arranque / reanudación de la VM
Si WSL ha estado inactivo, puede haberse apagado. El siguiente lanzamiento debe arrancar la VM de WSL. Normalmente es rápido, pero puede alargarse cuando el host está bajo presión de memoria, cuando el almacenamiento es lento o cuando algo fuerza trabajo extra (como protección de endpoints agresiva).
2) Inicialización de la distro (y systemd, si está activado)
WSL moderno puede ejecutar systemd. Eso es bueno—los servicios se comportan normalmente—pero añade comportamiento parecido a un arranque. Si una unidad es lenta, falla o espera por la red, pagarás ese coste durante el “inicio”. Si systemd no está habilitado, aún puedes tener scripts init heredados o hacks en tiempo de login que intentan emularlo.
3) Montajes y wiring de interoperabilidad
WSL conecta unidades de Windows, configura /mnt y opcionalmente importa variables de entorno de Windows como PATH. El comportamiento de montaje se puede configurar en /etc/wsl.conf. Cuando los montajes están mal, verás cuelgues que parecen “el shell no abre”, pero el verdadero culpable es un montaje bloqueante o una comprobación de sistema de archivos.
4) Inicialización del shell
Esta es la parte que controlas. Bash lee /etc/profile y tus dotfiles personales. Zsh lee archivos distintos. Fish tiene su propio mundo. Si tu prompt ejecuta git status en un repo enorme, o tu profile llama a un CLI cloud que espera un proxy, el terminal parecerá “atascado” aunque WSL esté bien.
Una cita que vale la pena tener en la pared, porque el rendimiento de inicio es mayormente esperar dependencias:
idea parafraseada — Werner Vogels: “Todo falla, todo el tiempo; diseña sistemas que lo esperen.”
En el mundo WSL, “falla” a menudo significa “timeout”, que es una falla con traje.
Playbook rápido de diagnóstico (primero/segundo/tercero)
Si quieres que WSL arranque rápido, necesitas identificar qué capa es la que está lenta. No empieces por reescribir dotfiles. No empieces por reinstalar la distro. Empieza midiendo de forma que aisles el cuello de botella.
Primero: aislar inicio del shell vs todo lo demás
- Lanza WSL con un comando que evite la inicialización interactiva del shell.
- Si eso es rápido, tu problema está en dotfiles/prompt/plugins.
- Si eso sigue siendo lento, el problema es WSL/distro/systemd/montaje/red.
Segundo: comprobar systemd y servicios (si están habilitados)
- Pide a systemd cuánto tiempo tardó.
- Busca unidades que esperen por red, DNS o montajes.
- Deshabilita lo que no necesites para shells de desarrollo.
Tercero: red/DNS y montajes
- Los timeouts de DNS son el culpable número 1 de los “5–10 segundos” aleatorios.
- El acceso a /mnt/c y la importación del PATH de Windows son culpables comunes de “muerte por mil cortes”.
- Si todo lo demás parece limpio, entonces ataca la ubicación del almacenamiento/VHDX y las exclusiones de antivirus.
Broma #1: Si tu prompt ejecuta tres llamadas de red, no es un prompt. Es un sistema distribuido con sentimientos.
Tareas prácticas: comandos, salidas y decisiones
Arreglar esto será más rápido si lo tratas como un incidente: recopila evidencias, aisla variables, haz un cambio a la vez y ten un camino de reversión. Abajo hay tareas reales con comandos, salidas de ejemplo y qué decidir según ellas.
Task 1: Mide el tiempo de iniciar WSL sin tu shell interactivo
cr0x@server:~$ /usr/bin/time -p wsl.exe -d Ubuntu-22.04 -- bash -lc 'true'
real 0.62
user 0.00
sys 0.00
Qué significa la salida: El número real es tiempo de reloj. Esto omite la lógica de prompt interactivo y la mayor parte del drama de los dotfiles.
Decisión: Si esto es rápido (<1–2s) pero tu terminal normal es lento, ve directo a depurar la inicialización del shell. Si esto es lento, sigue investigando systemd/montajes/red/almacenamiento.
Task 2: Compara el tiempo de inicio del shell interactivo
cr0x@server:~$ /usr/bin/time -p bash -lic 'exit'
real 2.87
user 0.19
sys 0.08
Qué significa la salida: Esto mide el inicio de login + interactivo. Si real es mucho mayor que user y sys, estás esperando I/O, red o subprocessos bloqueantes.
Decisión: Si lo interactivo es lento pero lo no interactivo es rápido, dotfiles/prompt/plugins son el sospechoso principal.
Task 3: Ve qué shell estás ejecutando y cómo se invocó
cr0x@server:~$ echo "$0"; ps -p $$ -o pid,ppid,cmd
-bash
PID PPID CMD
812 799 -bash
Qué significa la salida: Un guion inicial indica un login shell. Eso cambia qué archivos se cargan (/etc/profile, ~/.bash_profile, etc.).
Decisión: Si estás ejecutando accidentalmente un login shell cuando no lo necesitas, corrige el perfil del terminal (Windows Terminal / VS Code) para iniciar un shell no login y ganar velocidad.
Task 4: Traza qué está cargando tu shell (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
Qué significa la salida: Confirma que estás en un login shell y muestra la versión de bash (relevante para características de inicio y compatibilidad).
Decisión: Si los login shells son lentos, mueve cosas pesadas fuera de los archivos de solo login y dentro de funciones bajo demanda, o deja de usar login shells para sesiones interactivas.
Task 5: Usa xtrace de bash para encontrar la línea lenta
cr0x@server:~$ bash -lic 'PS4="+\t\D{%s}\t"; set -x; source ~/.bashrc; exit' 2> /tmp/bashrc.trace
...output...
Qué significa la salida: El archivo de traza tiene marcas de tiempo por línea ejecutada. Busca grandes brechas entre marcas.
Decisión: Elimina, difiere o protege los comandos lentos. Si la brecha coincide con llamar a git, kubectl, gcloud, npm o herramientas DNS, has encontrado el ancla.
Task 6: Perfilado de Zsh (si usas 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
Qué significa la salida: Ordena funciones por tiempo. compinit y ayudantes de prompt git sofisticados suelen dominar.
Decisión: Cachea la completación, reduce plugins o cambia a un prompt más simple. En WSL, “ágil” vence a “bonito”.
Task 7: Comprueba si systemd está habilitado y si es lento
cr0x@server:~$ ps -p 1 -o pid,comm,args
PID COMMAND COMMAND
1 systemd /sbin/init
Qué significa la salida: Si PID 1 es systemd, entonces el inicio de WSL incluye trabajo de unidades de systemd.
Decisión: Si systemd está habilitado y no necesitas servicios, considera desactivarlo. Si lo necesitas, mide y ajusta las unidades.
Task 8: Mide el tiempo de arranque de systemd y encuentra unidades lentas
cr0x@server:~$ systemd-analyze time
Startup finished in 2.103s (kernel) + 5.882s (userspace) = 7.985s
graphical.target reached after 5.841s in userspace
Qué significa la salida: El tiempo de userspace es donde residen los servicios lentos.
Decisión: Si userspace son varios segundos, lista el blame.
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
Qué significa la salida: Estas unidades consumieron más tiempo. wait-online es la clásica unidad “¿por qué espero una red que no existe?”.
Decisión: Enmascara o reconfigura servicios que no pertenecen a un entorno de desarrollo interactivo.
Task 9: Revisa montajes y si estás pagando extra por unidades de Windows
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)
Qué significa la salida: Las unidades de Windows están montadas como drvfs. Opciones como metadata y case afectan compatibilidad y rendimiento.
Decisión: Si tu flujo usa permisos Linux intensamente, conserva metadata. Si no, puedes simplificar. Pero la ganancia mayor es mover repos calientes al sistema de archivos Linux.
Task 10: Detecta si trabajas en /mnt/c (trampa de rendimiento)
cr0x@server:~$ pwd
/mnt/c/Users/alex/source/mega-repo
Qué significa la salida: Estás en almacenamiento de Windows. Compilaciones, instalaciones de paquetes y operaciones git a menudo serán más lentas.
Decisión: Clona el repo bajo ~ (sistema de archivos Linux) y usa un editor que pueda accederlo (VS Code Remote – WSL está diseñado para esto).
Task 11: Comprueba el comportamiento de DNS (falla rápida vs colgado lento)
cr0x@server:~$ getent hosts github.com
140.82.121.4 github.com
Qué significa la salida: La resolución DNS tuvo éxito rápidamente. Si cuelga, ese es tu indicio claro.
Decisión: Si es lento/está colgado, inspecciona /etc/resolv.conf y la configuración DNS de WSL. Si es rápido, la lentitud está en otro lado.
Task 12: Confirma si /etc/resolv.conf se genera automáticamente y qué nameserver usas
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
Qué significa la salida: WSL está generando resolv.conf y apuntando a una IP de gateway virtual. En VPNs esto puede funcionar o convertirse en una fiesta de timeouts.
Decisión: Si el DNS es inestable/lento, desactiva la generación automática y establece una estrategia de resolvers estable para tu entorno (detalles en la sección de redes).
Task 13: Comprueba si la importación del PATH de Windows está inflada
cr0x@server:~$ echo "$PATH" | tr ':' '\n' | wc -l
142
Qué significa la salida: 142 entradas en PATH no es un logro. Es una responsabilidad. Muchas son rutas de Windows que provocan comprobaciones extra en el sistema de archivos.
Decisión: Considera deshabilitar appendWindowsPath en /etc/wsl.conf y añadir explícitamente solo lo que necesites.
Task 14: Identifica si tu prompt hace trabajo git costoso
cr0x@server:~$ PS1='\u@\h:\w\$ ' bash --noprofile --norc
cr0x@server:~$ exit
exit
Qué significa la salida: Esto lanza un bash limpio con un prompt simple. Si responde instantáneamente, tu prompt sofisticado es el problema.
Decisión: Reemplaza frameworks de prompt o configúralos para evitar llamar a git en cada repintado del prompt (o hacerlo solo dentro de repos con caching).
Task 15: Comprobación rápida de comandos colgantes en dotfiles ejecutándolos con timeout
cr0x@server:~$ timeout 2s bash -lc 'source ~/.bashrc; echo ok' || echo "bashrc exceeded 2s"
bashrc exceeded 2s
Qué significa la salida: Tu bashrc no puede terminar en dos segundos en una ejecución no interactiva. Algo dentro está bloqueando.
Decisión: Usa el enfoque de trazado (Task 5) y elimina/protege las partes lentas.
Task 16: Comprueba si la interoperabilidad con Windows está activa y si te perjudica
cr0x@server:~$ cat /proc/sys/fs/binfmt_misc/WSLInterop 2>/dev/null | head -n 5
enabled
interpreter /init
flags: P
offset 0
magic 4d5a
Qué significa la salida: La interoperabilidad está habilitada, así que ejecutar binarios de Windows desde Linux funciona. Eso es conveniente—y a veces lento cuando scripts invocan herramientas de Windows por accidente.
Decisión: Si ves comandos lentos y descubres que se resuelven a binarios de Windows (como git.exe), corrige el orden de PATH o desactiva la interoperabilidad para ese flujo de trabajo.
Detener shells lentos: scripts de perfil, frameworks de prompt y trampas de PATH
El inicio del shell es donde el rendimiento va a morir porque es “solo un script”. Los scripts crecen como el moho: despacio, y de repente estás cargando cinco gestores de plugins y un motor de temas para imprimir tu usuario en cursiva.
WSL amplifica esto porque mucho del “azúcar” del shell asume recursos locales de baja latencia. Pero en WSL podrías estar atravesando /mnt/c, invocando binarios de Windows por accidente o desencadenando consultas DNS a través de una VPN medio dormida.
Sabe qué archivos se ejecutan y evita doble-sourcing
Bash suele ejecutar:
/etc/profile(login shells)~/.bash_profileo~/.profile(login shells)~/.bashrc(shells interactivos)
Un enlentecimiento clásico es ~/.bash_profile que carga ~/.profile que a su vez carga ~/.bashrc y luego el terminal lanza un login shell interactivo que vuelve a cargar ~/.bashrc. Acabas de ejecutar tu código lento dos veces. Nadie lo nota hasta que el repo crece y git status se vuelve costoso.
Frameworks de prompt: elige uno y configúralo con intención
Starship, oh-my-zsh themes, powerlevel10k, ayudantes de prompt git personalizados—estas herramientas son geniales. También están muy contentas de ejecutar comandos externos repetidamente. En WSL, los comandos externos pueden cruzar fronteras y llamar a binarios de Windows, o golpear capas de sistema de archivos que no cachean como esperas.
Reglas que aplico en equipos:
- No llamadas de red durante el render del prompt. Esto incluye CLIs cloud, recuperadores de contexto de kube que llaman a APIs o comprobaciones de versión “útiles”.
- No git status recursivo en repos enormes por defecto. Prefiere comprobaciones rápidas o cachés; evita
git statusen el prompt si no puedes acotar su coste. - Diferir la inicialización pesada. Sistemas de completado, gestores de versiones de lenguajes y herramientas tipo direnv deberían cargarse perezosamente cuando sea posible.
PATH: mantenlo corto, determinista y con prioridad Linux
WSL puede importar entradas PATH de Windows. Suena útil hasta que tu shell tiene que comprobar 140 directorios para resolver python, y la mitad están en /mnt/c. Peor: a veces ejecutas git.exe cuando crees que estás ejecutando git de Linux. Ahora tus operaciones de repo rebotan a través del límite.
Guía práctica:
- Deshabilita la adición del PATH de Windows salvo que realmente la necesites.
- Si necesitas un par de herramientas de Windows, añádelas explícitamente y ponlas al final.
- Cuando depures “comandos lentos”, comprueba qué binario se usa con
type -aocommand -v.
Protege cualquier herramienta opcional con comprobaciones rápidas
Si tu init del shell ejecuta una herramienta que puede no existir, no la llames a ciegas y esperes el fallo. Compruébala primero:
command -v tool >/dev/nulles barato.- Llamar a
tool --versionno siempre es barato (algunos CLIs inicializan plugins y config).
También deja de hacer “comprobaciones de actualización automáticas” en el arranque del shell. Si realmente lo necesitas, prográmalo en segundo plano después de que aparezca el prompt.
Scripts init rotos y systemd: cuando “arrancar” no es arrancar
Históricamente WSL entrenó a la gente a tratar el arranque de la distro como “ejecuta un shell y espera lo mejor”. Luego llegó el soporte de systemd y todos empezaron a habilitar servicios. Eso está bien—hasta que no lo está.
Decide si realmente necesitas systemd
Si tu flujo necesita Docker dentro de WSL, demonios en segundo plano, timers o supervisión de servicios, systemd puede ser la solución correcta. Si mayormente ejecutas compiladores y herramientas CLI, systemd suele ser una sobrecarga opcional.
Incluso con systemd habilitado, debes ser selectivo. WSL no es un servidor al que mimar. Es un entorno de desarrollo que debería arrancar al instante y ser desechable.
Unidades comunes lentas en WSL
- systemd-networkd-wait-online.service: espera a que la red esté lista; a menudo inútil en WSL donde la red se levanta de forma distinta.
- snapd.service: puede añadir latencia notable al inicio; los snaps no siempre valen la pena en WSL.
- apt-daily.service y timers: las actualizaciones en segundo plano pueden disparar uso de disco justo cuando abres un shell.
- integración de resolved: puede interactuar mal con el resolv.conf generado por WSL según la configuración.
Enmascarar vs deshabilitar: elige el martillo correcto
Si una unidad es activamente dañina en el arranque, enmáscarala para que no pueda iniciarse accidentalmente. Si solo no quieres que esté habilitada por defecto, deshabilítala. Para el rendimiento de inicio de WSL, enmascarar “wait-online” es una ganancia común.
Y sí: a veces un “script init roto” es tu propio ~/.profile haciéndose pasar por un sistema init. Si tienes scripts que arrancan demonios, exportan entorno y tocan montajes, has construido un mini-init. Tiene todas las desventajas de systemd y ninguna de las diagnósticas.
Montajes e I/O de archivos: el impuesto de /mnt/c, opciones de automount y dónde está tu repo
La mayoría de las historias de horror de rendimiento en WSL involucran el sistema de archivos de Windows. No porque sea malo, sino porque es distinto. Las herramientas Linux asumen semánticas POSIX. Las semánticas de Windows no son POSIX. WSL las disimula. El papel no es gratis.
Pon el código caliente en el sistema de archivos Linux
Si te importan la rapidez del arranque y la respuesta interactiva, tus repos principales y salidas de build deberían vivir bajo /home dentro de la distro. Eso significa clonar en WSL, no editar una copia en C:\. Aun así puedes editar desde Windows usando herramientas conscientes de WSL.
Este cambio soluciona:
- git status lento, git diff lento
- instalaciones de dependencias lentas (caches de npm/pip/gradle)
- comportamiento extraño de permisos de archivos
- sobrecarga por escaneo de endpoints (a menudo menos dolorosa dentro del VHDX)
Ajusta automount, pero no lo copies a ciegas
/etc/wsl.conf puede controlar el comportamiento de automount. A la gente le encanta pegar una config de un blog y luego olvidarla. Seis meses después, algo se rompe y todo el mundo culpa a WSL.
Ideas clave:
- metadata habilita permisos POSIX en archivos de Windows. Útil, pero puede añadir sobrecoste y confusión si no lo necesitas.
- case importa para toolchains y repos con rutas sensibles a mayúsculas.
- appendWindowsPath puede inflar PATH y ralentizar la búsqueda de comandos.
Sé intencional sobre lo que accedes a través de la frontera
Acceder un par de archivos de configuración en /mnt/c está bien. Ejecutar una build que hace millones de operaciones de archivos allí es un fallo de rendimiento. Si tu framework de prompt escanea directorios en /mnt/c al inicio, es un shell lento por diseño.
Red y DNS: la fábrica silenciosa de timeouts
Los problemas de DNS son la causa más común de “WSL se cuelga 5–10 segundos a veces”. La razón es aburrida: muchas herramientas hacen resolución de nombres al inicio, y a menudo lo hacen de forma síncrona. Tu shell no parece lento; parece congelado.
De dónde viene el dolor de DNS en WSL:
- WSL genera automáticamente
/etc/resolv.confbasándose en la red de Windows. - Las VPN corporativas modifican DNS y routing de Windows sobre la marcha.
- Algunas organizaciones empujan servidores DNS que solo son accesibles cuando estás conectado a la VPN.
- Herramientas como git, plugins de kubectl, gestores de paquetes de lenguajes y scripts de prompt pueden desencadenar DNS.
Detectarlo rápidamente
Si getent hosts some-domain cuelga, has encontrado un culpable primario. Luego decides si arreglar DNS en la capa WSL (comportamiento de resolv.conf) o en la capa de dotfiles/herramientas (evitar que hagan DNS en el arranque).
Haz el comportamiento DNS determinista
Para muchos entornos corporativos, la configuración más estable es:
- Desactivar la generación automática de
/etc/resolv.conf. - Escribir un resolv.conf que funcione dentro y fuera de la VPN, o generarlo mediante un script ligado al estado de la VPN.
- Evitar confiar en “lo que Windows piense hoy”.
Pero ten cuidado: si fijas resolvers públicos en una org con acceso restringido, los dominios internos fallarán. El enfoque correcto depende del entorno. La ingeniería de fiabilidad es el arte de respetar la realidad, no de discutir con ella.
Realidad de almacenamiento/VHDX: qué significa que “el disco está lento” en WSL2
Cuando WSL2 se siente lento, la gente culpa a “la VM”. Cuando se siente realmente lento, culpan a “Windows”. En la práctica es más específico: es tu disco virtual, su ubicación y la tubería de almacenamiento del host.
Entiende las implicaciones del VHDX
Tu sistema de archivos Linux vive en un archivo VHDX. Los patrones de I/O aleatorio, la alta rotación de archivos pequeños y cargas de trabajo pesadas en metadata (hola, node_modules) son sensibles al rendimiento del almacenamiento del host. Si tu perfil de usuario de Windows vive en una unidad cifrada o redirigida, tu VHDX de WSL puede vivir en un sitio desagradable.
La protección de endpoints es una variable de rendimiento
El escaneo en tiempo real puede hacer que las operaciones con muchos archivos se arrastren. Si los scripts de inicio tocan muchos archivos (reconstrucciones de cache de completado, escaneos de prompt, gestores de versión de lenguajes), lo sentirás durante el “arranque de WSL” aunque el trabajo real sea el escaneo de archivos.
Trabaja con seguridad en lugar de pelear con ella. La práctica correcta y aburrida es establecer exclusiones sancionadas para la ubicación del VHDX de WSL o directorios específicos que generan alta rotación. Si tu organización no permite exclusiones, tu mejor palanca es minimizar la rotación de archivos en el inicio y mantener repos dentro del sistema de archivos Linux para evitar la sobrecarga de drvfs.
Broma #2: El antivirus es como un detector de humo que también critica tu técnica culinaria—útil, pero te arruinará la velada tranquila.
Tres mini-historias corporativas (lo que realmente se rompe en organizaciones)
Incidente causado por una suposición errónea: “DNS es local, así que es rápido”
Un equipo de plataforma desplegó un entorno WSL estandarizado para ingenieros: Ubuntu, zsh, un prompt llamativo, algunos scripts auxiliares y contexto de kubectl en el prompt porque “es útil”. Probó bien en la oficina. En casa, la mitad del equipo se quejó de que WSL “se cuelga aleatoriamente” al abrir un nuevo terminal.
La suposición errónea fue sutil: asumieron que el coste de la resolución DNS es despreciable. En la Wi‑Fi corporativa lo era. En redes domésticas más split‑tunnel VPN, las peticiones DNS para dominios internos expiraban antes de retroceder. El script del prompt no solo leía un archivo de configuración; invocaba kubectl, que llamó a un plugin que intentó resolver un hostname interno. Cada nuevo shell pagaba el coste del timeout.
La depuración fue trabajo clásico de SRE: reproducir con un prompt limpio y luego añadir componentes. getent hosts colgó exactamente cuando el prompt colgaba. Lo solucionaron de dos maneras: (1) eliminaron las llamadas a kubectl del render del prompt; (2) hicieron el DNS determinista desactivando la generación automática de resolv.conf y gestionando resolvers según el estado de la VPN.
La lección quedó: las rutas de inicio deben estar libres de dependencias de red. Si necesitas contexto dinámico, calcúlalo de forma asíncrona tras aparecer el prompt y cachea con TTL.
Optimización que resultó contraproducente: “Pongamos los repos en C: para fácil acceso”
Un grupo de productividad de desarrollo quiso una regla simple: mantener el código en C:\src para que herramientas de Windows y WSL lo vean. A todos les encantó la conveniencia. Funcionó bien para servicios pequeños.
Luego llegó un monorepo con builds de TypeScript pesados y árboles de dependencias masivos. De repente los mismos portátiles que eran “suficientemente rápidos” empezaron a tardar minutos en instalaciones, y los shells tardaban varios segundos en mostrarse porque los prompts y completadores rastreaban el repo para inferir contexto.
Intentaron optimizar opciones de montaje drvfs, desactivaron metadata, añadieron noatime y ajustaron todo lo posible. Ganancias marginales. La discrepancia fundamental siguió ahí: toolchains Linux haciendo millones de operaciones de archivo sobre un puente de sistema de archivos Windows.
La solución real fue aburrida y algo inconveniente: mover el repo a ~/src dentro del sistema de archivos Linux y usar editores conscientes de WSL. Mantuvieron un conjunto pequeño de archivos visibles por Windows en /mnt/c cuando fue necesario, pero la ruta caliente se movió a ext4 dentro del VHDX. Los tiempos de inicio y build volvieron a niveles razonables.
Práctica aburrida pero correcta que salvó el día: “Los scripts de perfil son código de producción”
Una empresa regulada tenía muchos ingenieros en WSL y trataban los dotfiles como un proyecto personal de arte. Luego llegó una actualización de hardening: nuevas configuraciones de proxy, bundles de certificados actualizados y un cambio en el ruteo DNS interno. A la mañana siguiente, una parte de la organización no pudo abrir terminals WSL rápidamente. Algunos no pudieron abrirlos en absoluto.
Un equipo no entró en pánico porque tenían una práctica poco sexy: mantenían la lógica de init del shell mínima, versionada y revisada. Sus dotfiles estaban divididos en “crítico para el arranque” y “agradable de tener”, con timeouts alrededor de cualquier cosa que pudiera bloquear. También tenían un procedimiento de emergencia documentado: iniciar con --noprofile --norc para recuperar un shell roto.
Mientras otros equipos reinstalaban distros y culpaban a actualizaciones de Windows, este equipo tenía un terminal funcional, podía ejecutar diagnósticos y ayudar a otros. La solución para la organización fue al final un ajuste de DNS/proxy, pero los equipos con dotfiles disciplinados perdieron menos tiempo y generaron datos de incidente más limpios.
La moraleja: lo que se ejecuta al inicio es parte de tu plataforma. Trátalo con el mismo respeto que das a los scripts init de producción—porque es lo que necesitas cuando todo lo demás está en llamas.
Errores comunes: síntoma → causa raíz → solución
1) Síntoma: El terminal se abre, queda en blanco 5–15 segundos y luego aparece el prompt
Causa raíz: Un comando bloqueante en la inicialización del shell (a menudo relacionado con DNS) o un framework de prompt que ejecuta subprocessos lentos.
Solución: Inicia un shell limpio (bash --noprofile --norc), confirma que es instantáneo y luego traza tus archivos init (xtrace de bash o zprof de zsh). Elimina llamadas de red del render del prompt. Añade timeouts a ayudantes opcionales.
2) Síntoma: Solo lento con VPN activada (o solo lento sin VPN)
Causa raíz: Resolvers en /etc/resolv.conf solo alcanzables en un estado; las búsquedas expiran.
Solución: Desactiva resolv.conf autogenerado y gestiona resolvers intencionalmente para tu entorno, o arregla la configuración DNS/VPN en Windows para que WSL herede comportamiento correcto.
3) Síntoma: cd a un repo está bien, pero cada nuevo prompt tarda 1–2 segundos
Causa raíz: El prompt ejecuta git status o equivalente en cada render; el repo es grande o está en drvfs.
Solución: Simplifica el prompt o habilita caching; evita escanear en cada prompt; mueve el repo al sistema de archivos Linux.
4) Síntoma: Inicio de WSL lento tras habilitar systemd
Causa raíz: Unidades systemd lentas (wait-online, snapd, timers de apt) arrastrando el arranque de userspace.
Solución: Usa systemd-analyze blame y enmascara/deshabilita unidades innecesarias. Si no necesitas systemd, desactívalo.
5) Síntoma: Los comandos se sienten “lentos”, incluso comandos simples como python o node
Causa raíz: PATH enorme; resolución de comandos revisa muchas rutas de Windows; o estás invocando binarios de Windows sin querer.
Solución: Reduce el PATH, deshabilita la adición del PATH de Windows, revisa con type -a qué binarios se usan, corrige el orden de PATH.
6) Síntoma: Solo lento en una distro; otras distros son rápidas
Causa raíz: Dotfiles específicos de la distro, unidades systemd o caches corruptos (caches de completado, shims de gestores de versiones).
Solución: Compara systemd blame, compara dotfiles, renombra temporalmente ~/.bashrc/~/.zshrc, reconstruye caches.
7) Síntoma: El tiempo de inicio empeoró después de “ajustar” /etc/wsl.conf
Causa raíz: Ajustes copiados a ciegas de automount/interop causando trabajo extra o retrocesos de compatibilidad.
Solución: Vuelve a una config mínima y aplica cambios uno por uno midiendo. Conserva los cambios que realmente mejoren el resultado; borra el resto.
8) Síntoma: Pausas aleatorias durante el inicio del shell, más comunes en repos grandes
Causa raíz: Escaneo por protección de endpoints de operaciones con muchos archivos desencadenadas por scripts init (reconstrucciones de caches, escaneos de prompt).
Solución: Reduce la rotación de archivos en el arranque; considera exclusiones sancionadas; mantiene repos en el sistema de archivos Linux; evita reconstruir caches en cada lanzamiento.
Listas de verificación / plan paso a paso
Paso a paso: deja el inicio de WSL por debajo de 1 segundo (o lo más cerca que permita la realidad)
- Mide la línea base sin init interactivo. Usa la Task 1. Si eso es lento, no toques dotfiles aún.
- Mide el tiempo del shell interactivo. Usa la Task 2. Si lo interactivo es la diferencia, perfila dotfiles y mata lo innecesario en prompt/red.
- Abre un shell limpio. Usa la Task 14 (
--noprofile --norc) para demostrar que el entorno puede ser rápido. - Perfiliza tu init del shell. xtrace de bash (Task 5) o zprof de zsh (Task 6).
- Elimina dependencias de red del inicio. Nada de DNS, CLIs cloud ni llamadas a kube en el render del prompt.
- Mueve los repos calientes fuera de /mnt/c. Si compilas en drvfs, estás pagando extra por diseño.
- Poda el PATH. Reduce entradas, deshabilita importación de PATH de Windows si puedes.
- Revisa systemd solo si es relevante. Si PID 1 es systemd, ejecuta
systemd-analyze blamey enmascara unidades lentas que no necesites. - Valida la velocidad de DNS.
getent hostsdebe ser instantáneo. Si no, arregla la estrategia de resolv.conf. - Vuelve a medir tras cada cambio. No apiles tweaks esperando suerte; mide, conserva, repite.
Lista operativa: mantenerlo rápido en el tiempo
- Los dotfiles son código revisado, no folklore.
- El prompt no debe ejecutar operaciones no acotadas (red, escaneos profundos de sistema de archivos).
- Cualquier comando auxiliar opcional tiene timeout o carga perezosa.
- Los repos viven por defecto en el sistema de archivos Linux; drvfs es para compartir ocasional, no builds pesados.
- Al habilitar systemd, audita y minimiza las unidades habilitadas.
- En redes corporativas, decide una estrategia DNS explícita; no confíes en “auto”.
Preguntas frecuentes
1) ¿Por qué WSL es rápido a veces y dolorosamente lento otras?
Porque muchas veces estás esperando timeouts: DNS, disponibilidad de red o un comando en tu init del shell que bloquea en ciertas condiciones (estado de la VPN, proxy, dominio inaccesible).
2) ¿Cómo sé si el problema es WSL en sí o mi configuración de shell?
Ejecuta WSL con un comando trivial (Task 1). Si eso es rápido pero un shell interactivo es lento (Task 2), tus dotfiles/prompt/plugins son el problema.
3) ¿Es mala idea habilitar systemd en WSL?
No inherentemente. Es correcto si necesitas servicios gestionados. También es fuente de latencia si habilitas unidades que esperan por red o ejecutan mantenimiento. Mide con systemd-analyze y poda.
4) ¿Por qué trabajar en /mnt/c hace que todo sea más lento?
Porque drvfs hace de puente entre dos modelos de sistema de archivos. Las herramientas Linux hacen muchas operaciones de metadata que son más costosas a través de ese límite. Sitúa builds pesados en ~ dentro de la distro.
5) ¿Cuál es el arreglo de dotfiles más rápido que suele ayudar?
Deja de ejecutar comandos costosos en el prompt. Elimina git status de PS1 o configúralo con caching. Si debes mostrar info de git, mantenla ligera y acotada.
6) ¿Cómo sé si el DNS es el culpable?
Si getent hosts some-domain cuelga o tarda segundos, el DNS está involucrado. También revisa si la lentitud correlaciona con VPN activada/desactivada.
7) ¿Debo deshabilitar la integración del PATH de Windows?
Si tu PATH es enorme o ejecutas binarios de Windows por accidente, sí. Desactívala y añade rutas Windows específicas solo cuando sea necesario, preferiblemente al final.
8) Uso VS Code con WSL. ¿Cambia algo de esto?
No, se vuelve más importante. VS Code spawnará shells y ejecutará helpers. Un init de shell lento hace que el editor se sienta lento y frágil. Mantén el inicio mínimo y determinista.
9) Arreglé mi prompt, pero WSL todavía tarda ~5 segundos en abrir la primera vez cada día
Probablemente sea el arranque/reanudación de la VM más systemd (si está habilitado) y calentamiento de almacenamiento. Mide con la Task 1 y herramientas de systemd. Si la línea base es lenta, revisa unidades systemd, montajes y almacenamiento del host/protecciones.
10) ¿Cuál es la “salida de emergencia” más segura cuando mi shell está roto y no arranca?
Inicia un shell limpio: bash --noprofile --norc o zsh -f, luego arregla o renombra temporalmente tus archivos rc.
Conclusión: próximos pasos prácticos
La velocidad de inicio de WSL no es un misterio. Es una cadena de suministro: estado de la VM, servicios del sistema, montajes, red y luego tus scripts de shell. La dependencia más lenta gana. Si quieres que sea rápido, deja de adivinar y empieza a aislar.
Haz esto a continuación, en orden:
- Mide la línea base sin inicialización interactiva del shell.
- Mide el inicio del shell interactivo; si ese es el delta, perfila dotfiles y elimina cosas de prompt/red.
- Si la línea base es lenta, revisa el tiempo de arranque de systemd y unidades lentas; luego montajes y DNS.
- Mueve repos pesados al sistema de archivos Linux y usa /mnt/c solo para compartir ligero.
- Poda el PATH y deja de importar todo el ecosistema Windows a menos que realmente lo necesites.
Cuando lo haces bien, WSL se siente como lo que siempre debió ser: un espacio de trabajo Linux rápido y desechable que arranca en el tiempo que te lleva pensar el siguiente comando.