The /proc Filesystem Explained
/proc is a virtual filesystem that gives the kernel a way to expose live system and process information as ordinary, readable files, without needing a specialized API for every individual question you might have. It is not stored on disk; every file’s contents are generated by the kernel at the moment you read them, always reflecting current live state. Nearly every tool that reports on processes, memory, or system status, ps, top, free, uptime, and many more, is ultimately reading from /proc under the hood.
Why /proc exists
Before /proc existed as a convention, getting information out of the kernel required specialized system calls for each specific piece of data. Presenting kernel and process state as a filesystem instead means any tool that can read a file, which is essentially everything, can query kernel state with no special API needed: cat /proc/meminfo works the same way cat works on any other file, even though the content behind it is generated live by the kernel rather than stored anywhere on disk.
ls /proc
Most entries are numbered directories, one per running process, matching that process’s PID, alongside a set of system-wide files and directories covering everything from memory to loaded kernel modules.
Key system-wide files
cat /proc/cpuinfo # detailed info on every logical CPU core
cat /proc/meminfo # detailed memory statistics
cat /proc/loadavg # the current load average (the raw source behind the uptime command)
cat /proc/uptime # system uptime and idle time, in seconds
cat /proc/version # kernel version string
cat /proc/mounts # currently mounted filesystems
These are the same files tools like free, uptime, and lscpu read from directly. Running free -h is, at its core, a formatted, human-friendly presentation of the raw numbers already sitting in /proc/meminfo.
cat /proc/meminfo | head -5
MemTotal: 16384000 kB
MemFree: 3145728 kB
MemAvailable: 8912896 kB
Buffers: 204800 kB
Cached: 6144000 kB
Inspecting a specific process
Every running process has a numbered directory matching its PID:
ls /proc/1234
cmdline cwd environ exe fd maps status ...
A few of the most useful entries:
cat /proc/1234/cmdline | tr '\0' ' ' # exact command line the process was started with
cat /proc/1234/status # human-readable summary: memory, state, threads
ls -l /proc/1234/fd # every file descriptor currently open by this process
ls -l /proc/1234/cwd # symlink to the process's current working directory
cat /proc/1234/environ | tr '\0' '\n' # the process's environment variables
cmdline and environ separate their fields with null bytes rather than newlines or spaces, which is why tr '\0' ' ' (or \n) is commonly piped in to make the output readable, otherwise it prints as one unbroken line with no visible separators.
/proc/PID/fd is particularly useful for troubleshooting: it is exactly what lsof reads to report which files a process has open, and reading it directly answers “what files does this specific process currently have open” without needing a separate tool at all.
/proc/sys: readable and writable kernel tunables
Unlike most of /proc, which is read-only, /proc/sys/ exposes kernel parameters that can, for many entries, be both read and written, forming the actual mechanism behind the sysctl command:
cat /proc/sys/vm/swappiness
60
echo 10 | sudo tee /proc/sys/vm/swappiness
This has the identical effect to sudo sysctl vm.swappiness=10, changing the live kernel setting immediately. Changes made this way apply instantly but do not persist across a reboot unless also written to a configuration file such as /etc/sysctl.conf or a file under /etc/sysctl.d/.
A practical example: why is a port already in use
ss -tlnp | grep :8080
# tcp LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("myapp",pid=1234,fd=6))
ls -l /proc/1234/fd/6
Cross-referencing a PID reported by ss with that process’s /proc/PID/fd directory confirms exactly what that specific file descriptor is connected to, useful for confirming ss’s report against the actual live state of the process, rather than trusting one tool’s summary alone.
Things to keep in mind
Reading files under /proc is safe and does not modify kernel state, generation happens purely on read. The main exception is deliberately writable files like those under /proc/sys/, which are designed to be written to as a live configuration interface, and writing to them should be intentional. Also worth knowing: file sizes reported by tools like ls -l for /proc entries are often meaningless or zero, since content is generated at read time rather than stored with a predetermined size, which is normal /proc behavior rather than a sign anything is broken.
Frequently Asked Questions
What is /proc and why does it look like a filesystem?
/proc is a virtual filesystem, meaning it does not correspond to actual data stored on disk; instead, the kernel generates its contents dynamically, on demand, whenever something reads from it. It is presented as a filesystem, with directories and files you can cat, ls, and read normally, because that is a convenient, already-understood interface for exposing live kernel and process information, rather than requiring every tool to use a specialized API just to ask “how much memory is free” or “what command started this process.” Reading a file under /proc always reflects the current live state, not a stored snapshot from some earlier point.
Where do tools like ps, free, and top actually get their information?
Almost entirely from /proc. free reads /proc/meminfo for memory statistics, ps and top read the numbered process directories under /proc (like /proc/1234 for process 1234) for command lines, memory usage, and state information, and uptime and load average commands read /proc/uptime and /proc/loadavg respectively. None of these tools have special privileged access to the kernel beyond what reading these files provides; they are, in effect, formatted, human-friendly views over the same raw data anyone can read directly from /proc themselves.
What is inside a process directory like /proc/1234?
Each running process has a numbered directory under /proc matching its PID, containing files and subdirectories describing that specific process: cmdline (the exact command line it was started with), status (a human-readable summary including memory usage and process state), environ (its environment variables, null-separated), fd/ (a directory of symlinks representing every file descriptor the process currently has open), and several others. Reading these directly is how tools like ps and lsof gather their information, and reading them yourself is a useful way to inspect a specific running process in detail without needing a specialized tool for the exact question you have.
Is it safe to read files under /proc?
Reading is safe and does not affect the running system, since /proc files are generated on read and reading them does not modify kernel state, with rare specific exceptions for a small number of files deliberately designed to be written to as a control interface (like /proc/sys/ entries, used by sysctl to tune kernel parameters). Writing to most /proc files either has no effect, is not permitted without root, or in the specific case of files under /proc/sys/, is the intended mechanism for changing a live kernel setting, so writing should be done deliberately and only to files you specifically intend to change, not as routine exploration.
What is /proc/sys used for?
/proc/sys/ is the interface for reading and, in many cases, writing live kernel tunable parameters, the same underlying mechanism the sysctl command uses. For example, /proc/sys/vm/swappiness holds the current swappiness value, readable with cat /proc/sys/vm/swappiness, and writable directly (as root) with echo 10 | sudo tee /proc/sys/vm/swappiness, which has the identical effect to sudo sysctl vm.swappiness=10. Changes made this way take effect immediately but do not persist across a reboot unless also set in a sysctl configuration file, such as /etc/sysctl.conf.
Why does /proc show 0 bytes for most files even though cat shows real content?
Files under /proc are not stored on disk with a predetermined size the way an ordinary file is; their content is generated by the kernel at the moment they are read, so tools that check file size in advance (like some implementations of ls -l, or programs that try to read a fixed number of bytes based on a reported size) often see a reported size of 0, even though reading the file with cat or a similar tool produces real, non-empty content. This is expected behavior specific to virtual filesystems like /proc, not a sign of a corrupted or empty file, and it is one of several ways /proc behaves differently from a normal filesystem despite looking like one from the outside.