lsp

lassemaatta 2025-07-29T10:46:50.110289Z

anyone else seen increased cpu usage with clojure-lsp when rebasing etc?

lassemaatta 2025-07-29T10:47:34.695429Z

I recall a while back clojure-lsp learned how to rescan the project when you e.g. switch branches.

lassemaatta 2025-07-29T10:49:36.916219Z

For a while now (maybe a few weeks or so) what I've seen is that I'll do some trivial change (e.g. squash a bunch of wip commits into a single commit) and I'll notice my cpu usage goes through the roof as clojure-lsp starts to calculate something. I've tried to wait a while but usually I just close my project in emacs, which kill the lsp process.

lassemaatta 2025-07-29T10:54:31.725899Z

I was wondering if anyone else has seen anything like this or if there's some diagnostics I could provide to debug this

lassemaatta 2025-08-04T08:56:28.995339Z

I managed to look at the logs while this was happening at it was just thousands of lines of

lassemaatta 2025-08-04T08:56:45.008299Z

025-08-04T08:53:14.622Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.622Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.622Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.624Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 26ms
2025-08-04T08:53:14.632Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 5482ms
2025-08-04T08:53:14.632Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.636Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 2441ms
2025-08-04T08:53:14.638Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 683ms
2025-08-04T08:53:14.639Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 2479ms
2025-08-04T08:53:14.642Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 705ms
2025-08-04T08:53:14.634Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 2ms
2025-08-04T08:53:14.643Z  INFO [clojure-lsp.server:613] - :internal/analyze-file 25661ms
2025-08-04T08:53:14.643Z  INFO [clojure-lsp.server:195] - :lsp/refresh-test-tree 0ms
2025-08-04T08:53:14.645Z  INFO [clojure-lsp.feature.file-management:263] - :internal/uri-analyzed-by-clj-depend 0ms
2025-08-04T08:53:14.649Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 9ms
2025-08-04T08:53:14.652Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 3132ms
2025-08-04T08:53:14.659Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 3214ms
2025-08-04T08:53:14.661Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 42ms
2025-08-04T08:53:14.666Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 6ms
2025-08-04T08:53:14.669Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.668Z  INFO [clojure-lsp.server:132] - :lsp/publish-diagnostics 0ms
2025-08-04T08:53:14.672Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.672Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.674Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 2ms
2025-08-04T08:53:14.674Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.677Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.677Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 56ms
2025-08-04T08:53:14.678Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 2397ms
2025-08-04T08:53:14.681Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 8ms
2025-08-04T08:53:14.681Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.683Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 11ms
2025-08-04T08:53:14.683Z  INFO [clojure-lsp.kondo:174] - :internal/kondo-findings->analysis 0ms
2025-08-04T08:53:14.684Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 799ms
2025-08-04T08:53:14.694Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 902ms
2025-08-04T08:53:14.694Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 778ms
2025-08-04T08:53:14.697Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 3ms
2025-08-04T08:53:14.698Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 14ms
2025-08-04T08:53:14.685Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 69ms
2025-08-04T08:53:14.704Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 3211ms
2025-08-04T08:53:14.720Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.720Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.723Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 3251ms
2025-08-04T08:53:14.724Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 120ms
2025-08-04T08:53:14.724Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.725Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 1ms
2025-08-04T08:53:14.725Z  INFO [clojure-lsp.feature.file-management:153] - :reference-files/find 77ms
2025-08-04T08:53:14.725Z  INFO [clojure-lsp.feature.file-management:151] - :internal/notify-references 78ms
2025-08-04T08:53:14.727Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 7ms
2025-08-04T08:53:14.731Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 53ms
2025-08-04T08:53:14.731Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 3271ms
2025-08-04T08:53:14.730Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.736Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 1667ms
2025-08-04T08:53:14.731Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 1912ms
2025-08-04T08:53:14.741Z  WARN [clojure-lsp.kondo:372] - [clj-kondo] No configs copied.
2025-08-04T08:53:14.743Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 16ms
2025-08-04T08:53:14.749Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.750Z  INFO [clojure-lsp.feature.diagnostics.built-in:298] - :internal/built-in-linters.unused-public-vars 3356ms
2025-08-04T08:53:14.751Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 4127ms
2025-08-04T08:53:14.753Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 1944ms
2025-08-04T08:53:14.753Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 2ms
2025-08-04T08:53:14.755Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.756Z  INFO [clojure-lsp.kondo:174] - :internal/kondo-findings->analysis 0ms
2025-08-04T08:53:14.756Z  INFO [clojure-lsp.feature.file-management:259] - :internal/uri-analyzed-by-clj-kondo 112ms
2025-08-04T08:53:14.759Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 0ms
2025-08-04T08:53:14.767Z  INFO [clojure-lsp.feature.diagnostics.built-in:304] - :internal/built-in-linters.cyclic-dependencies 0ms
2025-08-04T08:53:14.770Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 3409ms
2025-08-04T08:53:14.771Z  INFO [clojure-lsp.feature.diagnostics.built-in:301] - :internal/built-in-linters.different-aliases 0ms
2025-08-04T08:53:14.773Z  INFO [clojure-lsp.feature.diagnostics.built-in:295] - :internal/built-in-linters.find-linter-ignore-comments 11ms
2025-08-04T08:53:14.774Z  INFO [clojure-lsp.feature.diagnostics.built-in:289] - :internal/built-in-linters 1761ms
2025-08-04T08:53:14.780Z  INFO [clojure-lsp.dep-graph:280] - :internal/maintain-dep-graph 28ms

orestis 2025-07-29T11:21:08.700039Z

I have recently switched to Neovim from VSCode, mainly to avoid the lagginess that seems to plague VSCode. However, I can't seem to avoid the clojure-lsp lag - it's even noticeably slower (or perhaps I just see it better) - I also get an occasional time out. However, I don't see a CPU spike or anything like that that would explain the error. Any similar issues by neovim users?

practicalli-johnny 2025-08-01T10:17:16.026149Z

I've been using Neovim (AstroNvim) with Clojure LSP & Conjure for the last couple of years, on two different commercial projects. I haven't experienced any performance issues with Clojure LSP or Neovim's LSP client (Neovim 0.9 / 0.10 /0.11). I do have 32Gb on Linux / MacOSX machines. Note: I've also run Clojure LSP on an android tablet via Termux and the jar version for Clojure LSP and it worked well.

šŸŽ‰ 2
borkdude 2025-07-29T11:22:32.523319Z

have you tried the latest nightly build? there might be an improvement in there

orestis 2025-07-29T11:25:27.742489Z

I was just reading through that. Indeed, clojure-lsp is the most memory intensive program in my list right now!

borkdude 2025-07-29T11:26:05.012569Z

how much memory does your system have

orestis 2025-07-29T11:26:18.152589Z

I have an M1 Macbook Air with 16GB.

borkdude 2025-07-29T11:26:32.425009Z

I have one too (one of my systems)

orestis 2025-07-29T11:27:05.106659Z

Right now I see clojure-lsp at 6.53 GB

orestis 2025-07-29T11:29:24.154579Z

I will check how to install nightly builds with use in Neovim

ericdallo 2025-07-29T12:18:05.135289Z

6gb sounds too much. About the lag, I never heard issues like that, after started server is fast. Maybe it's a nvim thing like emacs has lsp-idle-time which is the time to process server new messages

orestis 2025-07-30T06:52:11.264039Z

I did a fresh restart of everything incl. download the nightly build mentioned above. So far everything is very very fast, but I will check to see how it goes through the course of the day.

šŸ‘ 2
orestis 2025-07-30T13:57:42.875009Z

After a day of working, I see the memory usage at 3.85gb

orestis 2025-07-30T13:58:00.924199Z

The initial memory at startup was around 2gb

borkdude 2025-07-30T13:59:54.636759Z

I have these java processes which run clojure-lsp. the 7gb one is metabase, one of the biggest OSS clojure projects I know

borkdude 2025-07-30T14:00:18.324519Z

I don't think it can be clj-kondo anymore though since there's nothing being kept in memory anymore (hopefully) after run! is finished

orestis 2025-07-30T14:04:42.741999Z

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
ClojureScript                  305           6192           2237          69649
Clojure                        358           9626           3965          67046
ClojureC                        21            340            168           2026

borkdude 2025-07-30T14:05:13.597359Z

looks like a pretty normal project

orestis 2025-07-30T14:05:32.027569Z

Yep, nothing huge.

borkdude 2025-07-30T14:05:54.190049Z

it could be that clojure-lsp is also using a cache (using memoize or other) with collections as keys. this is what messed up clj-kondo's memory usage

orestis 2025-07-30T14:06:52.174039Z

The interesting thing is that all that memory is swapped to disk. The "real memory" used is only 40MB.

borkdude 2025-07-30T14:07:56.744029Z

ah, it could be that it's just keeping files in the memory cache, the OS does that to keep things fast

borkdude 2025-07-30T14:08:11.721019Z

huh

borkdude 2025-07-30T14:08:25.285289Z

no, maybe your machine is just swapping because of memory shortage

orestis 2025-07-30T14:08:49.136559Z

Yes, it's definitely swapping out.

borkdude 2025-07-30T14:09:04.957679Z

is memory pressure yellow in your activity tab?

orestis 2025-07-30T14:09:20.793979Z

Does it even have any other color? šŸ˜„

borkdude 2025-07-30T14:09:50.047629Z

hehe. mine is also constantly yellow (on my m1). I opted for more memory in my newer machine

borkdude 2025-07-30T14:10:00.539179Z

is it still slow though? or managable?

orestis 2025-07-30T14:11:21.023749Z

neovim became usable again. I've also killed an ollama server I had running in the background. AI so far has been only a drag šŸ˜„

orestis 2025-07-30T14:11:40.797159Z

The LSP is snappy - it feels like I'm not waiting on it at all.

borkdude 2025-07-30T14:12:33.484479Z

if it feels fast, that's the most important thing I guess

borkdude 2025-07-30T14:13:21.911909Z

if lsp has a memory leak, should manifest itself after using it for a longer time and running larger and larger. should be detectable via an hprof file

borkdude 2025-07-30T14:13:58.899839Z

this might also help: https://www.graalvm.org/latest/reference-manual/native-image/guides/create-heap-dump/

orestis 2025-07-30T14:14:22.169249Z

I'll clock out for the day and resume tomorrow, let's see how another full day feels like.

borkdude 2025-07-30T14:15:14.296539Z

oh I guess you should compile the native image with --enable-monitoring=heapdump,jvmstat to be able to get an hprof file

borkdude 2025-07-30T14:15:28.766519Z

might as well run a jvm when testing for this

orestis 2025-07-30T14:16:45.272349Z

to be honest I'm too close to my vacation (Friday, yay!) to test for this. It feels like it could be tested synthetically somehow by running a server and sending 10 commands per second for a period of a hew hours...

šŸ‘ 1
ericdallo 2025-07-30T14:25:18.138979Z

Ollama serve affects a lot my machine memory BTW. And yes, clojure-lsp has a atom in memory for all analysis, but I don't think it should be a problem unless it's a metabase project with thousands of analysis

ericdallo 2025-07-30T14:25:37.007029Z

You can always tune and disable keywords or other features analysis although not ideal

orestis 2025-07-30T14:26:24.983069Z

Speaking of, in Calva/VSCode, I could get references to keywords etc, but in neovim it seems not. I guess Calva overrides some configuration properties? I will have to revisit.

ericdallo 2025-07-30T15:18:57.557289Z

Sounds like you are using a outdated clojure-lsp? Keyword References should work all the same for any client

ericdallo 2025-07-30T15:19:11.140909Z

In the end it's just LSP references feature

orestis 2025-07-30T16:31:19.632119Z

I’m using the nightly version as of this morning

orestis 2025-07-30T16:35:42.715559Z

What I used to able to do, was in big EDN file, I was able to go to definition on plain keywords and it would take me to the place where that keyword appears as a key. Not sure if that was a VACode heuristic though.

ericdallo 2025-07-30T17:34:10.711819Z

maybe, clojure-lsp supports find-definition of keywords only when it's a reg-fx or similar, not only map keys

robert-stuttaford 2025-07-29T12:59:05.755589Z

is it possible to constrain lsp-find-references to a specific set of namespaces somehow?

robert-stuttaford 2025-08-01T10:11:35.288719Z

pretty sure the path regex stuff isn't working as described, @ericdallo šŸ˜…

robert-stuttaford 2025-08-01T10:12:17.113809Z

should i file an issue?

borkdude 2025-08-01T10:15:02.850569Z

why do you use multiple of the same strings on source-paths-ignore-regex and why do you use a trailing /?

borkdude 2025-08-01T10:16:06.243249Z

(not that is probably matters)

robert-stuttaford 2025-08-01T10:16:06.473509Z

i don't:

{:clean                     {:automatically-after-ns-refactor true
                             :ns-inner-blocks-indentation     :same-line
                             :ns-import-classes-indentation   :same-line}
 :cljfmt-config-path        ".cljfmt.edn"
 :source-paths-ignore-regex ["src/cognician/chat/"
                             "src/cognician/c3_model"]
 :paths-ignore-regex        ["src/cognician/chat/"
                             "src/cognician/c3_model"]}

robert-stuttaford 2025-08-01T10:16:19.207669Z

and, the trailing slash is so that chat_c4 is not filtered out

borkdude 2025-08-01T10:16:32.359649Z

ok, I see something different in your screenshot

robert-stuttaford 2025-08-01T10:16:52.671879Z

yeah the duplicates are in the lsp-clojure-server-info output, but not in the config i maintain

borkdude 2025-08-01T10:16:58.325849Z

weird

borkdude 2025-08-01T10:19:24.553169Z

I'm using this script to run clojure-lsp locally:

#!/usr/bin/env bash

# override project config:
export CLJ_KONDO_EXTRA_CONFIG_DIR=~/.config/clj-kondo

clj -Sdeps '{:aliases
              {:lsp
                {:replace-paths []
                 :replace-deps
                  {org.clojure/clojure {:mvn/version "1.11.1"}
                   clj-kondo/clj-kondo {:local/root "/Users/borkdude/dev/clj-kondo"}
                   clojure-lsp/clojure-lsp {:local/root "/Users/borkdude/dev/clojure-lsp/cli"}
                   cider/cider-nrepl {:mvn/version "0.28.6"}}}}}' \
                       -M:lsp -m clojure-lsp.main "$@"
I use this to always have my dev version of clj-kondo active, but you could also try this to debug the source-paths regex thing

robert-stuttaford 2025-08-01T10:19:33.357659Z

usually i'd just tough it out (i have been for years), but in this situ i'd really value the ability to filter like this

robert-stuttaford 2025-08-01T10:19:41.835559Z

ok ty!

borkdude 2025-08-01T10:20:23.839089Z

in your case you can leave out clj-kondo and just let clojure-lsp pick clj-kondo

borkdude 2025-08-01T10:20:53.427719Z

I don't remember why I have the env var at the top though

borkdude 2025-08-01T10:20:59.042179Z

but you get the gist

robert-stuttaford 2025-08-01T10:21:50.602559Z

i do, thanks borkers!

ericdallo 2025-07-29T13:02:03.921149Z

currently not

borkdude 2025-07-29T13:02:18.827269Z

why would you do so @robert-stuttaford?

robert-stuttaford 2025-07-29T13:04:33.457859Z

210,000 loc monorepo šŸ˜„

robert-stuttaford 2025-07-29T13:05:04.024399Z

reworking a part of the code some times involves working through a set of find-references. being able to limit that to a src sub-path reduces friction

ericdallo 2025-07-29T13:05:10.381309Z

you can configure clojure-lsp to ignore some paths for analysis, then it should exclude all features including references

robert-stuttaford 2025-07-29T13:05:24.528949Z

that might help, thank you!

ericdallo 2025-07-29T13:05:44.319429Z

:paths-ignore-regex or :source-paths-ignore-regex https://clojure-lsp.io/settings/#all-settings

šŸ™ 1
robert-stuttaford 2025-07-29T13:19:09.921389Z

i have two paths src/cognician/chat/* and src/cognician/chat_c4/*. i want the first one ignored but not the second. my settings, which don't seem to work after a restart of emacs (in .lsp/config.edn; .lsp is a sibling of src): :source-paths-ignore-regex ["src/cognician/chat/.*"] i guess i need to clear caches šŸ˜„

robert-stuttaford 2025-07-29T13:19:46.986009Z

trying that now...

robert-stuttaford 2025-07-29T13:22:03.145429Z

naw it's still listing stuff from that folder

ericdallo 2025-07-29T13:33:15.280039Z

the source-paths is kinda of tricky, try checking clojure-lsp server logs about the source-paths using when starting

šŸ™ 1