Linux Troubleshooting Made Simple: High CPU vs High Memory vs Disk Full
A practical, beginner-friendly guide to diagnosing and fixing the 3 most common Linux performance problems with real commands and real…

Linux Troubleshooting Made Simple: High CPU vs High Memory vs Disk Full
A practical, beginner-friendly guide to diagnosing and fixing the 3 most common Linux performance problems with real commands and real examples.
▶️ **YouTube , [📸 Instagram](https://www.instagram.com/devops_voice) , [💼 LinkedIn](https://www.linkedin.com/in/tushar-jadhav29/) , [✍️ Medium](https://medium.com/@tushar.jadhav29)**
👉 Non-Member= Click HERE!
[embed]
Introduction
It’s 2.17 AM, your monitoring tool just paged you, and a server that was fine an hour ago is barely responding now. Users are complaining. Requests are timing out. You have exactly one job: figure out why, fast.
Almost every Linux performance emergency comes down to one of three culprits — the CPU is maxed out, the RAM is exhausted, or the disk is full. From the outside, all three look nearly identical: “everything is just slow.” But the causes, the diagnostic steps, and the fixes are completely different — and confusing one for another wastes the one thing you don’t have during an incident: time.
This guide walks through all three, with the exact commands to run, what the output actually means, and how to fix each one for good — plus a real-world example for each.
In this guide:
- A 30-second map for figuring out which resource is the problem
- Part 1: High CPU — symptoms, diagnosis, fixes, real example
- Part 2: High Memory — symptoms, diagnosis, fixes, real example
- Part 3: Disk Full — symptoms, diagnosis, fixes, real example
- A simple decision flow to follow mid-incident
- A full command cheat sheet
- The best practices that prevent most of this from happening in the first place
The 30-Second Diagnosis Map
Before running a single command, it helps to know what you’re looking for:
- CPU problem → processor overloaded → high load average, everything runs slowly
- Memory problem → RAM exhausted → OOM Killer messages, heavy swap usage
- Disk problem → storage full → “No space left on device” errors
- Network problem → high latency → connection timeouts
- I/O problem → slow storage → applications hang without an obvious cause
Once you know which category you’re in, the rest of this guide tells you exactly what to do.
Part 1: High CPU Usage
What’s Actually Going On
CPU usage is simply how much of your processor’s capacity is in use at any moment. “High CPU” means one or more processes are hogging that capacity, and everything else is stuck waiting in line behind them.
Symptoms to Watch For
- The whole system feels sluggish
- Even SSH login takes noticeably longer than usual
- Applications freeze or stop responding
- Load average climbs well above normal
- Fans spin up on physical hardware
- Monitoring alerts start firing
How to Diagnose It
Start with top — your first stop for almost any performance issue:
top
It gives you a live view of CPU usage, memory, load average, and every running process.
**htop for a friendlier version:**
htop
Same data as top, but with color, a process tree, search, and the ability to kill a process without memorizing its PID.
Find exactly which process is the problem:
ps aux --sort=-%cpu | head
This sorts every process by CPU usage, highest first:
PID USER %CPU COMMAND
3254 mysql 95.4 mysqld
2210 java 82.3 java
4100 python 65.2 python3
That’s your smoking gun — now you know exactly what to dig into.
Track a specific process over time:
pidstat -u 1
Check the load average:
uptime
load average: 7.4, 6.8, 5.1
Those three numbers are the average load over the last 1, 5, and 15 minutes. Compare them to your CPU core count. On a 4-core server, roughly:
- Load ~4 → healthy, fully utilized
- Load ~8 → busy, worth watching
- Load ~20 → critical, users are feeling it
Check usage per core:
mpstat -P ALL 1
top's aggregate number can hide a single maxed-out core — common with single-threaded apps.
Look at historical trends:
sar -u 1 5
Useful for spotting patterns, like “CPU spikes every night at 2 AM,” instead of just what’s happening this second.
What to Investigate
Once you’ve found the process, dig into why it’s consuming so much CPU:
- Infinite loops or runaway code
- Expensive, unoptimized SQL queries
- Constant Java garbage collection
- Oversized or overlapping cron jobs
- Backup jobs running during peak hours
How to Fix It
Kill the process, if safe to do so:
kill -9 PID
Try a plain kill PID (SIGTERM) first if you can — it lets the process shut down cleanly. Reach for -9 only when it won't die. (Add sudo if the process isn't owned by your user.)
Or just lower its priority instead of killing it:
renice +10 PID
Higher number = lower priority — a good middle ground when the process needs to stay alive but shouldn’t dominate the CPU.
Start new processes at a lower priority from the beginning:
nice -n 10 command
Preventing It From Happening Again
- Optimize slow SQL queries and application code
- Move heavy cron jobs to off-peak hours
- Track CPU trends so you catch problems building, not just when they hit
- Add caching to cut down repeated expensive work
- Scale horizontally if one server is consistently maxed out
Real-World Example
Problem: A website suddenly became painfully slow.
Investigation:
topshowedmysqldpinned at 98% CPU.
Root cause: A missing database index — MySQL was running full table scans on every query.
Fix: Added the index. CPU usage dropped from 98% to 12% almost immediately.
Part 2: High Memory Usage
What’s Actually Going On
Memory problems happen when applications ask for more RAM than the system has to give. Once RAM is exhausted, Linux starts swapping to disk — far slower than RAM — or, in the worst case, the kernel’s OOM (Out-Of-Memory) Killer starts terminating processes to free up space.
Symptoms to Watch For
- Applications crash without warning
- The whole system feels frozen
- Swap usage is unusually high
- “Out of memory” messages show up in logs
- Even simple commands respond slowly
How to Diagnose It
Get the big picture:
bash
free -h
total used free
Mem: 16G 15G 300M
Swap: 6G
15 of 16 GB used and swap in heavy use — that’s a system under real memory pressure.
Find which process is using the most RAM:
ps aux --sort=-%mem | head
Get a more accurate breakdown:
smem -r
smem accounts for shared memory more precisely than ps, so its numbers are often more trustworthy.
Watch memory and swap activity live:
vmstat 1
Watch the si (swap in) and so (swap out) columns closely — consistently non-zero values mean the system is actively swapping.
Check swap configuration:
swapon --show
Check whether the OOM Killer has been active:
dmesg | grep -i oom
Seeing “Out of memory: Killed process” confirms something was sacrificed to keep the system alive.
Go deeper into memory internals:
cat /proc/meminfo
What to Investigate
- Memory leaks — usage climbs steadily and never comes back down
- Oversized Java heap settings
- Python processes with unbounded memory growth
- Docker containers with no memory limits set
- Heavy page/cache usage (often harmless — Linux reclaims this automatically when something else needs it)
How to Fix It
Kill the offending process:
kill -9 PID
Clear the page cache (rarely needed, but useful as an emergency valve):
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
Treat this as temporary relief, not a fix — the cache refills quickly, and clearing it can briefly make things slower rather than faster.
Add swap space in a pinch:
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Preventing It From Happening Again
- Set up ongoing RAM monitoring, not just reactive checks
- Configure memory limits on apps and containers so one process can’t take everything down
- Tune JVM heap sizes properly instead of relying on defaults
- Right-size containers based on real usage
- Upgrade RAM if the workload has genuinely outgrown the hardware
Real-World Example
Problem: An application crashed every night, like clockwork.
Investigation:
dmesgshowed the OOM Killer stepping in repeatedly.
Root cause: A Java memory leak — the heap kept growing until nothing was left.
Fix: Corrected the heap configuration. The nightly crashes stopped.
Part 3: Disk Full
What’s Actually Going On
This one’s the most abrupt of the three: once a disk or partition fills up completely, Linux simply can’t write anything new to it — no log entries, no database writes, no temp files.
Symptoms to Watch For
- “No space left on device” errors
- Logs silently stop updating
- Databases crash or refuse to start
- Applications fail in ways that don’t obviously point to disk
How to Diagnose It
Check overall disk usage:
df -h
Find what’s eating space, directory by directory:
du -sh /*
Zoom into the usual suspect — /var is a very common offender:
du -sh /var/* | sort -hr
See all disk devices and partitions:
lsblk
Check disk I/O, not just space:
iostat -xh 1
Don’t forget inodes — you can run out of these with plenty of free space left, if you have millions of tiny files:
df -i
Find “phantom” space usage from deleted-but-still-open files:
lsof | grep deleted
A sneaky one: a file gets deleted, but a running process still has it open, so the space never actually frees up until that process closes or restarts.
Common Causes
- Runaway log files
- Old Docker images and unused containers piling up
- Core dumps from crashed processes
- Backups that were never cleaned up
- Application or package caches
How to Fix It
Clean up old logs:
sudo journalctl --vacuum-time=7d
Force log rotation:
sudo logrotate -f /etc/logrotate.conf
Clear package manager cache:
# Debian/Ubuntu
sudo apt clean
# RHEL/CentOS
sudo yum clean all
Remove temporary files (double-check what’s actually safe to delete first):
rm -rf /tmp/*
Preventing It From Happening Again
- Set up proper
logrotateconfigs so logs never grow unchecked - Monitor disk usage continuously, not just when things break
- Clean up old backups on a schedule
- Set alerts well before 100% — 90% is already too late to react calmly
- Keep at least 20% of disk space free as a buffer
Real-World Example
Problem: MySQL suddenly stopped.
Investigation:
df -hshowed/varat 100% full.
Root cause: Old binary logs had piled up and were never cleaned.
Fix: Deleted the old binary logs. MySQL started right back up.
The Decision Flow
When a server goes slow and you don’t know why yet, work through it in this order:
Server slow?
│
├─ High CPU? → top → find process → optimize or kill it
├─ High memory? → free -h + dmesg → free memory or add swap
└─ Disk full? → df -h + du -sh → clean up space
Nine times out of ten, top and df -h alone will point you to the right one of these three paths within the first minute.
Quick Reference Cheat Sheet
- CPU →
top,htop,ps aux --sort=-%cpu | head,mpstat,pidstat - Memory →
free -h,ps aux --sort=-%mem | head,vmstat 1,dmesg | grep -i oom - Disk space →
df -h,du -sh /*,df -i(inodes),lsof | grep deleted - Load →
uptime - Logs →
journalctl
More Commands Worth Knowing
CPU:
pgrep -f <process> # Find a process by name
nice -n 10 <command> # Start a process at low priority
renice -10 -p <PID> # Change priority of a running process
stress --cpu 4 # Simulate CPU load for testing
vmstat 1 # Quick system summary
Memory:
pmap -x <PID> # Memory map of a specific process
numastat # NUMA memory stats
cat /proc/<PID>/status # Detailed memory info for one process
sysctl vm.overcommit_memory # Check memory overcommit settings
journalctl -k | grep -i oom # OOM events from the kernel log
Disk:
find / -xdev -type f -size +1G -exec ls -lh {} \; 2>/dev/null # Find files over 1GB
ncdu / # Interactive disk usage explorer
watch -n 5 df -h # Live-refreshing disk usage
sudo tune2fs -l /dev/sda1 | grep "Inode count" # Inode details
sudo fstrim -av # Discard unused SSD blocks
Best Practices That Prevent 85% of These Incidents
- Set up continuous monitoring (Prometheus + Grafana, or Nagios) instead of relying on manual checks
- Configure alerts before resources hit critical thresholds, not after
- Schedule automatic log rotation and cleanup
- Review CPU, memory, and disk trends regularly — not just when something breaks
- Keep the kernel and software patched
- Load-test after major deployments or config changes
- Document recurring issues in a runbook so the next person isn’t starting from zero
- Automate health checks and capacity planning wherever you can
***🐧 Linux Server Configuration — Complete Administrator’s Guide (Beginner → Advanced → Production)***
***🏆 Ultimate DevOps & SRE Learning Hub (2026 Edition) — 100% Free, Real-World Knowledge***
🌟 Final Note
This single page is designed to be:
- 📌 Bookmarked
- 📌 Shared
- 📌 Used daily
Thank you for reading! 😊🚀
If you’re a Linux admin, DevOps engineer, cloud engineer, or SRE — this page is your personal technical library.
👏 If it helped you, clap & share 💬 Drop a comment if you want a topic-wise PDF or roadmap next
🐳Happy Learning & Troubleshooting!
메타데이터
- post_id
- df0325383df6
- slug
- linux-troubleshooting-made-simple-high-cpu-vs-high-memory-vs-disk-full-df0325383df6
- url
- https://medium.com/beyond-localhost/linux-troubleshooting-made-simple-high-cpu-vs-high-memory-vs-disk-full-df0325383df6
- canonical_url
- https://medium.com/beyond-localhost/linux-troubleshooting-made-simple-high-cpu-vs-high-memory-vs-disk-full-df0325383df6
- author_url
- https://medium.com/@tushar.jadhav29
- status
- ok
- fetched_at
- 2026-07-19 08:45:00