Skip to content
CH SCShop classdrupal · intermediate · ~90 min · 6 steps

How to speed up a slow Drupal site

Find where a Drupal site actually spends its time — cache misses, heavy views, unaggregated assets — and fix the things that move the needle.

August 10, 2026 · by Dane Petersen

Most slow Drupal sites aren’t slow everywhere — they’re slow in one or two places that touch every page. The fix is rarely a bigger server; it’s finding those places. You’ll need drush, SSH access, and a site you can safely poke at. It helps to already be comfortable clearing caches the right way, because you’ll be doing it between changes.

Measure before you touch anything

Pick three real pages — the front page, a busy landing page, and something content-heavy — and time them from the command line:

curl -s -o /dev/null -w "total: %{time_total}s\n" https://example.com/

Run each one twice and write down both numbers. The second run is your warm number; the gap between them is your caching story. No numbers, no way to know later whether you actually helped.

Confirm page caching is on and actually working

Drupal ships two big caches: Page Cache (whole pages for anonymous visitors) and Dynamic Page Cache (most of the page for everyone else). Check that pages are actually hitting them:

curl -sI https://example.com/ | grep -i x-drupal

You want X-Drupal-Cache: HIT on the second request. A steady MISS or UNCACHEABLE means something on the page is spoiling it — hold that thought for step five. Also make sure anonymous pages are allowed to live a while:

drush config:get system.performance cache.page.max_age
drush config:set system.performance cache.page.max_age 3600 -y

Turn on CSS and JS aggregation

Aggregation bundles dozens of small CSS and JS files into a few, which saves the browser a pile of round trips. It’s on by default in newer installs, but sites that grew up through upgrades — or had it switched off for debugging — often ship bare:

drush config:set system.performance css.preprocess 1 -y
drush config:set system.performance js.preprocess 1 -y
drush cache:rebuild

Find the slow queries and heavy views

Views are the usual suspects: a listing with no cache set will run its query on every single load. In each slow view, open Advanced → Caching and set time-based caching — even one minute helps a busy page enormously. To catch the rest, install Webprofiler on a local copy only — it puts a toolbar on every page showing exactly where the milliseconds went: which queries ran, what missed cache, what rendered slow. Fix the top item, re-measure, repeat. Resist fixing the fifth-worst thing first; the portage doesn’t get shorter by rearranging the packs.

Deal with the uncacheable bits

One personalized block — a cart, a “hello, name,” a random promo — can mark a whole page uncacheable and drag everyone down with it. If step two showed UNCACHEABLE, hunt for the block or module setting a max-age of zero. The usual fixes: cache the block with the right context, load the personal bit with JavaScript after the page lands, or ask honestly whether the page needs it at all. Anything session-related (an unneeded cookie set for every visitor) has the same effect and is worth chasing down.

Measure again and keep the receipt

Run the same curl timings on the same three pages and compare against your step-one numbers. Cold and warm should both be down, and the warm loads on anonymous pages should be well under a second. Save both sets of numbers somewhere durable — when someone asks in six months whether the site got slower, you’ll have a true north to check against instead of a feeling.

That's the lesson. Back to the shop for more — or if this is the chore your organization never gets to,that's literally what we're for.