A Metabase engineer investigated why clojure-lsp took over 3 minutes to analyze the Metabase codebase. Using VisualVM and clj-async-profiler allocation profiling, they identified key bottlenecks in clj-kondo (which accounts for 95% of initialization work). Optimizations included: improving the deep-merge function to skip unnecessary assoc operations, removing a dynamic variable on a hot path in rewrite-clj, and replacing clojure.core/memoize with a specialized implementation using nested maps for two-argument functions. The result was a 2x reduction in startup time and nearly 3x reduction in heap allocations (from 145GB to 51.6GB total allocated). Changes are merged and will ship in the next clojure-lsp release.

9m read timeFrom metabase.com
Post cover image
Table of contents
Part 1: The mystery of heap headroomPart 2: Profiling and optimizationsPart 3: Measuring total allocationsConclusions

Sort: