garbage-day.nvim stops your LSP clients when Neovim loses focus
Garbage collector that stops inactive LSP clients to free RAM
At a glance
- What is it?
- garbage-day.nvim is a GPL-3.0 licensed Neovim plugin in Lua that shuts down language server clients when the editor loses focus and restarts them on return, on a configurable grace period. It was written for NormalNvim but works on any distribution, and it exposes an aggressive mode for buffer-based switching plus manual triggers for scripting.
- Who is it for?
- Adopt garbage-day.nvim if your Neovim setup holds several language servers open at once and you see the memory cost when you switch away from the editor. Skip it if you work in one language at a time or if your servers are cheap to keep warm.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 65 days ago.
- What is it written in?
- Mainly Lua, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem: background language servers that will not let go
The stated motivation is specific. In many scenarios, unmanaged LSP clients running in the background can take several gigabytes of RAM, and the author wrote this collector to free that memory automatically, originally for NormalNvim, though the README says you can use it on any distribution. That framing matters because the plugin is not trying to make your editor faster. It is trying to make your editor smaller when you are not looking at it. Language servers are long-lived processes, and the default behaviour in most editors is to keep them alive for the whole session so that the next file of the same type opens instantly. The trade the plugin makes is deliberate: give up some of that instant-warm advantage in exchange for memory that comes back when you leave. The topics confirm the scope, with language-server-protocol, neovim-plugin, nvim-lsp and nvim-plugins, and the primary language is Lua with the repository not archived and the last push on 2026-08-19.
Installing it through lazy.nvim
The setup section gives one configuration block, and it is a lazy.nvim plugin spec with an event of VeryLazy so that the plugin itself does not cost you anything at startup.
{
"zeioth/garbage-day.nvim",
event = "VeryLazy",
opts = {
-- your options here
}
},The plugin also supports changing options at execution time, with the README giving the form of that as setting a key on the g:garbage_day_config table from a command line, so you can adjust the grace period or toggle a mode without editing your configuration and reloading. The repository layout is small and tells you how the code is organised: a lua directory with the plugin code, a selene.toml and a .selene-schema.yml for the Lua linter, a .stylua.toml for formatting, a .github directory, a LICENSE and the README. Releases are v1.4.0 from 2026-02-25, v1.3.1 from 2024-09-23 and v1.3.0 from 2024-05-23.
The four options that decide when servers die
The available options table is short, and the defaults tell you the intended behaviour. aggressive_mode defaults to false, and setting it to true stops all LSP clients except the current buffer every time you enter a buffer. The README is precise about two things: aggressive_mode ignores grace_period, and it only triggers when you enter a buffer with a different filetype than the current buffer. That last condition is the interesting design choice, because it means the aggressive path only fires when you are actually switching languages, not every time you move between two files of the same type. The stated purpose is maximum RAM saving. excluded_lsp_clients is a table of clients that should never be stopped, described as useful for LSP clients that misbehave, with the default table living in the plugin's config module. grace_period defaults to 60*15, the number of seconds to wait before stopping all LSP clients after Neovim loses focus. And wakeup_delay defaults to 0, the milliseconds to wait before restoring LSP after the mouse re-enters Neovim, offered as a way to avoid waking clients by accident when the mouse passes over the window.
The debug options, and the one rule you must not break
There is a separate set of debug options for the case where a particular client does not start or stop correctly on your machine. aggressive_mode_ignore is a list of buffers to ignore when aggressive_mode fires, and notifications defaults to false and when set to true gives you a notification every time garbage collection triggers, which is the first thing to turn on when something is not behaving. retries defaults to 3, the number of times to try to start an LSP client before giving up, and timeout defaults to 1000 milliseconds, the time taken for the retries to complete, with the README's example that by default it tries 3 retries for 1000ms. Below the tables there is an instruction that matters more than the individual defaults: if you change the default values, make sure the value of grace_period is always bigger than timeout/1000. The reason given is that this leaves enough time between stop_lsp() and start_lsp() so that they do not overlap, which is the kind of detail that turns into a race condition with no useful error message when it is wrong.
Triggering collection by hand from a keymap
The FAQ answers the question of whether garbage collection can be triggered manually, and it can, through the plugin's utils module.
require("garbage-day.utils").stop_lsp() -- stop all lsp clients.
require("garbage-day.utils").start_lsp() -- start lsp clients for the current buffer.The two calls are deliberately separate, so you can bind them to different keys, one to free memory on demand and one to warm the servers back up. That makes the plugin usable as a building block in a larger workflow rather than only as an automatic background behaviour, which is the more useful of the two modes if you know when you are about to switch projects. The FAQ also records the tested Neovim versions, 0.10, 0.11, 0.12 and 0.13, and asks that anyone on a newer version who finds it not working open an issue, since the plugin uses LSP client APIs that have changed across those releases.
Where garbage-day.nvim is the wrong choice
Three limits. The first is that it trades startup latency for memory, and for some people that trade is the wrong way round. If you keep four language servers for four languages open and switch between projects all day, every switch back now costs you a server start, and the aggressive mode makes that worse by firing on every filetype change rather than only on focus loss. Whether that is acceptable depends on your machine and how often you switch, and the plugin cannot decide that for you. The second is that stopping a client is not always clean. The README itself anticipates clients that misbehave and ships excluded_lsp_clients for them, which tells you the author has seen clients that fail to restart or fail to shut down properly. Any client you exclude is a client whose memory is never reclaimed, so the exclusion list is a direct subtraction from the benefit. The third is the alternative the README points at, lsp-timeout, which is recommended for Neovim versions at or below 0.8. That is a different mechanism with a different design, and the recommendation is specific: for older versions, use lsp-timeout rather than this plugin. On a current Neovim the choice is narrower, but it is still a choice between a background collector that acts on focus and a timeout-based one that acts on idleness, and they will not behave the same way on your setup.
Editorial conclusion
Adopt garbage-day.nvim if your Neovim setup holds several language servers open at once and you see the memory cost when you switch away from the editor. Skip it if you work in one language at a time or if your servers are cheap to keep warm. Before you change any defaults, remember the README's constraint that grace_period must stay larger than timeout divided by 1000, so the stop and start calls cannot overlap.
Frequently asked questions
What does garbage-day.nvim do?
It is a garbage collector for LSP clients that stops them to free RAM. The README explains that unmanaged LSP clients running in the background can take several gigabytes of RAM, and the plugin stops them after Neovim loses focus and restarts them when you come back.
How do I install garbage-day.nvim?
Add it to your lazy.nvim configuration with an event of VeryLazy and an opts table, using the plugin name zeioth/garbage-day.nvim. Options can also be changed at execution time by setting a key on the g:garbage_day_config table from the command line.
What are the main options in garbage-day.nvim?
aggressive_mode, false by default, stops all clients except the current buffer on entering a buffer with a different filetype and ignores grace_period. excluded_lsp_clients lists clients that should never be stopped. grace_period defaults to 60*15 seconds, the wait after focus loss before stopping clients. wakeup_delay defaults to 0 milliseconds and delays restoring clients after the mouse returns.
Can I trigger garbage collection manually in garbage-day.nvim?
Yes. Call `require("garbage-day.utils").stop_lsp()` to stop all clients and `require("garbage-day.utils").start_lsp()` to start the clients for the current buffer, which lets you bind the two to separate keymaps.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zeioth-garbage-day-nvim)Was this useful?