How to Safely Clean Up a Linux Server Without Breaking Services
Level: Intermediate (production systems)
Estimated time: ~30 minutes
Goal: Free up disk space on a Linux server by removing unused packages, old kernels, stale logs, and cached files - without taking down any running services.
This guide assumes SSH access to a production or production-like VPS. Do not run blindly on critical systems without snapshots.
Introduction
Over time, even a lightly-used VPS accumulates dead weight: orphaned packages, outdated kernels, gigabytes of unrotated logs, and leftover package cache. Left unchecked, a full disk will crash your web server, break your database writes, and fill your mail queue. This linux system cleanup guide walks you through how to clean up a Linux server safely - checking disk usage first, removing what is safe to remove, and verifying that your services survived the process. Every command here is safe to run on a live server without downtime.
What you will clean up
| Category | Examples | Typical savings |
|---|---|---|
| Unused packages & dependencies | Orphaned libs, replaced drivers | 100 MB - 2 GB |
| Old kernels | Previous kernel versions | 200 MB per kernel |
| Package cache | Downloaded .deb / .rpm files | 500 MB - 5 GB |
| Journal logs | systemd log archives | 100 MB - 10 GB |
| Rotated log files | /var/log/*.gz, *.1 | Varies |
Prerequisites
Before you begin, make sure the following conditions are met:
- Operating system: Ubuntu 24.04/26.04 LTS, Debian 13, or AlmaLinux 10
- Access: sudo or root access to the server via SSH
- Required knowledge: Confident use of the Linux terminal and basic command-line navigation
- Backup: Always take a snapshot or backup before bulk-removing packages on a production server. On INTROSERV, you can order a full backup directly from the Client Area.
This linux system cleanup guide covers both APT-based systems (Ubuntu, Debian) and DNF/YUM-based systems (AlmaLinux, RHEL). Commands that differ between families are shown separately. Commands that are identical on all systems are shown once.
Do not proceed if any of the following is true:
/partition is above 95% full - your system may already be failing writes. Fix the immediate cause first (find and delete a single large file manually).- Services are already down or behaving unexpectedly. Investigate the root cause before cleaning to avoid breaking services linux systems depend on.
- You have no backup or snapshot. Take one first - on INTROSERV this takes under 2 minutes from the Client Area.
Step 1: Check disk usage before you start
Risk level: LOW - Read-only commands only. Nothing is modified.
Never clean blindly. First, understand what is actually using space.
1.1 Check overall disk usage
Run df to check disk usage at the filesystem level:
df -h
Expected output:
Filesystem Size Used Avail Use% Mounted on /dev/vda1 40G 34G 3.8G 90% / tmpfs 1.0G 0 1.0G 0% /dev/shm
A / partition above 80% use is a warning sign. Above 95%, services will start failing.
1.2 Find the biggest space consumers
Use du to drill into directories. Start at the root and work down:
sudo du -h --max-depth=1 / 2>/dev/null | sort -rh | head -20
This shows the top 20 largest directories under /. Common culprits are /var/log, /var/cache, /usr, and /home.
Narrow it down further:
sudo du -h --max-depth=1 /var/log | sort -rh | head -10
1.3 Check inode usage
Disk space is not the only limit. Inodes track the number of files. A partition can have free space but run out of inodes, which will also cause writes to fail.
df -i
Expected output:
Filesystem Inodes IUsed IFree IUse% Mounted on /dev/vda1 2621440 210543 2410897 9% /
If IUse% is above 80%, you likely have a directory with tens of thousands of small files - often a mail queue, a session directory, or a PHP cache. Use du --inodes to find it:
sudo du --inodes -h --max-depth=2 /var | sort -rh | head -10
You should check disk usage linux systems show before proceeding. On INTROSERV KVM VPS plans, disk quotas are enforced at both the block and inode level. Running out of either will cause the same symptom: writes silently fail or services report "no space left on device."
Step 2: Remove unused packages and dependencies
Risk level: MEDIUM - Package removal is reversible via package manager history, but review the list before confirming.
Unused packages are the safest thing to clean. They sit on disk, serve no running process, and in some cases carry unpatched CVEs.
2.1 Ubuntu / Debian - apt autoremove
apt autoremove removes packages that were installed as dependencies but are no longer needed by anything:
sudo apt autoremove --purge -y
The --purge flag also removes leftover configuration files. Without it, the package binary is gone but config files stay in place.
Expected output:
The following packages will be REMOVED: libfoo1 libbar2 old-driver-utils ... 0 upgraded, 0 newly installed, 8 to remove and 0 not upgraded.
apt autoremove is the safest way to remove unused packages linux dependency managers know are orphaned. It does not remove packages you installed manually that you no longer use. Those require manual review with apt list --installed.
2.2 AlmaLinux / RHEL - dnf autoremove
sudo dnf autoremove -y
On older RHEL 7 / CentOS 7 systems, use yum autoremove:
sudo yum autoremove -y
On RHEL-family systems, dnf autoremove and yum autoremove are more aggressive than their Debian counterparts. They may propose removing packages that appear unused by the dependency graph but are still needed by your application. Review the removal list carefully before confirming.
2.3 Clean the package cache
After updates and installations, package managers store downloaded archive files locally. They are safe to delete after installation is complete.
Ubuntu / Debian:
sudo apt clean
This removes all cached .deb files from /var/cache/apt/archives/. To remove only packages that are no longer available in the repository (superseded versions):
sudo apt autoclean
AlmaLinux / RHEL:
sudo dnf clean all
Expected output:
16 files removed
apt clean is always safe. It only removes the download cache. If you later need to reinstall a package, it will be re-downloaded from the repository.
Step 3: Delete old kernels
Risk level: HIGH - Removing the wrong kernel leaves the server unbootable after the next reboot. Always verify uname -r before proceeding.
Every kernel update leaves the previous version in place as a safety net. After confirming your server is stable on the new kernel, old kernels are safe to remove - each one typically frees 200-400 MB.
3.1 Check which kernel is running
Never remove the kernel you are currently booted into:
uname -r
Expected output:
5.15.0-105-generic
3.2 List all installed kernels
Ubuntu / Debian:
dpkg -l | grep linux-image | awk '{print $2}'
Expected output:
linux-image-5.15.0-100-generic linux-image-5.15.0-105-generic linux-image-generic
The meta-package must not be removed - it tracks the current recommended kernel:
- Ubuntu:
linux-image-generic - Debian:
linux-image-amd64 - AlmaLinux: No meta-package is used, it relies on
installonly_limitindnf.
Only remove specific versioned packages that are not your current kernel.
AlmaLinux / RHEL:
rpm -q kernel
Expected output:
kernel-5.14.0-284.11.1.el9_2.x86_64 kernel-5.14.0-362.8.1.el9_3.x86_64
3.3 Remove old kernels
Ubuntu / Debian - automatic method:
apt autoremove from Step 2 already handles old kernels on Ubuntu if linux-image-generic is installed. You can also target them explicitly. Replace the version with the one you want to remove (not the currently running one):
sudo apt remove --purge linux-image-5.15.0-100-generic -y
AlmaLinux / RHEL:
The dnf package manager keeps a configurable number of old kernels. Set the limit in /etc/dnf/dnf.conf:
sudo nano /etc/dnf/dnf.conf
Add or update the line:
installonly_limit=2
Then run:
sudo dnf remove $(dnf repoquery --installonly --latest-limit=-1 -q)
This removes all but the two most recent kernels.
Confirm uname -r matches one of the kernels you are keeping before you delete old kernels linux servers still need. Removing the active kernel will not break the running system, but you will have nothing to boot into after the next reboot.
Step 4: Clean up journal logs
Risk level: LOW - Removes archived log entries only. Running services are not affected.
systemd-journald collects logs from every service on the system. By default, it can grow without bound until it hits a disk limit - or your disk limit hits zero.
4.1 Check current journal size
journalctl --disk-usage
Expected output:
Archived and active journals take up 2.3G in the filesystem.
4.2 Trim the journal
To keep only the last 7 days of logs:
sudo journalctl --vacuum-time=7d
To keep only the last 500 MB:
sudo journalctl --vacuum-size=500M
Expected output:
Deleted archived journal /var/log/journal/.../[email protected] (64.0M). Vacuuming done, freed 1.8G of archived journals from /var/log/journal/.
4.3 Prevent future journal growth
Create a drop-in configuration file to cap the journal permanently (on AlmaLinux 10, the main config is not present in /etc/ by default anyway, making this the standard approach):
sudo mkdir -p /etc/systemd/journald.conf.d sudo tee /etc/systemd/journald.conf.d/99-size.conf <<EOF [Journal] SystemMaxUse=500M MaxRetentionSec=30day EOF
Apply the change:
sudo systemctl restart systemd-journald
During journal logs cleanup linux systems do not affect application logs in /var/log/ - those are managed by logrotate. The journal only covers systemd-native services that write to the journal directly (like sshd, nginx when using the systemd unit, cron, etc.).
Step 5: Clean rotated and old log files
Risk level: MEDIUM - Only compressed archives are deleted. Do not touch files without a .gz extension or numeric suffix.
Application logs in /var/log/ are managed by logrotate. Normally, logrotate keeps a set number of rotated copies and compresses them automatically. If logrotate was misconfigured or not running, you may find large accumulations of .gz, .1, .2 files.
5.1 Find large log files
find /var/log -type f -name "*.gz" -o -name "*.log" | xargs du -sh 2>/dev/null | sort -rh | head -20
Or more simply:
sudo du -h /var/log | sort -rh | head -20
5.2 Delete old compressed log archives
Compressed rotated logs (.gz) are safe to delete. They are archives of already-closed log files.
First, preview what will be removed - run without -delete to see the list:
sudo find /var/log -name "*.gz" -mtime +30
If the output looks correct, run the actual deletion:
sudo find /var/log -name "*.gz" -mtime +30 -delete
This deletes .gz log archives older than 30 days.
Do not delete actively written log files - those without a rotation suffix or .gz extension. Deleting /var/log/nginx/access.log while nginx is running does not stop nginx from writing to the now-deleted inode. The space is not freed until nginx is reloaded. Instead, truncate it safely: sudo truncate -s 0 /var/log/nginx/access.log.
5.3 Verify logrotate is configured correctly
Check which services have logrotate configurations:
ls /etc/logrotate.d/
Run logrotate manually in debug mode to confirm it is working without errors:
sudo logrotate -d /etc/logrotate.conf
The -d flag is a dry run - nothing is changed, but you will see exactly what would happen. If a service is missing from /etc/logrotate.d/, create a configuration for it. See the Log Rotation guide for full logrotate configuration instructions.
Step 6: Clear temporary files
Risk level: MEDIUM - PHP sessions and application caches affect live users. Preview before deleting.
6.1 Clean /tmp
/tmp is cleared on reboot by most distributions. If your server has been running for months, it may have accumulated large temporary files:
du -sh /tmp
To remove files older than 7 days, preview first:
sudo find /tmp -type f -mtime +7
If the list looks safe, run the deletion:
sudo find /tmp -type f -mtime +7 -delete
6.2 Clean application caches
Many applications write their own caches. Check these common locations (note: verify these directories exist on your system, on a clean system they may not be present and you will see a 'No such file or directory' error):
# PHP session files (often forgotten, if installed) sudo du -sh /var/lib/php/sessions/ # Pip / Python package caches (if running as root and installed) sudo du -sh /root/.cache/pip/ # npm cache (if node is installed system-wide) sudo du -sh /root/.npm/
These directories are safe to purge if the application is not actively using them.
Before clearing an application cache, confirm the service is not mid-transaction. Clearing a PHP session directory while users are logged in will log everyone out.
Step 7: Verify services are still running
Risk level: LOW - Read-only verification. Run this after every step, not just at the end.
After every cleanup pass, confirm that your services survived. Do this before closing your SSH session.
7.1 Check critical service status
Check only the services that are actually installed on your server (on a clean system, checking nginx or mysql will return Unit not found).
Ubuntu / Debian:
systemctl status nginx systemctl status mysql systemctl status ssh
AlmaLinux / RHEL:
systemctl status nginx systemctl status mysqld systemctl status sshd
Each should show Active: active (running). If any shows failed or inactive, check its logs:
journalctl -u nginx --since "10 minutes ago"
7.2 Confirm disk usage improved
df -h
Compare the Use% column against what you saw in Step 1. The change should reflect the space you freed.
7.3 Test your application
If you run a web server, send a test request:
curl -I http://localhost
Expected output:
HTTP/1.1 200 OK Server: nginx/1.24.0
A 200 OK confirms nginx is serving traffic normally.
Troubleshooting
`df` shows no improvement after removing packages
Package removal frees space immediately. If df does not change, the files are still open. Find open-but-deleted files:
sudo lsof | grep deleted
Restart the service holding the file open and the space will be reclaimed.
`apt autoremove` wants to remove something that looks important
Read the list carefully. If you see a package name you recognize as a dependency of a running service, press N and investigate. Run apt-cache rdepends <package> to see what depends on it.
`journalctl --vacuum-time` makes no change
The journal may already be smaller than the target. Check with journalctl --disk-usage. Also confirm the journal is persistent: check that /var/log/journal/ exists. If only /run/log/journal/ exists, the journal is stored in RAM and clears on reboot automatically.
Service fails after `apt autoremove`
Run systemctl status <service> and check the error. If a shared library was removed, reinstall the package that provides it:
sudo apt install --fix-broken
Running out of inodes despite free disk space
Find the directory with the most files:
find / -xdev -printf '%h\n' 2>/dev/null | sort | uniq -c | sort -rn | head -10
Common culprits: mail queues in /var/spool/mail, PHP sessions in /var/lib/php/sessions, or a runaway cron job creating temp files.
Rollback
Most cleanup operations are not reversible - deleted files are gone. This makes the backup step in Prerequisites non-optional.
For package removal specifically, you can reinstall what was removed:
Ubuntu / Debian:
sudo apt install <package-name>
AlmaLinux / RHEL:
sudo dnf install <package-name>
To see a history of what was removed in the current session:
Ubuntu / Debian:
cat /var/log/dpkg.log | grep "^$(date +%Y-%m-%d)" | grep " remove "
AlmaLinux / RHEL:
sudo dnf history list sudo dnf history undo last
dnf history undo last reinstalls packages removed in the most recent transaction - a useful recovery tool if autoremove went further than intended.
Conclusion
A linux server cleanup without downtime comes down to three things: measure first, remove only what the system confirms is unused, and verify services after each step. Run df -h and du before you touch anything. Use apt autoremove / yum autoremove for unused packages, journalctl --vacuum-time for journal logs cleanup, and find /var/log -name "*.gz" for old rotated archives. Remove old kernels only after confirming uname -r matches what you are keeping. And always check systemctl status before you close the terminal.
For an INTROSERV VPS, keeping / below 80% use is a practical target - it leaves room for log bursts and package updates without emergency intervention. If disk space is a recurring problem, consider resizing your VPS storage directly from the INTROSERV Client Area.
Document Version: 1.0
Last Updated: May 2026
Owner: Technical Documentation Team