Every time I’m troubleshooting a hardware issue, a networking oddity, or trying to understand what’s actually running inside the kernel of a box I’ve just SSH’d into, lsmod is one of the first three commands I type. It’s simple, it’s fast, and it gives you an honest, real-time snapshot of exactly what kernel code is currently loaded and in use.
What lsmod Actually Is
lsmod lists all kernel modules that are currently loaded into the running Linux kernel. Unlike modinfo (which reads static metadata from a module file on disk), lsmod reports live kernel state — what’s actually loaded right now, how much memory it’s using, and how many other things depend on it. Under the hood, lsmod is a thin, almost trivial wrapper: it simply formats and prints the contents of /proc/modules.
Basic Syntax
lsmod
That’s it — lsmod takes no meaningful options in most implementations (some very old versions accept --version/-V, and that’s about it). All the real filtering happens by piping its output through grep, awk, sort, etc.
A Basic Example
lsmod
Module Size Used by
nf_conntrack 172032 1 xt_conntrack
vfat 24576 0
fat 98304 1 vfat
e1000e 335872 0
ip_tables 32768 1 iptables
Three columns, always:
- Module — the module’s name (matches what you’d pass to
modprobe/rmmod). - Size — how much memory the module currently occupies, in bytes.
- Used by — a count of how many other things (other modules, or open references from userspace) are currently using this module, followed by a comma-separated list of the names of the modules that depend on it, if any.
This last column is critical: a module with a non-zero “used by” count cannot be unloaded until those dependents are removed first.
No Options, Lots of Piping
Since lsmod itself has essentially no flags, the real skill is in how you filter and interpret its output.
Finding a specific module:
lsmod | grep vfat
Sorting by memory usage (largest first) — useful when hunting for memory hogs:
lsmod | sort -k2 -n -r | head -10
Counting how many modules are currently loaded:
lsmod | wc -l
(Subtract 1 for the header line if you want the exact module count.)
Listing only modules with zero dependents (safe to consider unloading):
lsmod | awk '$3 == 0 {print $1}'
Checking whether a specific module is loaded, in a script:
if lsmod | grep -q "^nf_conntrack "; then
echo "nf_conntrack is loaded"
else
echo "nf_conntrack is NOT loaded"
fi
Note the trailing space and ^ anchor in the grep pattern — without it, grep vfat would also match nf_conntrack style names that happen to contain your search string as a substring elsewhere, or worse, match a longer module name that starts with the same characters (e.g., nf_conntrack vs nf_conntrack_ipv4).
Where the Data Actually Comes From
lsmod reads directly from:
/proc/modules
You can, in fact, get the exact same raw information yourself:
cat /proc/modules
nf_conntrack 172032 1 xt_conntrack, Live 0xffffffffc0a4e000
vfat 24576 0 - Live 0xffffffffc0912000
lsmod is really just this file, reformatted into aligned columns with a header row — which is why it’s such a fast, lightweight command with essentially zero overhead.
Related live information also lives under /sys/module/<name>/, which lsmod doesn’t display directly but is worth knowing about:
ls /sys/module/e1000e/
coresize drivers holders initsize initstate notes parameters refcnt sections taint uevent version
For instance, /sys/module/<name>/parameters/ shows the currently active values of a loaded module’s runtime-adjustable parameters — genuinely useful alongside lsmod for confirming a module isn’t just loaded, but configured the way you expect.
cat /sys/module/e1000e/parameters/debug
Real-World System Administration Examples
Pre-flight check before attempting to unload a module:
lsmod | grep "^fat "
fat 98304 1 vfat
Seeing 1 vfat here tells you immediately that you must remove vfat first — rmmod fat alone will fail with “in use” until you do.
A quick health-check script confirming required modules are loaded on a Kubernetes node:
#!/bin/bash
REQUIRED=(overlay br_netfilter ip_vs)
MISSING=()
for mod in "${REQUIRED[@]}"; do
lsmod | grep -q "^${mod} " || MISSING+=("$mod")
done
if [ ${#MISSING[@]} -gt 0 ]; then
echo "Missing required kernel modules: ${MISSING[*]}"
exit 1
fi
echo "All required kernel modules present."
Diagnosing unexpectedly high kernel memory usage:
lsmod | sort -k2 -n -r | head -5
If one module is consuming an outsized amount of memory relative to expectations (drivers with memory leaks are a known, if uncommon, real-world issue), this is usually the first place to look, alongside /proc/meminfo‘s Slab figures.
Comparing loaded modules before and after a hardware or kernel change:
lsmod | awk '{print $1}' | sort > /tmp/modules_before.txt
# ... make a change, reboot, reconnect hardware, etc ...
lsmod | awk '{print $1}' | sort > /tmp/modules_after.txt
diff /tmp/modules_before.txt /tmp/modules_after.txt
Combining lsmod With Other Module Commands
lsmod tells you what’s loaded. To go further, pair it with:
modinfo $(lsmod | awk 'NR==2{print $1}') # inspect the metadata of the top module in the list
sudo modprobe -r $(lsmod | awk '$3==0 && $1=="oldmodule"{print $1}')
A very common admin workflow:
lsmod | grep target_module # 1. confirm it's loaded and check dependents
modinfo target_module # 2. review what it does and its parameters
sudo modprobe -r target_module # 3. safely remove it (and now-unused deps)
lsmod | grep target_module # 4. confirm it's actually gone
Troubleshooting
A module I just loaded doesn’t appear in lsmod — check dmesg immediately; the load may have failed silently at the shell level (e.g., a version mismatch), and lsmod will correctly show nothing because nothing actually succeeded in loading.
lsmod output looks empty or truncated in a container — inside most containers, /proc/modules reflects the host kernel’s loaded modules (since containers share the host kernel), but access may be restricted or the file may not be mounted at all depending on the container runtime’s configuration — this is expected container isolation behavior, not a bug in lsmod.
Trying to unload a module fails with “in use” — check the “Used by” column; you must remove dependent modules first, or use modprobe -r which handles the chain automatically (where safe to do so).
Module shows in lsmod but the device still isn’t working — being loaded doesn’t guarantee successful hardware initialization; check dmesg for post-load errors and confirm with ls /sys/module/<name>/ that the module actually attached to a device, not just that it’s resident in memory.
Performance Considerations
lsmod itself has negligible performance cost — reading /proc/modules is essentially free. The genuinely useful performance angle is using lsmod as a lightweight diagnostic tool: unusually large module memory footprints, or an unexpectedly long list of loaded modules on a minimal system, can both be early signals of driver bloat, unnecessary hardware support being loaded, or (rarely) a misbehaving/leaking driver worth investigating further with tools like /proc/slabinfo or crash/kdump analysis.
Security Considerations
- Reviewing
lsmodoutput periodically on servers — especially ones with strict security baselines — helps catch modules that shouldn’t be loaded (unused filesystem drivers, legacy protocol support, unnecessary USB storage drivers) that represent unneeded attack surface; unload and blacklist anything not required. - On systems where you’ve deliberately locked down module loading after boot (
sysctl kernel.modules_disabled=1),lsmodremains fully functional as a read-only audit tool even after that lockdown is in effect, since it doesn’t itself load or unload anything. - Rootkits historically have targeted the loaded-module list as something to hide from — some kernel-level rootkits attempt to unlink themselves from the list
lsmod//proc/modulesreads from. This is one reason security-conscious environments cross-checklsmodoutput against independent memory-forensics tooling rather than trusting it as the sole source of truth on a potentially compromised system.
Comparison to Related Commands
modinfo— static, on-disk metadata about a module file;lsmodis live, in-kernel state.modprobe/insmod— the commands that actually change whatlsmodwill subsequently show.rmmod/modprobe -r— remove a module;lsmod‘s “Used by” column tells you in advance whether that removal will succeed.cat /proc/modules— the raw data sourcelsmodformats; functionally near-identical, just less readable./sys/module/<name>/— richer, per-module live detail (parameters, sections, taint status) thatlsmoddoesn’t show directly but complements well.
lsmod‘s behavior and output format are effectively identical across every Linux distribution — Debian, Ubuntu, RHEL, CentOS, Fedora, SUSE, Arch — since it’s just a thin, standardized wrapper around /proc/modules, which is core kernel functionality, not a distro-specific feature.
Summary
lsmod is about as simple as Linux commands get — no options to memorize, no configuration files, just an honest, instant snapshot of what’s actually loaded in the kernel right now, how much memory it’s using, and what depends on it. It’s rarely the whole answer to a troubleshooting question on its own, but it’s almost always the right first command to run before reaching for modinfo, modprobe, or rmmod.
References
man lsmodon your local systemman 5 proc(documents/proc/modules)kmodproject documentation- Linux Kernel Module Programming Guide (kernel.org)
