Skip to content

Performance#

Tuning#

Use M-x lsp-doctor to validate if your lsp-mode is properly configured. In the section below, you could find description for each of the checks:

When configured properly lsp-mode's performance is on par with mainstream LSP clients (e. g. VScode, Theia, etc). Here are steps to achieve optimal results.

JSON native serialization/deserialization#

  • Use Emacs 27+ with native json support. (Note: this requires that you have libjansson installed, and that emacs was compiled with `–with-json` passed to `./configure`.) You can check your installation for native json support by running M-: (functionp 'json-serialize) RET. Benchmarks show that Emacs 27 is ~15 times faster than Emacs when using Elisp json parser implementation.

Adjust gc-cons-threshold#

The default setting is too low for lsp-mode's needs due to the fact that client/server communication generates a lot of memory/garbage. You have two options:

- Set it to big number(100mb) like most of the popular starter kits like Spacemacs/Doom/Prelude, etc do:

```elisp
(setq gc-cons-threshold 100000000)
```

- Follow the method recommended by Gnu Emacs Maintainer Eli Zaretskii: "My suggestion is to repeatedly multiply gc-cons-threshold by 2 until you stop seeing significant improvements in responsiveness, and in any case not to increase by a factor larger than 100 or somesuch. If even a 100-fold increase doesn't help, there's some deeper problem with the Lisp code which produces so much garbage, or maybe GC is not the reason for slowdown." Source: <https://www.reddit.com/r/emacs/comments/brc05y/is_lspmode_too_slow_to_use_for_anyone_else/eofulix/>

Increase the amount of data which Emacs reads from the process#

Again the emacs default is too low 4k considering that the some of the language server responses are in 800k - 3M range.

(setq read-process-output-max (* 1024 1024)) ;; 1mb

Use plists for deserialization.#

lsp-mode can be compiled in 2 modes plist and hash-table based lsp-use-plists flag. plists provide better performance in deserialization and also put less presure than hash-tables. To switch to plist you have to perform 2 steps:

  1. Configure the following env variable. Make sure that Emacs can see that variable (best way to do that is to start Emacs from the shell, not from the icon).
    export LSP_USE_PLISTS=true
    
  2. Delete lsp-mode related packages.
  3. Make sure that lsp-use-plists is non-nil.
  4. Restart Emacs and install again lsp-mode related packages.

NB: make sure that lsp-use-plists does not change after you compile the file. Furthermore, if you are using something like exec-path-from-shell you'll need to make sure to add LSP_USE_PLISTS to exec-path-from-shell-variables.

Optional steps#

  • Optional: Disable lsp-ui. Normally, lsp-ui is very fast but in some systems (especially when using Windows) lsp-ui overlays and popups might slow down emacs.
  • Optional: fine-tune lsp-idle-delay. This variable determines how often lsp-mode will refresh the highlights, lenses, links, etc while you type.
(setq lsp-idle-delay 0.500)

Using Emacs 28.1 or later#

Emacs 28.1 includes "native compilation" of elisp code (changelog). For optimal performance, using Emacs 28.1 or later (with native compilation enabled) is recommended.

Ignore watch folders/files#

If the server supports watch files, by default lsp-mode tries to watch all files and folders of the project ignoring the regexp from lsp-file-watch-ignored. If you don't want some file or folder to be watched for performance reasons, you can add a regexp to that variable excluding the file or folder.

Check the file watchers section for details.

Check if logging is switched off.#

Make sure lsp-log-io is nil. You might have forgotten it after a debugging session, for example. It can cause a great performance hit.

(setq lsp-log-io nil) ; if set to true can cause a performance hit

Sometimes you might need to check logging for specific LSP server configuration as well, i.e. for lsp-eslint it is: lsp-eslint-trace-server.

Reporting performance problems#

If you have tried all of the non-optional steps from the list and emacs is still not very responsive please open a PR with the following information:

  • Include emacs performance report. Use the following step to collect it:
  • M-x profiler-start and select CPU
  • Reproduce the slow behavior.
  • M-x profiler-stop
  • M-x profiler-report to create a report
  • In the profiler report expand all nodes by doing C-u TAB.

Note: - lsp-mode is just a frontend and the performance depends on server as well. Some servers (e. g. Palantir's Python Language Server) might be slow when performing auto-completion.


Last update: December 3, 2023