Every time you SSH into a Linux VPS for the first time after something has gone strange, you reach for roughly the same dozen commands. This article is a compact, copy-pasteable cheatsheet of those commands — what they show, when to use them, and how to install whatever isn't already there. Install lines are grouped by distribution family in tabs (Ubuntu/Debian on top by default, then RHEL/Rocky/AlmaLinux/CentOS), so you don't need to remember which package manager applies.
1. Are you on the right machine?
Sounds silly, but the most common Sev-1 mistake is running a destructive command on the wrong server. Confirm before you act:
hostname # short hostname
hostname -f # FQDN
hostnamectl # hostname + OS + kernel + virtualization in one shot
ip -4 addr # which IPs does this box have
whoami; id # who am I and what groups
who; w # who else is logged in right now
last | head -10 # recent logins (catch unexpected sessions)2. System / OS info
cat /etc/os-release # distribution + version
uname -a # kernel version + architecture
uptime # uptime + load avg (1, 5, 15 min)
lsb_release -a 2>/dev/null # may need: apt install lsb-release
lscpu # CPU model, sockets, cores, threads
nproc # number of logical CPUs
free -h # RAM + swap, human-readable
lsblk # block devices and mount points
df -h # filesystem usageRead the load average from `uptime` against `nproc`. Load of 4.0 on a 4-core box = fully busy but not overloaded; load of 12 on a 4-core box = serious queue, things are waiting on CPU.
3. CPU & memory in real time
`top` is everywhere; `htop` is what you actually want. Big colored display, sortable by column, shows process tree.
sudo apt update && sudo apt install -y htophtop # interactive process viewer (q to quit, F6 to sort)
top -c # built-in alternative, no install
free -h # quick RAM snapshot
vmstat 1 5 # 5 samples of CPU/IO/swap, 1 second apart
ps auxf | head -30 # process tree, top 30 by output order
ps -eo pid,user,rss,%mem,%cpu,cmd --sort=-rss | head -10 # top 10 by RAMIf something is hammering the box, `vmstat 1 5` will tell you whether it's CPU (`us`/`sy` columns high), IO (`wa` high), or swap thrashing (`si`/`so` non-zero). Three samples is usually enough to spot the pattern.
4. Disk — space, IO, health
df -h # filesystem free space (human)
df -i # inodes free (separate from bytes!)
lsblk -f # block devices + filesystems + UUIDs
sudo du -sh /var/log/* | sort -h # what's eating /var/log
sudo du -sh /* 2>/dev/null | sort -h # top-level / breakdown
iostat -xz 1 5 # disk IO per second (needs sysstat)
sudo lsof +L1 # files opened but already deleted (frees space when killed)Quick sequential disk speed check (no install needed):
# Sequential write (creates a 1 GiB file in /tmp, then deletes it):
dd if=/dev/zero of=/tmp/diskbench bs=1M count=1024 oflag=direct status=progress
rm /tmp/diskbench
# Sequential read:
sudo hdparm -Tt /dev/sda # cached + uncached read speed (Debian/Ubuntu has it preinstalled)For proper IOPS / mixed workload tests, install `fio`:
sudo apt install -y fio# 4K random read+write, 30 seconds, 4 jobs (a realistic-ish DB workload):
fio --name=mix --rw=randrw --rwmixread=70 --bs=4k --size=1G \
--numjobs=4 --runtime=30 --time_based --group_reporting --direct=1For SMART data on bare-metal servers (note: usually unavailable inside virtualised VMs):
sudo apt install -y smartmontoolssudo smartctl -a /dev/sda # full SMART report
sudo smartctl -H /dev/sda # health summary only (PASSED / FAILED)5. Network — basic reachability
Two directions, two questions: can the server reach the world, and can the world reach the server.
# FROM the server outward:
ping -c 4 8.8.8.8 # IPv4 reachability + RTT to Google DNS
ping -c 4 -6 2606:4700:4700::1111 # IPv6 to Cloudflare
ping -c 4 your-domain.com # DNS + RTT in one shot
curl -I https://www.google.com # HTTPS reachability + headers# FROM your laptop TOWARD the server (run on your laptop, not on the server):
ping <server-ip>
curl -v http://<server-ip>:<port>6. Network — traceroute & MTR
`traceroute` shows you the hops between you and the destination once. `mtr` runs traceroute in a loop and shows you packet loss per hop in real time — much more useful for diagnosing network issues.
sudo apt install -y mtr-tiny traceroutetraceroute -n 8.8.8.8 # path, no DNS lookups (faster)
mtr 8.8.8.8 # interactive (q to quit)
mtr -rwbzc 100 8.8.8.8 # report mode: 100 packets, wide, both ASN+IPIn `mtr` output, focus on the Loss% column. Loss only on intermediate hops with 0% loss at the destination = those routers de-prioritise ICMP, not real packet loss. Sustained loss at the final hop or growing loss across the last few hops = real problem somewhere on the path.
7. Network — speed tests
Two tools, two purposes. `speedtest` (Ookla CLI) measures against the public internet. `iperf3` measures between two machines you control — much more useful for figuring out whether the path is the bottleneck.
Install Ookla speedtest CLI:
curl -s https://packagecloud.io/install/repositories/ookla/speedtest-cli/script.deb.sh | sudo bash
sudo apt install -y speedtestspeedtest --servers | head -20 # find a server in the same city
speedtest --server-id=<id-near-the-DC> # use a specific local server
speedtest --format=json | jq '.download.bandwidth' # scriptableInstall iperf3 on both machines you want to test between:
sudo apt install -y iperf3# On machine A (server):
iperf3 -s
# On machine B (client):
iperf3 -c <A-ip> -t 30 # 30 second test
iperf3 -c <A-ip> -P 4 -t 30 # 4 parallel streams (more realistic)
iperf3 -c <A-ip> -R # reverse direction (download)
iperf3 -c <A-ip> -u -b 100M # UDP test at 100 Mbps target(Why this matters and what speedtest results actually mean is covered in the internet speed article.)
8. Network — what's listening, what's connected
ss -tlnp # all TCP listeners + process names
ss -ulnp # all UDP listeners
ss -tnp state established # currently established TCP connections
ss -s # summary counts (TCP, UDP, sockets)
sudo lsof -iTCP -sTCP:LISTEN -P # alternative listener view, no name resolution
ss -tnp dport = :443 # connections going to remote port 443(For a deeper dive on "why my port shows as closed from outside" see the firewall and ports article.)
9. Network — firewall rules
Several firewall layers may be active at once. Check them all:
# ufw (Ubuntu/Debian default)
sudo ufw status verbose
# firewalld (RHEL family default)
sudo systemctl is-active firewalld
sudo firewall-cmd --list-all
# Always check iptables/nftables directly — these are what the kernel actually applies
sudo iptables -L -n -v
sudo ip6tables -L -n -v
sudo nft list ruleset
# Docker rules (if you run containers)
sudo iptables -L DOCKER -n -v 2>/dev/null
sudo iptables -L DOCKER-USER -n -v 2>/dev/null10. DNS lookups
Install `dig` and friends:
sudo apt install -y dnsutilsdig +short example.com # just the answer
dig example.com A # with full record
dig example.com MX +short # mail servers
dig example.com NS +short # authoritative nameservers
dig +trace example.com # follow delegation from root
dig @8.8.8.8 example.com # query a specific resolver
host -t A example.com # alternative
nslookup example.com # alternative
getent hosts example.com # uses the OS resolver (matches what your apps see)
resolvectl status # systemd-resolved current state11. Processes & services
ps auxf | head -30 # process tree
pstree -p # cleaner tree view
pgrep -a nginx # find PIDs of nginx (with cmdline)
sudo systemctl status nginx # service status + last log lines
sudo systemctl list-units --type=service --state=running # all running services
sudo systemctl --failed # services that crashed
kill -TERM <pid> # polite kill (let process clean up)
kill -KILL <pid> # forceful kill (last resort)12. Logs
Modern systems use `journalctl` (systemd journal). Older systems also write text logs in `/var/log/`. The text log file path differs by distro:
sudo tail -F /var/log/syslog # main system log
sudo tail -F /var/log/auth.log # SSH and authentication# journalctl works the same way on every modern distro:
sudo journalctl -xe # most recent, with explanations, jump to end
sudo journalctl -u nginx --since '1 hour ago'
sudo journalctl -u nginx -f # follow live (tail -f equivalent)
sudo journalctl -k -p err # kernel-level errors
sudo journalctl --disk-usage # how much space is the journal eating
sudo dmesg --time-format=iso | tail -50 # kernel ring buffer (drivers, OOM kills)13. Time & NTP
date # current local time
timedatectl # status + timezone + NTP sync state
chronyc tracking 2>/dev/null # if chrony is the NTP daemon
ntpq -p 2>/dev/null # if ntpd is the NTP daemon
sudo timedatectl set-timezone Europe/Berlin # change timezone if neededTime drift breaks TLS, breaks Kerberos, breaks distributed databases. Check this if you have weird "certificate not yet valid" or "clock skew" errors.
14. Quick health snapshot — one block to copy
When you SSH into a server you've never seen, this is what we usually paste first to get oriented in 30 seconds:
echo '== HOST =='; hostnamectl
echo; echo '== UPTIME / LOAD =='; uptime
echo; echo '== CPU =='; lscpu | grep -E 'Model name|^CPU\(s\)|MHz'
echo; echo '== RAM =='; free -h
echo; echo '== DISK =='; df -h --output=target,size,used,avail,pcent | grep -v tmpfs
echo; echo '== LISTENERS =='; sudo ss -tlnp
echo; echo '== FAILED SERVICES =='; sudo systemctl --failed --no-legend
echo; echo '== LAST 10 LOGINS =='; last -n 10Related: if your investigation points to network or port issues, the dedicated articles are open ports and firewalls, internet speed on a VPS, how shared 1 Gbps ports work, and why your VPS may show in the wrong country.
VPS from€1.99/ month
Unlimited traffic, a 1 Gbps port and NVMe storage. 12 locations across Europe & the US.