How do I schedule a Lua callback to run after a delay in Neovim for deferred or non-blocking initialization?
Answer
vim.defer_fn()
Explanation
vim.defer_fn(fn, timeout) schedules a Lua function to run after timeout milliseconds. It is the simplest way to defer work in Neovim without blocking the editor startup or the current event loop iteration.
How it works
vim.defer_fn(fn, timeout)takes a zero-argument function and a delay in milliseconds- The callback runs on the main Neovim event loop after the timeout expires
- It is backed by
vim.uv.new_timer()internally but handles cleanup automatically — no need to calltimer:close() - Passing
0as the timeout defers to the next event loop iteration without any real delay
Example
Deferring a notification until after startup completes:
vim.defer_fn(function()
vim.notify('Neovim is ready!', vim.log.levels.INFO)
end, 200)
Delay a heavy autocmd setup so it doesn't slow startup:
vim.defer_fn(function()
require('my-heavy-plugin').setup()
end, 0) -- next event loop tick
Tips
- For repeating timers or precise control, use
vim.uv.new_timer()instead vim.defer_fndoes not return a cancellable handle — usevim.uv.new_timer()if you need to cancel before firing- Useful in
VimEntercallbacks to avoid blocking the initial render