Skip to content

[WSL2] input delay #96

Open
Open

Description

@jmeder0s

ble version: 0.4.0-devel3+0506df2
Bash version: 5.0.17(1)-release, x86_64-pc-linux-gnu

Hi. This project is great.

Basically I'm having performance issues, there is a perceptible delay between my key strokes and the letter appearing on the screen. Is this something that should be expected ? I'm currently under Ubuntu 20.04 on WSL2. I'm coming from zsh and I would really love to use bash, but syntax-hightlight and autocomplete features like the ones you provide are a must have. However performance issues are a deal breaker.

I see there are other open issues related to performance, but I saw they were more specifically related to autocomplete or some other features. Please let me know if I should close this and continue the discussion in those open issues.


Summary

(Edited by @akinomyoga)

Here I summarize the discussions made here. There can be various causes that slows down the response in WSL2. Depending on the actual bottleneck in your environment, maybe you can take the following workarounds.

Remove slow Windows filesystems on /mnt from PATH

It is known that the Windows filesystems mounted on /mnt is very slow microsoft/WSL#4197. When PATH contains directories under /mnt, the completion becomes slow. One solution is to remove /mnt/* from the environment variable PATH:

From #96 (comment)

If you are fine with removing all the Windows paths from PATH, you can just put the following command in your blerc:

ble/path#remove-glob PATH '/mnt/*'

Another solution is to configure wsl so that it doesn't include Windows paths in the environment variable on the startup of the shell:

From #96 (comment)

You can also create a file called /etc/wsl.conf and put this:

[interop]
appendWindowsPath = false

More info can be found in WSL's docs here.

Integration with bash-preexec to remove the overhead of DEBUG trap

This has been solved by introducing a proper support for the integration of ble.sh and bash-preexec. When bash-preexec is loaded, ble.sh automatically detects it and properly communicate with the loaded bash-preexec. Please just update ble.sh to the latest master. See also #96 (comment).

Disable auto-complete

If the above settings does not work, maybe you can turn off auto-complete or set a delay for auto-complete.

From #96 (comment)

$ bleopt complete_auto_complete=

[...] you can configure bleopt complete_auto_delay (the delay of auto-complete) so as to reduce the frequency of auto-complete, e.g.,

# blerc
bleopt complete_auto_delay=300

Activity

  1. akinomyoga commented on Apr 5, 2021

    @akinomyoga
    Owner

    Thank you. OK, I have set up WSL2 with Ubuntu 20.04 LTS and could reproduce the small delay even after disabling auto-complete (although the delay is almost unnoticeable in my environment). It seems that the plain Bash doesn't have the delay in WSL2. I don't see the delay either in Cygwin or genuine Linux systems. This must be related to some characteristics of WSL2.

    I'll take a look later, but I'm busy recently so would appreciate it if you could narrow down the bottleneck. Thank you!

  2. changed the title [-]Performance issues[/-] [+][WSL2] input delay[/+] on Apr 5, 2021
  3. jmeder0s commented on Apr 5, 2021

    @jmeder0s
    Author

    I kind of narrowed it down. It turns out the delay only happens (or at at least is most noticeable) when I type the very first character after starting my terminal session, subsequent keystrokes appear to behave normal. In addition this only happens when I override some settings in the blerc file. Particularly I'm changing the syntax highlight colors, so my blerc file only contains a bunch of calls to ble-color-setface. Please let me know if this makes sense.

  4. akinomyoga commented on Apr 5, 2021

    @akinomyoga
    Owner

    It turns out the delay only happens (or at at least is most noticeable) when I type the very first character after starting my terminal session,

    I'm not sure, but this is possibly related to auto-complete. Is the delay still present after disabling auto-complete by the following command?

    $ bleopt complete_auto_complete=

    If it is the delay by auto-complete, you can configure bleopt complete_auto_delay (the delay of auto-complete) so as to reduce the frequency of auto-complete, e.g.,

    # blerc
    bleopt complete_auto_delay=300

    In addition this only happens when I override some settings in the blerc file. Particularly I'm changing the syntax highlight colors, so my blerc file only contains a bunch of calls to ble-color-setface.

    Ah, OK. ble.sh defers the initialization of faces until it is first required. It seems the deferred settings of faces takes some time in your environment. I'll check it later.

  5. jmeder0s commented on Apr 5, 2021

    @jmeder0s
    Author

    Oh I see. If ble.sh defers the initialization of faces until it is first required, then that would explain the problem. There are a lot of calls to ble-color-setface in my blerc file, so if they are all run once I type for the first time, we should expect the delay. Is there any way to tweak tis behaviour, maybe some kind of flag or config to make ble.sh evaluate calls to ble-color-setface when blerc file is sourced ????

  6. rashil2000 commented on Aug 28, 2021

    @rashil2000

    Hi @akinomyoga!

    I was about to open an issue related to performance in WSL2, but I saw that this is already open. I'm facing issues too. I'll try to elaborate.

    While auto-complete and auto-suggestions work fine, there's a very perceptible lag on input (delay between typing and characters appearing). I'm on a laptop, so power consumption might be interfering with how snappy the input is. Therefore I've tried to record on both battery-mode and plugged-in mode.

    battery
    wsl_slow

    plugged-in
    wsl_fast

    Both these have very perceptible lag, but the typing is slightly more responsive in plugged-in mode. I have only 3 lines in my blerc

    bleopt history_share=1                                                                    
    ble-bind -f up 'history-search-backward hide-status:immediate-accept:point=end'           
    ble-bind -f down 'history-search-forward hide-status:immediate-accept:point=end'
    

    Note that this lag doesn't appear in WSL2 at all (whether on battery or plugged-in) in zsh, pwsh or vanilla bash.

  7. akinomyoga commented on Aug 29, 2021

    @akinomyoga
    Owner

    @rashil2000 Thank you for the information!

    First, I need to note that ble.sh is different from the normal line editors of the shells which are implemented in the compiler languages such as C and C#, so the performance difference is inevitable. In particular, when the computer is slow, there might be nothing that we can do. Nevertheless, if you could point out the bottleneck of ble.sh, I'm not reluctant to improve it, but generally, performance issues wouldn't be completely resolved in slow computers as far as ble.sh is implemented in Bash script.

    In your case, I'm not sure if there is any bottleneck that significantly worsens the performance, or just the entire processing takes a long time in the battery mode, but I might do something in the former case. I implemented ble.sh so that the auto-complete doesn't interfere with the user input processing, so there are two possibilities: 1) the bottleneck lies outside of auto-complete, or 2) the user-input detection becomes slow in the battery mode. I have related questions:

    • Q1: What are the results of the following command in the battery mode and the plugged-in mode?
    $ ble-measure -a 50 'ble/util/msleep 10
    • Q2: When you turn off auto-complete and other background processing, does the response in the battery mode change?
    $ bleopt complete_auto_complete=
    $ bleopt complete_menu_filter=
    $ bleopt complete_auto_menu=
    • Q3: With the following settings In addition to the above settings, does the response in the battery mode change?
    $ bleopt highlight_filename=
    $ bleopt highlight_variable=
  8. rashil2000 commented on Aug 29, 2021

    @rashil2000

    ...performance issues wouldn't be completely resolved in slow computers as far as ble.sh is implemented in Bash script.

    I have a gaming laptop [Specs: i7-8750H, 6 cores (12 threads), 16GB RAM, GTX 1060 GB graphics]. I don't think the system is a slow one. In any case, to completely eliminate any possibility of doubt, I conducted an elaborate experiment. I created 2 virtual machines, both running Ubuntu:

    • one running inside VMware on my own laptop (2 cores, 4GB RAM alloted)
    • one running on Azure (1 core, 1GB RAM alloted)

    In both these VMs, ble.sh runs buttery smooth - no input lag/latency. Note that they're not particularly heavily-specced VMs. This leads me to believe that the performance is certainly not a ble.sh issue. It almost exclusively occurs on WSL (and sometimes MSYS2, or even Termux (Android)). However, the amazing features of ble.sh have spoilt me, and I would like to use it everywhere possible (which includes WSL2, albeit with some workarounds, if possible).

    • Q1: What are the results of the following command in the battery mode and the plugged-in mode?
    10435.150 usec/eval: ble/util/msleep 10 (x10) # battery
    10111.150 usec/eval: ble/util/msleep 10 (x10) # plugged-in
    
    • Q2: When you turn off auto-complete and other background processing, does the response in the battery mode change?

    No effect

    • Q3: With the following settings In addition to the above settings, does the response in the battery mode change?

    Very slight improvement

  9. akinomyoga commented on Aug 29, 2021

    @akinomyoga
    Owner

    Thanks for the information and answers. From these answers, it seems that the delay is caused by somewhere not related to the auto-complete or syntax-highlighting based on the filenames. Another possibility that causes the delay is the access to /tmp which is a RAM disk on many Linux distributions but is not in WSL2 by default.

    • Q4: What are the result of the following command in the battery and plugged-in modes respectively.
    $ ble-measure -a 5 'ble/util/assign a "echo $((b++))"'

    I have also tested with WSL2 in my environment. It seems that I also have a very small delay with WSL2 (though I'm not sure if this is the same issue as the one that you observe). I tried to figure out the cause of the small delay, but I found some strange behavior: While I observe the delay when I open the WLS2 through the "Ubuntu 20.04 LTS" icon in the Windows start menu, it seems that I don't have the delay if I connect to the WSL2 through ssh from Cygwin.

    The terminal that opens up by the start menu icon seems to be actually the command prompt (at least the property window which can be opened from the shortcut menu of the window icon is that of the command prompt). Maybe the delay is related to the terminal or some interface of the connection between the WSL2 subsystem and the Windows subsystem.

    • Q5: Which terminal do you use for WSL2? Or, how do you connect to WSL2?
    • Q6: If you connect to the WSL2 using ssh, do you experience the same delay in the battery mode?
  10. rashil2000 commented on Aug 29, 2021

    @rashil2000
    • Q4: What are the result of the following command in the battery and plugged-in modes respectively.
    1314.331 usec/eval: ble/util/assign a "echo $((b++))" (x100) # battery
     827.690 usec/eval: ble/util/assign a "echo $((b++))" (x100) # plugged-in
    
    • Q5: Which terminal do you use for WSL2? Or, how do you connect to WSL2?

    I start it using the wsl command. This is the same command that the Start menu shortcut uses. It is the recommended way of starting/stopping/managing WSL distributions.

    • Q6: If you connect to the WSL2 using ssh, do you experience the same delay in the battery mode?

    I don't have Cygwin set up on my machine, but I could install openssh on MSYS2 (pacman -S openssh). But since Windows 10 already comes with the OpenSSH client pre-installed (at C:\Windows\System32\OpenSSH\ssh.exe), I used that. Surprisingly, I experience zero input lag as you described, even on battery mode. Ble.sh runs buttery-smooth.

    It's definitely an issue with the wsl command. However, there are a few points to note:

    1. WSL2 does not support systemd services. As such, the ssh daemon will have to be started manually each time a distro is started.
    2. WSL2's network configuration is NAT'd, which means the IP address will change every time WSL2 is restarted. There are ways around it, but they're not pretty. Would love to hear what method you use to get around this.
    3. When using the wsl command, Windows sets up some useful variables inside the WSL2 shell, like these:
    WSL_DISTRO_NAME=arch-linux
    WSL_INTEROP=/run/WSL/4145_interop
    

    They are particularly useful for detecting if you're on WSL for generic linux apps/scripts. When using ssh, they don't get set.

  11. rashil2000 commented on Aug 29, 2021

    @rashil2000

    Needless to say, the disparity between wsl and ssh is huge (although ble.sh is the first application where I've observed this).

    Do you think I should report this in the official WSL repo (citing this issue as source)?

  12. akinomyoga commented on Aug 31, 2021

    @akinomyoga
    Owner

    OK, thank you for your information. As you have experienced the zero delay with ssh, the delay that I observe in my system seems to be the same issue with yours. I'm not sure if we can do anything from the ble.sh side, but as readline and Zsh Line Editor don't share the issue, maybe some specific operation that ble.sh uses is slow with the wsl connection. I will later test it in my environment.

    Do you think I should report this in the official WSL repo (citing this issue as source)?

    Currently, the issue is not so clear, and I think they are so busy that they don't have time to investigate such an obscure issue that "some specific application is slow in some specific situation". I'd think the issue would be just ignored at best (unless there are reports from many different people on the same issue with ble.sh which is not likely).

    We may report it only after we have identified what specific operation causes the delay of wsl.

  13. rashil2000 commented on Aug 31, 2021

    @rashil2000

    We may report it only after we have identified what specific operation causes the delay of wsl.

    Okay, I understand that.

    Thank you for your help so far and the ssh tip!

  14. rashil2000 commented on Sep 3, 2021

    @rashil2000

    Okay, I somehow missed this, but I changed my default shell in WSL2 to zsh, and I can observe the same input delay in zsh, when launched through the wsl command. The delay is absent through ssh.

    Though I could observe the difference only in battery mode, there's definitely something wrong with the wsl binary.

  15. 14 remaining items

  16. SuperSandro2000 commented on Jan 23, 2022

    @SuperSandro2000

    I meant by one-by-one that you might be able to identify which of these plugins in PROMPT_COMMAND causes the dominant delay.

    I think most of the delay came from history -a; history -c; history -r.

    Then, we actually don't need to modify the codes that use bash-preexec like wezterm/wezterm#1572 and ellie/atuin#267.

    wezterm needed to be modified anyway since it always loads bash-preexec and vendors it.

  17. akinomyoga commented on Jan 23, 2022

    @akinomyoga
    Owner

    wezterm needed to be modified anyway since it always loads bash-preexec and vendors it.

    Hmm, didn't it work without the modification? In the above integration, I intended to make ble.sh work with existing bash-preexec.sh without modifications; the above integration doesn't include the code of bash-preexec but communicates with the existing code when it is loaded. If the integration doesn't work without wez/wezterm#1572, it means that bash-preexec bundled with wezterm is actually a different implementation from rcaloras/bash-preexec?

    I have now checked bash-preexec embedded in wezterm. I haven't really checked by running wezterm, but I think it will properly work because the following conditions are met:


    Edit: I now tried wezterm and wezterm.sh of wezterm/wezterm@3cc26cc (before wez/wezterm#1572) and wezterm/wezterm@78ea214 (after wez/wezterm#1572). Both bash-preexec works fine though both wezterm integration seems to have some problems.

    It is unrelated to the wezterm shell-integration, but I faced another problem with wezterm and ble.sh. Somehow ble.sh seems to fail to reset DECSTBM in wezterm and the scrolling region is restricted in the first two lines with a certain condition. This happens after bleopt prompt_status_line is cleared. Note that the problem does not arise in other terminals.

  18. SuperSandro2000 commented on Jan 23, 2022

    @SuperSandro2000

    Could you test the latest version of ble.sh?

    So far it seems to work but I think it would be easier if I keep the patches for atuin and wezterm to remove a whole bunch of fragile bash code. I could imagine that the removal functions break which would be a bit of a pain to debug.

    Hmm, didn't it work without the modification?

    I was referring that the patch is still required when I want to use the hooks without the preexec compatibility stuff.

    It is unrelated to the wezterm shell-integration, but I faced another problem with wezterm and ble.sh. Somehow ble.sh seems to fail to reset DECSTBM in wezterm and the scrolling region is restricted in the first two lines with a certain condition. This happens after bleopt prompt_status_line is cleared. Note that the problem does not arise in other terminals.

    I must admit I wasn't using wezterm terminal in the last weeks but only the shell functions. I intent to use it again in the future especially because Windows Terminal breaks tmux panes and splits.

  19. akinomyoga commented on Jan 24, 2022

    @akinomyoga
    Owner

    Could you test the latest version of ble.sh?

    So far it seems to work but I think it would be easier if I keep the patches for atuin and wezterm to remove a whole bunch of fragile bash code. I could imagine that the removal functions break which would be a bit of a pain to debug.

    Ah, I see your point. Then let's keep the special treatment in wezterm.sh. By the way, the special treatment in wezterm.sh only works when it is loaded after ble.sh. If wezterm.sh is loaded first and then ble.sh is loaded, the integration by ble.sh will be turned on.

    Actually, what I have implemented in the integration is the switching between the DEBUG trap and the blehook in either direction. This is needed for bash-preexec to work even after ble.sh is detached by ble-detach (which is currently undocumented in the manual, but only found in ble --help). When ble.sh detaches, ble.sh lets bash-preexec reinstall the DEBUG trap. But, considering that it is rare to detach from ble.sh, maybe it is fair to completely remove bash-preexec implementations.

    It is unrelated to the wezterm shell-integration, but I faced another problem with wezterm and ble.sh. Somehow ble.sh seems to fail to reset DECSTBM in wezterm and the scrolling region is restricted in the first two lines with a certain condition. This happens after bleopt prompt_status_line is cleared. Note that the problem does not arise in other terminals.

    I must admit I wasn't using wezterm terminal in the last weeks but only the shell functions. I intent to use it again in the future especially because Windows Terminal breaks tmux panes and splits.

    I have fixed the issue of DECSTBM in 4b1601d.

    Digression: Some detailed story of DECSTBM

    This above problem is related to the supported terminal sequence for clearing DECSTBM. The DECSTBM escape sequence has the form \e[...r. However, the escape sequence terminated by r is designated as the sequences for private use by ANSI X3.64 and ECMA-48 so heavily conflicting with other escape sequences defined by terminal vendors and terminal emulators. Currently, most other escape sequences are not used anymore, but there is one escape sequence conflicting with DECSTBM, i.e., SCORC \e[r which is used by consoles and terminal emulators in SCO OpenServer. Some terminals distinguish these two different escape sequences by the number of arguments, so that \e[;r is clearing DECSTBM and \e[r is performing SCORC. Some other terminals only support DECSTBM and thus accept both forms \e[r and \e[;r as clearing DECSTBM. kitty and wezterm somehow only accepts \e[r, which means that they only support DECSTBM and, in addition, they fail to ignore extra CSI parameters. So far I have recognized kitty for this behavior, but now I realized that wezterm also behaves in a similar way. I have newly implemented the test for the terminal to check which form of the escape sequence the terminal supports for clearing DECSTBM.


    I recognize another layout issue with wezterm.sh shell-integration (even without bash-preexec). Some extra empty lines are inserted between the prompts. I'll later work on the problem.

    *Edit: This was easier than I though. I fixed it in e199bee. In order to use it with wezterm.sh shell-integration, one needs to put the following setting:

    # blerc
    bleopt prompt_command_changes_layout=1
  20. SuperSandro2000 commented on Jan 24, 2022

    @SuperSandro2000

    When ble.sh detaches, ble.sh lets bash-preexec reinstall the DEBUG trap. But, considering that it is rare to detach from ble.sh

    I need to do it from time to time because nix-shell is still not working like it should. I will write you another comment into the other thread.

  21. akinomyoga commented on Jan 24, 2022

    @akinomyoga
    Owner

    OK, thank you for the information! Please feel free to open a thread.

  22. refparo commented on May 13, 2024

    @refparo

    Hello. On the problem with PATH, is it possible for blesh to use a different PATH to calculate the completions? I still want explorer.exe and other programs from Windows to be accessible from WSL.

  23. akinomyoga commented on Sep 22, 2024

    @akinomyoga
    Owner

    @refparo @mgastonportillo @heathprovost I've been believing that the issue of the slow filesystem should be fixed in the upstream WSL2 system, but it doesn't seem to be fixed there. I decided to accept a workaround contributed by @musou1500. Now, in the master branch, when the completion is performed in WSL2 with PATH containing /mnt/*, ble.sh generates the command names in a background process so that the completion doesn't block the foreground shell. This should significantly improve the situation of the slow auto-complete in WSL2 (though there might still be places affected by the slow filesystem apart from the completion).

  24. refparo commented on Sep 23, 2024

    @refparo

    Thank you a lot! But actually, I believe that even on native Linux, if the PATH contains a FUSE-based filesystem, there would likely be a performance issue as well. It would be even better if a customizable option is added.

  25. cyberalt1 commented on May 7, 2025

    @cyberalt1

    The biggest issue with ble.sh so far. The lag is extremely slow compared to native bash, night and day difference. 100% of development work should be focused on resolving this issue because otherwise ble.sh is unusable.

  26. akinomyoga commented on May 7, 2025

    @akinomyoga
    Owner

    The system dependence is large. Honestly, I've never experienced a performance issue with Linux (except for unusual cases with e.g. a directory with several tens of thousands of files).

    The biggest issue with ble.sh so far. The lag is extremely slow compared to native bash, night and day difference.

    Of course, the performance of a line editor written in Bash cannot be comparable to that of Readline written in C. It is impossible. However, it's not important to make it comparable to the C implementation. Here, what is important is that the absolute delay of ble.sh (instead of the delay relative to the C implementation) would be a reasonable one for daily use. Currently, it seems to be fine in most systems.

    100% of development work should be focused on resolving this issue because otherwise ble.sh is unusable.

    It is already the primary concern in the development---Well, I should say the primary is portability, which is the reason that ble.sh is written in Bash instead of C. Then, the performance is secondary.---I've already put a lot of effort into the performance. I'm pretty sure that the current performance is almost the upper limit for the general case. There may still be room to improve the performance for specific cases by identifying the cause, but it is hard to identify the cause for delays that cannot be reproduced in my environment.

  27. akinomyoga commented on May 7, 2025

    @akinomyoga
    Owner

    If you want to solve the performance issue with your environment, please consult the page Performance · akinomyoga/ble.sh Wiki, if you haven't yet checked it.

  28. tjallingt commented on Oct 1, 2025

    @tjallingt

    I'm using 1password with WSL which relies on ssh.exe see https://developer.1password.com/docs/ssh/integrations/wsl/
    Unfortunately ssh.exe cannot be executed anymore when using the ble/path#remove-glob PATH '/mnt/*' configuration.

    Without that configuration ble.sh is really slow on WSL, even with that configuration it introduces some input lag.

  29. SuperSandro2000 commented on Oct 1, 2025

    @SuperSandro2000

    I had a similar issue on NixOS WSL and fixed it by adding a a wrapper script in another place in PATH and exceed there the absolute path to ssh.exe.

    #!/usr/bin/env bash
    exec /mnt/..../ssh.exe "$@" 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions