Skip to main content
GullySystem
A practical guide

Linux server running slow: how to find the cause

Ganesh HSStrategy and Technology, GullySystem
Practical advice · 4 min read

In this guide 6 sections
The short answer

Check in this order: load average and top for CPU, free for memory and swap, iostat for disk waits, df for full disks, then process and connection counts. Read the logs around the slow moment. Resize the server only when the numbers show real, steady demand.

Start with load and what is running

Log in over SSH and run uptime. Three load averages appear: one, five and fifteen minutes. Compare them with the number of CPU cores from nproc. A load of four on a four core machine is busy but healthy. A load of twenty is not.

Open top, or htop if installed. Press 1 to see each core. Look at the us, sy, wa and st values. High us means your programs are busy. High wa means they are waiting on the disk. High st means a shared host is taking your time.

Sort by CPU, then by memory. Write down the top three processes and their owners. A PHP-FPM pool, a Node worker or a PostgreSQL backend each tell a different story.

  • Load average against core count
  • us, sy, wa and st columns in top
  • Top three processes by CPU
  • Top three processes by memory

Check memory and swap

Run free -h. Ignore the free column, which looks scary on any healthy Linux box because the kernel uses spare memory for cache. Read available instead.

If available is tiny and swap used keeps growing, the machine is thrashing. Run vmstat 5 and watch si and so. Steady nonzero values mean pages are moving to and from disk all the time, and everything feels slow.

Check dmesg for lines mentioning the OOM killer. If it killed a database or an app worker, you have found a cause. Then compare the memory limit on each service with what the box really has.

Look at the disk

Run df -h first. A full root partition stops logging, breaks databases and slows everything. Then df -i, since running out of inodes looks the same. The usual culprits are old logs, core dumps, backups and uploads.

Run iostat -x 5. Look at await and %util for each device. High await with high utilisation means the disk cannot keep up. Use iotop to see which process is hammering it.

Find big directories with du -xh --max-depth=1, starting at the root and working down.

  • df -h for space
  • df -i for inodes
  • iostat -x for await and utilisation
  • iotop for the process responsible
  • du to find large folders

Find runaway processes and connection limits

A cron job that overlaps itself, a stuck backup script or a worker in an endless loop will show up in ps aux sorted by CPU. Check how long it has been running and what started it.

Connections cause slowness without high load. Run ss -s to count sockets, and check the open files limit with ulimit -n. A web server or PostgreSQL that hits its connection ceiling queues new requests while the CPU sits idle.

Read the logs from the slow window: journalctl --since, the Nginx error log, the database log. Look for timeouts, too many open files and upstream errors.

Decide between a fix and a bigger server

Resize when the same resource is near its limit for hours every day, and your software is already tuned. A queue of real users on a four core machine is a capacity problem.

Fix when the pressure comes from a bug, a missing index, a log that never rotates or a job scheduled at the wrong hour. A bigger server only delays those problems and raises the bill.

Tonight, record uptime, free, df and iostat output at a quiet time. A baseline makes the next slow day far easier to read.

Slow server triage card

A one page card with a numbered command list: uptime, top, free, vmstat, df, iostat, ps, ss and journalctl. Beside each command is a blank for the reading taken and a note on what a bad value looks like. A bottom block records the cause found, the fix and the date.

Open a blank worksheet to print

Questions owners ask

What is a normal load average?

It depends on core count. A load near the number of cores means fully used. Values well above it, held for minutes, mean processes are queuing.

Why is free memory so low on a healthy server?

Linux uses spare memory as cache. Read the available column in free instead. Trouble shows as small available memory plus growing swap use.

How do I tell a disk problem from a CPU problem?

In top, a high wa value points to disk waits. Confirm with iostat -x, where high await and utilisation on one device show the bottleneck.

When should I add more RAM or cores?

When the same resource stays near its limit through normal working hours and the software has been checked for leaks, bad queries and runaway jobs.

Browse all guidesBack to top ↑
Next step

Have a specific situation to work through?

This article covers the general case. Tell us what you’re actually dealing with and we’ll respond directly.

Share Your Requirements