Why Is My Drupal Site Suddenly Using 100% CPU?
When a Drupal site suddenly starts consuming most or all of the available CPU, the obvious conclusion is that the website is receiving too much traffic.
Sometimes that is true.
But high CPU can come from several very different sources: PHP requests, database activity, cron, Drush commands, queue workers, bots, or a process that has simply got stuck.
We recently investigated a Drupal server where the load average had climbed above 20 and remained high for an extended period.
At first glance, it looked like a traffic problem.
It wasn't.
One long-running Drush process was consuming around 87% CPU and had been running for several hours.
That changed the investigation completely.
High CPU does not automatically mean high traffic
Drupal is a PHP application, so a busy site can certainly generate high CPU usage.
A sudden increase might be caused by:
- a spike in genuine visitors
- search-engine crawlers
- aggressive bots
- expensive Drupal Views
- PHP workers stuck on slow requests
- database queries
- cron
- queue processing
- scheduled Drush commands
- imports or exports
- background maintenance tasks
The important thing is not to guess which one it is.
First establish what process is actually consuming the CPU.
Start with the server, not Drupal
When a site becomes slow, it is tempting to start clearing caches, disabling modules or changing Drupal configuration.
That can easily send the investigation in the wrong direction.
The first useful question is much simpler:
What is using the CPU right now?
On a Linux server, tools such as top or htop will normally show this immediately.
In our case, the server load was very high, but one process stood out.
A Drush command was consuming roughly 87% CPU.
The command involved config-get, and it had been running for approximately four hours.
That is not normal behaviour for a simple configuration lookup.
Once that process was identified, the high server load suddenly made much more sense.
Look at the process list
The process list helps separate several very different problems.
If you see many PHP processes consuming CPU, the issue is more likely to be incoming web requests.
If MySQL or MariaDB dominates CPU usage, you may be dealing with expensive queries, missing indexes, large tables or heavy concurrent database activity.
If a Drush command is at the top, the problem may have nothing to do with front-end traffic at all.
Other things you might find include:
php
lsphp
php-fpm
mysqld
mariadbd
drush
cron
queue workers
backup processes
Composer commands
image or PDF generation processes
That distinction matters because each has a completely different remedy.
PHP workers: is Drupal processing too many requests?
If multiple PHP processes are consuming significant CPU, the next question is what they are doing.
This is where the web server access log becomes useful.
Look for:
- unusually high request volumes
- repeated requests to the same route
- large numbers of different query-string URLs
- bots pretending to be normal browsers
- expensive Views
- search endpoints
- AJAX requests
- uncached pages
- missing static files causing repeated Drupal requests
A high number of PHP workers often points towards traffic, but even then the traffic itself is not necessarily the real problem.
A few expensive routes can be more damaging than thousands of cheap static requests.
Bots can still be involved
During the same broader investigation, we also found significant automated traffic hitting Drupal sites.
That matters because bots can create real server load, particularly when they request dynamically generated pages.
A crawler requesting a cached article is relatively inexpensive.
A crawler repeatedly requesting thousands of filtered Drupal Views can be very expensive.
So access logs still need checking even when another process initially looks suspicious.
There can be more than one contributing factor.
But it is important not to assume:
high CPU = bot attack
until the process list and access logs support that conclusion.
Drush can cause server load too
Drush is usually associated with short administrative commands:
- clearing caches
- running cron
- applying database updates
- importing configuration
- inspecting Drupal configuration
Most of those commands should finish relatively quickly.
A Drush process that has been running for hours deserves investigation.
Possible reasons include:
- a command waiting on another process
- database locking
- a script repeatedly invoking Drush
- cron repeatedly launching commands
- a shell or deployment process that has gone wrong
- a module hook performing unexpectedly expensive work
- a process that has simply become stuck
In our case, spotting the duration of the Drush process was as important as seeing its CPU consumption.
A command consuming 80% CPU for three seconds is unremarkable.
A command consuming 80% CPU for four hours is not.
Check how long the process has been running
CPU percentage only tells part of the story.
Process age is another useful diagnostic.
If a Drupal server suddenly becomes overloaded, ask:
Did these processes start a few seconds ago, or have they been running for hours?
Long-running PHP or Drush processes can point towards:
- hung operations
- runaway scripts
- external services timing out
- database waits
- locking
- loops
- broken cron jobs
That is a very different problem from a temporary burst of legitimate traffic.
Don't forget cron
Drupal cron can trigger a surprising amount of work.
Modules may use cron to:
- clean cache tables
- process queues
- send email
- update search indexes
- fetch external data
- remove expired data
- perform maintenance
- generate files
A site that is perfectly responsive most of the time but suddenly spikes every hour may therefore have a scheduled-job problem rather than a traffic problem.
Check both Drupal cron and system-level cron jobs.
Also check whether cron is accidentally being invoked from several places.
For example, a site might have:
- Drupal's automated cron
- a server cron job
- a hosting control-panel cron
- an external uptime service triggering cron
Multiple mechanisms doing the same work can create unexpected load.
Database CPU is a different investigation
If the database server is consuming most of the CPU, restarting PHP or blocking bots may not solve anything.
You need to investigate database activity.
Useful questions include:
- Which queries are running?
- Are queries taking unusually long?
- Is one Drupal View responsible?
- Are cache tables unusually large?
- Are temporary tables being created heavily?
- Are database indexes missing?
- Is a module repeatedly performing expensive queries?
Drupal can appear to be the cause because Drupal initiated the query, but the bottleneck may actually be inside the database.
Load average and CPU percentage are not the same thing
Another common source of confusion is the Linux load average.
A load average of 20 does not literally mean the CPU is running at 20 times capacity.
Load represents processes that are running or waiting for resources.
The significance depends partly on the number of CPU cores.
A load of 4 on a four-core server may be manageable.
A sustained load of 20 on the same machine suggests serious contention.
It is therefore useful to look at:
- CPU utilisation
- load average
- process count
- memory
- swap
- I/O wait
rather than relying on one number.
Clearing Drupal caches is not a diagnosis
Clearing caches is often one of the first responses to a slow Drupal site.
Sometimes it helps.
Sometimes it makes things temporarily worse because Drupal then has to rebuild everything.
More importantly, clearing caches tells you very little about the cause of high CPU.
If a runaway Drush process is consuming 87% CPU, clearing Drupal's cache does not fix it.
If bots are hammering an expensive View, clearing the cache does not stop them.
If MySQL is executing an expensive query, clearing caches may simply cause Drupal to execute it again.
Cache clearing is a maintenance action.
It should not replace diagnosis.
A practical order for investigating high Drupal CPU
When a Drupal server suddenly becomes overloaded, we generally work through the problem in this order.
1. Check CPU and load
Confirm that the server really is under sustained load rather than experiencing a brief spike.
2. Identify the highest-consuming processes
Use the process list to determine whether the load is coming from PHP, MySQL, Drush, cron or something else.
3. Check process age
A process that has been running for hours can be much more revealing than one that has just started.
4. If PHP is responsible, inspect the access logs
Find out which URLs are being requested and by whom.
5. If the database is responsible, inspect database activity
Look for long-running or repetitive queries.
6. Check cron and scheduled commands
Establish whether the problem appears at regular intervals or whether a scheduled process has become stuck.
7. Only then start changing Drupal
Once the source is known, you can decide whether the solution belongs in:
- Drupal
- the database
- PHP
- the web server
- Cloudflare
- cron
- Drush
- server configuration
That prevents a lot of unnecessary changes.
The process consuming the CPU is the clue
The useful lesson from this incident was simple.
A Drupal server was showing very high load, and there were several plausible explanations.
Traffic looked suspicious.
Bots were present.
PHP processes were running.
But the single most important clue was sitting in the operating system's process list: a Drush command consuming most of a CPU core for hours.
Drupal performance problems are often approached from the top down — starting with the website and working towards the server.
For sudden CPU problems, it is frequently better to work in the opposite direction.
Start with the server.
Find out what is consuming the resources.
Then work backwards to discover why.
Because “Drupal is using 100% CPU” is not really a diagnosis at all.