Is Your Server Slow? Diagnosing Performance Problems in 10 Minutes
09:00 in the morning, the phone rings: "The site won't open — what happened?" It is one of the calls we get most often. The customer is panicking; we are calm. Because we have seen the same scenario hundreds of times over 14 years. Most of the time it is diagnosed in 10 minutes and solved in 30. In this article we explain how to diagnose server slowdowns, which commands to use and how to solve the 10 most common problems. You can follow along even without technical knowledge.
The First 60 Seconds: Quick Diagnosis
You have connected to the server over SSH. The first things to do:
# 1. Check the load average (1-5-15 minute averages)
uptime
# Output: load average: 2.50, 1.80, 1.20
# Rule: if it is higher than the number of CPUs, there is a problem
# 2. Memory status
free -h
# Look at the Available column; below 10% is a problem
# 3. Disk usage
df -h
# 95%+ full is critical
# 4. The processes using the most resources
top
# Shift+P: Sort by CPU
# Shift+M: Sort by RAM
60-Second Diagnosis Results:
- High load average: A CPU problem (go on to Step 1)
- Low available memory: A RAM problem (Step 2)
- Disk 95%+ full: A disk problem (Step 3)
- Everything normal: A network problem (Step 4)
Problem 1: High CPU Usage
Symptoms:
- Load average > number of CPUs
- Processes using 100% CPU in top
- The site is slow but has not crashed
Diagnostic Commands:
# The 10 processes using the most CPU
ps aux --sort=-%cpu | head -11
# How much each user is using
ps aux | awk '{cpu[$1]+=$3} END {for (user in cpu) print user, cpu[user]}'
# Real-time CPU monitoring (htop is better)
htop
# Sort by CPU with F6
Common Causes and Solutions:
1. Too many PHP-FPM or Apache processes
# Check the number of PHP-FPM processes
ps aux | grep php-fpm | wc -l
# Solution: lower the pm.max_children value
nano /etc/php/8.2/fpm/pool.d/www.conf
pm.max_children = 20 # lower from 50 to 20
systemctl restart php8.2-fpm
2. Slow MySQL queries
# Find slow queries
mysql -e "SHOW FULL PROCESSLIST;" | grep -v Sleep
# Enable the slow query log
nano /etc/mysql/my.cnf
slow_query_log = 1
long_query_time = 2
# Inspect the log
tail -f /var/log/mysql/slow.log
3. A cron job stuck in an infinite loop
# Check running crons
ps aux | grep cron
# Kill a specific script
pkill -f backup.sh
Problem 2: RAM Full (Out of Memory)
Symptoms:
- Available < 500 MB in free -h
- High swap usage
- Processes are killed at random (OOM Killer)
# Detailed memory status
free -h
# total used free shared buff/cache available
# Mem: 16Gi 12Gi 200Mi 500Mi 3.8Gi 2.5Gi
# Swap: 8Gi 6Gi 2Gi
# The 10 processes using the most RAM
ps aux --sort=-%mem | head -11
# OOM Killer logs
dmesg | grep -i "killed process"
Emergency Fixes:
1. Clear the cache (temporary fix)
# Clear PageCache, dentries, inodes
sync; echo 3 > /proc/sys/vm/drop_caches
# Check the result
free -h
2. Restart the service with the memory leak
# Example: if Apache is using 8 GB
systemctl restart apache2
# PHP-FPM
systemctl restart php8.2-fpm
3. Shrink the MySQL buffer pool
# /etc/mysql/my.cnf
innodb_buffer_pool_size = 2G # lower from 8G to 2G
systemctl restart mysql
A Real Case: A WordPress site was crashing 3 times a day. The cause: the WP Rocket cache plugin had piled up 12 GB of RAM. The problem was solved once the plugin was removed. Lesson: every plugin consumes RAM.
Problem 3: Disk Full
Symptoms:
- 95%+ usage in df -h
- "No space left on device" error
- Logs cannot be written, database lock
# Disk usage
df -h
# The largest directories (start from root)
du -h --max-depth=1 / | sort -rh | head -20
# The largest files in a specific directory
find /var/log -type f -exec du -h {} + | sort -rh | head -20
Common Causes:
1. Bloated log files
# Find the largest log files
find /var/log -type f -size +100M
# Safe cleanup (empty the file without deleting it)
> /var/log/apache2/access.log
> /var/log/mysql/error.log
# Delete old logs
find /var/log -type f -mtime +30 -delete
2. Backup files have piled up
# Delete backups older than 30 days
find /backup -type f -mtime +30 -name "*.tar.gz" -delete
3. Temp files not cleaned up
# /tmp cleanup
find /tmp -type f -atime +7 -delete
# PHP session files
find /var/lib/php/sessions -type f -mtime +7 -delete
Problem 4: High Disk I/O
Symptoms:
- The site is slow but CPU/RAM are normal
- "wa" (wait) is high in top
- Database queries hang
# I/O statistics (iostat may need to be installed)
apt install sysstat
iostat -x 1 5
# If %util > 80 there is a disk bottleneck
# Which process is using the disk (iotop must be installed)
apt install iotop
iotop -o
# -o: Only those doing active I/O
Solutions:
1. MySQL slow query problem
# Check for missing indexes
mysql -e "SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA='dbname' AND INDEX_LENGTH=0;"
# Turn on the query cache (MySQL 5.7)
query_cache_size = 64M
query_cache_type = 1
2. High swap usage (writing to disk)
# Reduce swappiness (prioritise RAM)
sysctl vm.swappiness=10
echo "vm.swappiness=10" >> /etc/sysctl.conf
Problem 5: Network Connection Problems
Symptoms:
- SSH connection is slow
- The site loads intermittently
- API requests time out
# Number of active connections
netstat -an | grep ESTABLISHED | wc -l
# Which IP has the most connections
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20
# Is it listening on port 80/443
netstat -tlnp | grep :80
netstat -tlnp | grep :443
Common Causes:
1. Under a DDoS attack
# SYN flood check
netstat -an | grep SYN | wc -l
# 1000+ means there is an attack
# Emergency fix: rate limiting
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
2. Slow DNS resolution
# DNS response time test
dig @8.8.8.8 sistemdc.com
# Check the query time
# Use an alternative DNS
nano /etc/resolv.conf
nameserver 8.8.8.8
nameserver 1.1.1.1
Problem 6: A Service Has Crashed
# Which services are running
systemctl list-units --type=service --state=running
# Apache status
systemctl status apache2
# Nginx status
systemctl status nginx
# MySQL status
systemctl status mysql
# Start a service
systemctl start apache2
# Error logs
journalctl -u apache2 -n 50
SistemDC 24/7 Monitoring and Response
Automatic monitoring is active on SistemDC servers:
- Uptime monitoring: Checked every 60 seconds
- Resource alerts: CPU > 90%, RAM < 10%, Disk > 90%
- 24/7 NOC: An engineer responds when an alarm comes in
- Automatic restart: Critical services are restarted automatically when they crash
Managed Support Package: With prices starting from 500 TL a month, we solve all performance problems for you. Focus on your business and leave the technical details to us.
Proactive Measures: Do Them Before Problems Arise
1. Set Up Monitoring
# Netdata installation (lightweight monitoring)
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# Access it at http://server-ip:19999
2. Automatic Backups
# Daily database backup
0 2 * * * mysqldump --all-databases > /backup/db-$(date +\%Y\%m\%d).sql
3. Log Rotation
# /etc/logrotate.d/apache2
/var/log/apache2/*.log {
daily
rotate 7
compress
delaycompress
missingok
}
Having a Server Problem?
Our technical team is at your service 24/7. If you need an emergency response, call right away.
Emergency Support:
satis@sistemdc.com
Corporate WhatsApp: +90 224 334 02 42
Conclusion: Quick Diagnosis, Quick Fix
80% of server performance problems fall into one of the 6 categories above. We have seen hundreds of problems in 14 years, and our experience is this:
- If you diagnose correctly in the first 60 seconds, you solve it in 10 minutes
- Without monitoring you stay reactive; you cannot be proactive
- Most problems can be prevented with small configuration changes
- Backups are a must; otherwise a mistake can turn into a disaster
Make a note of these commands. When you run into a problem, do not panic; take a systematic approach. If you cannot solve it, we are here.
Note: The commands in this article have been tested on Ubuntu 24.04 and Debian-based systems. Make sure you have a backup before making changes on a production server. On critical systems, try it in a test environment first.