A slow Linux server does not always need more CPU cores, additional RAM or faster storage. In many cases, the real problem lies elsewhere: a saturated processor, memory pressure, overloaded disks, network issues, restrictive resource limits or an application waiting on a slow dependency. The key is to identify what is actually holding the system back before changing its configuration or spending money on new hardware.

The key signs of Linux server performance issues in 30 seconds

  • CPU saturation: A growing run queue can indicate that processes are competing for processor time.
  • Memory pressure: Heavy swapping and rising memory pressure can cause slowdowns even when the server remains online.
  • Storage bottlenecks: High I/O latency can leave applications waiting for disk operations.
  • Network problems: Retransmissions, packet drops and connection limits can affect response times.
  • Resource limits: File descriptors, container quotas and cgroup restrictions can constrain individual services.
  • Application latency: Slow database queries, DNS lookups or external APIs can delay requests even when the server itself appears healthy.

1. CPU saturation: when processes compete for processor time

CPU usage is one of the first metrics administrators check when a Linux server becomes slow. However, high CPU utilisation alone does not prove that the processor is the bottleneck. A server can run at high utilisation and still respond well if its workload is predictable and its queues remain under control.

A useful starting point is:

vmstat 1

The command reports system activity at one-second intervals. Pay particular attention to the r column, which indicates the number of runnable processes waiting for CPU time or running on a processor.

If the run queue remains consistently above the number of available CPU cores, the system may be struggling to keep up with demand. That is a signal to investigate, not an automatic diagnosis: the type of workload and the duration of the condition also matter.

To identify which processes are consuming CPU time, use:

top

For more detailed per-process statistics, pidstat can help:

pidstat -u 1

The mpstat command can also reveal whether CPU activity is distributed evenly across processors:

mpstat -P ALL 1

This distinction matters on servers running databases, web services or background jobs. A single busy process or an unevenly distributed workload may be more relevant than the overall CPU percentage.

Before adding more vCPUs, check whether a particular process, scheduled task or application request is responsible for the load. More CPU capacity can help when the workload genuinely needs it, but it will not fix inefficient code or an unexpected loop.

2. Memory pressure: when available RAM is not enough

Memory problems can be harder to recognise than CPU saturation. A server may remain operational while applications become progressively slower because the kernel has to reclaim memory or move pages between RAM and swap.

Start with:

free -m

The available column is generally more useful than the amount of memory shown as free. Linux uses otherwise unused RAM for caches, which can be released when applications need memory.

Next, examine memory and swap activity:

vmstat 1

In the output, si and so represent memory swapped in and out. Sustained swap activity can indicate memory pressure, especially when it coincides with application latency. Swap usage by itself does not necessarily mean the server is unhealthy, because inactive pages can remain in swap without causing a current performance problem.

For a closer look at memory pressure, Linux exposes Pressure Stall Information (PSI):

cat /proc/pressure/memory

PSI reports how much time tasks spend stalled because of memory-resource contention. It can help distinguish a server with little free RAM but acceptable performance from one where memory pressure is actively delaying work.

Also check for processes terminated by the Out-Of-Memory (OOM) killer and for container memory limits. A service can run out of its allocated memory even when the host still has RAM available.

Useful checks include:

dmesg -T | grep -i -E 'out of memory|killed process'Code language: JavaScript (javascript)

If memory pressure is confirmed, identify the processes consuming RAM and determine whether usage is expected. Increasing memory may be appropriate, but a leak, an oversized cache or an incorrectly configured container limit may be the underlying cause.

3. Storage bottlenecks: when applications wait for disks

A server can have plenty of CPU capacity and sufficient RAM but still feel slow because storage operations take too long. This is common with databases, virtual machines, logging systems and workloads that read or write many small files.

The iostat utility, provided by the sysstat package on many distributions, reports CPU and storage statistics:

iostat -xz 1

Several fields are worth examining:

  • await: Average time, in milliseconds, for I/O requests to be completed, including time spent waiting in the queue.
  • aqu-sz: Average queue length for outstanding I/O requests.
  • %util: The proportion of time a device was busy handling I/O.

These values need to be interpreted together. High latency and a growing queue under sustained load are stronger evidence of a storage bottleneck than one metric in isolation. The meaning of %util also depends on the device: for modern SSDs and devices capable of handling multiple requests concurrently, a value close to 100% does not always mean that throughput cannot increase further.

For example, a database may respond slowly because its queries trigger frequent reads from storage. A logging service may create a burst of writes that competes with application data. In both cases, the storage metrics can help establish whether I/O is contributing to the delay.

The next step is to identify which process is generating the activity and whether the pattern is expected. Depending on the workload, the solution might involve reducing unnecessary disk access, reviewing database queries, adjusting caching or changing the storage configuration.

Buying faster storage without identifying the source of the I/O can improve capacity while leaving the underlying inefficiency untouched.

4. Network problems: retransmissions, drops and connection pressure

Network problems do not always cause complete outages. A service can remain reachable while connections take longer to establish, requests need retransmission or packets are dropped under load.

Begin by checking interface statistics:

ip -s link

Look for increasing error and drop counters. A single non-zero value is not enough to establish a fault, so compare the counters over time and check whether they rise during the periods when users experience slow responses.

TCP connection information can provide further clues:

ss -ti

The output includes details about TCP connections, including retransmission and congestion-related information where available. System-wide network statistics can also be inspected with:

nstat

The goal is to determine whether the server is losing packets, retransmitting data or struggling to handle the number of connections. These symptoms can also originate outside the machine, so the results should be compared with network devices, load balancers and the remote service when possible.

Connection limits deserve attention too. A service may have a full listening queue, while a server under heavy connection churn may run into resource constraints. Inspect listening sockets with:

ss -lnt

For services that rely on connection tracking, the Linux connection-tracking table can also become a constraint. That possibility is particularly relevant to systems acting as routers, gateways or firewalls.

Network diagnosis should follow the evidence. Increasing bandwidth will not necessarily fix packet loss, a saturated connection table or a slow upstream dependency.

5. Process and container limits: when the operating system says no

Sometimes the host has enough CPU, memory and storage, but one application still cannot use the resources it needs. Linux limits, service configuration and container quotas can impose restrictions below the level of the whole machine.

One common example is the file descriptor limit. Linux uses file descriptors for open files, sockets and other resources. A service that reaches its limit may fail to accept new connections or open additional files.

Check the current shell’s limit with:

ulimit -n

For a running process, inspect its limits directly:

cat /proc/PID/limits

Replace PID with the process identifier. If the service is managed by systemd, its unit configuration may define a separate LimitNOFILE value. The shell’s ulimit output does not necessarily reflect the limits of a service launched by systemd.

Containers introduce another layer. A container can be restricted by CPU quotas or memory limits even if the host has unused capacity. On cgroup v2 systems, the following files can help identify relevant restrictions:

cat /sys/fs/cgroup/cpu.stat
cat /sys/fs/cgroup/memory.events

The exact paths depend on the cgroup hierarchy and the process’s location within it. For a container or service, inspect the corresponding cgroup rather than assuming the root-level files describe its limits.

CPU throttling counters can indicate that a workload is being restricted by its configured quota. Memory events can reveal conditions such as reaching a limit or triggering an out-of-memory event within a cgroup.

Before increasing limits, check why the service is approaching them. A file descriptor limit may be too low, but it can also expose a connection leak. Raising a container’s memory allowance may help, although it will not necessarily fix uncontrolled memory growth.

6. Application latency: when the server is healthy but requests are slow

The final signal is the one most likely to be missed by monitoring that focuses exclusively on infrastructure. A server can show normal CPU utilisation, acceptable memory usage and healthy storage metrics while users still experience slow responses.

The reason may be inside the application or in a service it depends on. Examples include a slow database query, a delayed DNS lookup, an overloaded authentication service or an external application programming interface (API) that takes too long to respond.

Google’s Site Reliability Engineering guidance recommends monitoring latency, traffic, errors and saturation, often referred to as the four golden signals. Latency measures how long a request takes to complete, making it a useful complement to operating-system metrics.

A simple first check for an HTTP endpoint is:

curl -o /dev/null -s -w \
'DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nFirst byte: %{time_starttransfer}s\nTotal: %{time_total}s\n' \
https://example.comCode language: JavaScript (javascript)

Replace the example address with the service being tested. The output breaks down several stages of the request, including name resolution, connection establishment, time to first byte and total elapsed time. The measurements can help narrow down where the delay occurs, although one request is not enough to establish a consistent pattern.

For production services, monitor latency distributions rather than relying only on averages. The 95th percentile (P95) represents a response time at or below which 95% of the measured requests completed. The 99th percentile (P99) provides a view of slower requests that can disappear inside an otherwise healthy average.

Compare those measurements with request volume and error rates. If latency rises at the same time as traffic, the service may be reaching a capacity limit. If only requests involving a particular database or external API slow down, that dependency deserves closer inspection.

The best diagnosis combines application-level measurements with infrastructure metrics. That approach helps distinguish a server that lacks capacity from one that is waiting on another component.

How to use the six signals together

No single metric explains every slowdown. The most reliable approach is to collect measurements during the period when the problem occurs and compare them with a known healthy baseline.

SignalFirst tool to checkWhat to investigate
CPUvmstat 1, topRun queue, busy processes and CPU distribution
Memoryfree -m, /proc/pressure/memorySwap activity, memory pressure and OOM events
Storageiostat -xz 1I/O latency, queue depth and sustained device load
Networkip -s link, ss -tiDrops, retransmissions and connection pressure
Resource limits/proc/PID/limits, cgroup filesFile descriptors, CPU throttling and memory limits
Application latencycurl -w, application metricsDNS, connection setup, time to first byte and slow dependencies

The sequence matters less than collecting evidence before changing configuration. If the CPU is saturated, identify the workload. If memory pressure is high, find the processes responsible. If storage latency rises, establish which operations are generating I/O. If the host appears healthy but requests remain slow, follow the request through the application and its dependencies.

That method reduces guesswork and makes it easier to verify whether a change actually improves performance.

Frequently asked questions

How can CPU bottlenecks be identified on a Linux server?

Use vmstat 1 to inspect the run queue and top or pidstat -u 1 to identify CPU-intensive processes. Persistent queue growth alongside high CPU demand can indicate contention.

Does using swap mean a Linux server needs more RAM?

Not necessarily. Swap usage can persist without causing a current performance problem. Sustained swap activity combined with memory pressure and slow applications is a stronger reason to investigate RAM capacity or excessive memory consumption.

Which Linux command helps diagnose slow disks?

iostat -xz 1 reports storage metrics such as average I/O latency, queue depth and device utilisation. Interpret these values together and compare them with the workload and a healthy baseline.

Why is an application slow when CPU and memory look normal?

The application may be waiting on a database, DNS, a network connection or an external API. Request latency measurements and dependency-level monitoring can help locate the delay.

Scroll to Top