Innovate | Connect | Transform
ContactService statusUSD $

GICT knowledge base

Linux /proc: The Hidden Dashboard Every Server Admin Should Know

Published

monitoring
Linux /proc: The Hidden Dashboard Every Server Admin Should Know

A server feels sluggish. You open top and CPU looks fine. You run free -m and RAM is not maxed out. Nothing obvious. So what is holding things up?

The answer lives in /proc — a directory that looks like ordinary files but is actually a live window into your running kernel. Every number in it is real-time telemetry. No installation, no agents, no extra tools. This article opens that window and reads it.

What /proc Actually Is

On a typical Linux server, /proc is the first clue that something unusual is happening with filesystems. It contains entries like meminfo, loadavg, and numbered directories such as 1, 1234, 5678. It sits alongside your regular directories in the root filesystem.

Here is the first thing that surprises people: those files are not on disk. The kernel generates their content dynamically every time you read them. There is no /proc/meminfo blob sitting on an SSD somewhere. When you run cat /proc/meminfo, the kernel assembles the output from its own internal data structures and streams it to you.

There are two distinct kinds of entries in /proc:

  • System-wide entries — files like meminfo, loadavg, and uptime that describe the kernel state across the entire machine
  • Per-process entries — numbered directories like /proc/1/ where each number is a running process ID

Everything in /proc is real-time. The moment you read it, you are reading the current state of the kernel.

The Sluggish Server Scenario

You log into a VPS via SSH. The shell is responsive but something feels slow. Here is where you start.

$ cat /proc/loadavg
0.20 0.23 0.19 1/525 2008309

loadavg shows three numbers: the load average over the last 1, 5, and 15 minutes. The fourth field (1/525) tells you how many processes are running compared to total processes on the run queue. The fifth number is the last PID assigned. In this case, the load average of 0.20 means the system has been mostly idle.

Now check how long the server has been running:

$ cat /proc/uptime
4949843.40 9014224.84

Two numbers. The first is total uptime in seconds (this machine has been running for about 57 days). The second is the sum of all cores idle time. Divide the second by the first and you get a rough picture of overall CPU idleness.

Memory Pressure

When memory seems fine but something is swapping or reclaiming pages, /proc/meminfo tells the real story. This is the raw source that the free command parses into human-readable output.

$ cat /proc/meminfo
MemTotal:        3905932 kB
MemFree:          275636 kB
MemAvailable:     752408 kB
Buffers:           19132 kB
Cached:           644088 kB
SwapCached:            0 kB
Active:          2250688 kB
Inactive:         943608 kB
SwapTotal:             0 kB
SwapFree:              0 kB

Ignore MemFree. The field you want is MemAvailable. This is the kernel is estimate of how much memory is available for starting new applications without forcing them into swap. On this machine, about 752 MB is available out of 3.9 GB total.

If you want to know whether the OOM killer has fired at any point, check /proc/vmstat:

$ grep -i oom /proc/vmstat
oom_kill 10

Ten OOM kills since boot. That number is cumulative. If it is climbing, your system is repeatedly running out of memory and the kernel is killing processes to stay alive.

Per-Process Inspection

The numbered directories in /proc correspond to running processes. /proc/1 is always the init or systemd process.

$ ls /proc/1/
arch_status  attr  autogroup  auxv  cgroup  clear_refs  cmdline  comm
coredump_filter  cpu_resctrl_groups  cpuset  cwd  environ  exe  fd  fdinfo
gid_map  io  ksm_merging_pages  ksm_stat  loginuid  map_files  maps  mem
mm  mountinfo  net  ns  numa_maps  oom_adj  oom_score  oom_score_adj  pagemap
personality  projid_map  root  sched  schedstat  sessionid  setgroups  smaps
smaps_rollup  stack  stat  statm  status  syscall  timens_offsets  uid_map  wchan

Each of these files exposes something about process 1. Two are particularly useful when you are debugging:

/proc/[PID]/cmdline holds the commands arguments, separated by null bytes:

$ cat /proc/1/cmdline | tr '\0' ' '
/usr/lib/systemd/systemd --system --deserialize=118

/proc/[PID]/status gives a human-readable summary of everything important about a process:

$ cat /proc/self/status
Name:   cat
Umask:  0022
State:  R (running)
Tgid:   2008313
Pid:    2008313
PPid:   2008307
VmRSS:      5828 kB
Threads:    1

VmRSS is the resident set size — the amount of memory actually held in RAM. State shows the process state: R is running, S is sleeping, D is uninterruptible disk sleep, and Z is zombie.

To see what files a process has open, look at its file descriptors:

$ ls -la /proc/self/fd
total 0
lrwx------ 1 root root 64 Jul  8 23:17 0 -> /dev/null
l-wx------ 1 root root 64 Jul  8 23:17 1 -> pipe:[83488113]
l-wx------ 1 root root 64 Jul  8 23:17 2 -> pipe:[83487321]
lr-x------ 1 root root 64 Jul  8 23:17 3 -> /proc/2008357/fd

File descriptor 0 is stdin, 1 is stdout, 2 is stderr. Everything beyond that is what the process actually has open — log files, sockets, pipes, or in this case another process file descriptor.

Real-Time Without Installing Anything

The /proc filesystem lets you build live monitoring on the spot, no tools required.

Watch disk I/O in real time:

$ watch -n 1 'cat /proc/diskstats'

Watch network interface counters:

$ cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier
  eth0: 21530295868 16634716    0    0    0     0          0         0 9430640269 12836024    0    0    0     0

The eth0 line shows total bytes received and transmitted. Run it twice with a pause in between and you can calculate throughput manually.

Find which process is hogging the most file descriptors:

$ ls /proc/*/fd 2>/dev/null | wc -l

Replace wc -l with a loop over /proc/PID/fd and readlink to get a sorted list of the top consumers.

Conclusion

The /proc filesystem is always there. It needs no installation and reveals what external monitoring tools sometimes miss. Every time a process reads a file, writes to disk, allocates memory, or communicates over the network, the kernel updates something in /proc.

Next time a server misbehaves and the usual logs do not help, crack open /proc before you open a support ticket. The kernel is already watching itself. You just have to look.

Related guides

Account services are unavailable until the production backend is configured.