Skip to header Skip to main navigation Skip to main content Skip to footer
Drupal Maintenance and Developments in Austin TX
Drupal Care

Main navigation

  • Home
  • Why Drupal Care?
  • What’s Included
  • About
  • Our Approach
  • Prices & Plans
  • Portfolio (opens in new tab)
  • Blog
  • Videos
  • Contact
  • Site Evaluation

Drupal Performance Optimization: Caching, Database Queries, and Front-End Speed

Alaa Haddad, professional Drupal developer based in Austin, TX   Drupal Care
  1:53 PM CDT, Tue September 15, 2026
Share

Slow Drupal sites are usually slow for one or two specific reasons, and the reasons are rarely the ones people start with. The instinct is to add caching or move to a bigger server. Both can help; neither is diagnosis, and applied to the wrong problem they hide it rather than fix it.

A page that takes four seconds is spending that time somewhere specific: waiting on the database, executing PHP, waiting on an external service, or in the browser after the HTML has already arrived. Those are four different problems with four different fixes, and guessing between them is how weeks get spent without the number moving.

This page covers where Drupal actually spends time, how to find out which case you are in, and the fixes that reliably matter.

Measure Before Changing Anything

The first question is not "how do we make it faster" but "what is it waiting for". Without that, every change is a guess, and a guess that appears to work is worse than one that fails — it ends the investigation.

Three measurements separate the main cases. Time to first byte tells you whether the server is slow or the browser is. If TTFB is fine and the page still feels slow, the problem is front-end. If TTFB is poor, profiling the request — with XHProf, Blackfire, or Drupal's own devel tooling on a copy — shows whether the time is in the database, in PHP, or in an external call.

Also measure the right page. The homepage is usually the most heavily cached and least representative. The pages that matter are the ones with real traffic and real complexity: a search result, a filtered listing, a logged-in dashboard.

The Cache Layers, and What Each One Does

Drupal has several caches, and confusion between them wastes a lot of time. In rough order from the visitor inward:

  • Browser cache — the visitor's own copy, controlled by response headers.
  • An edge cache or CDN — a shared copy near the visitor.
  • Drupal's page cache — complete pages, for anonymous users only.
  • Drupal's dynamic page cache — pages with the personalised parts left as placeholders, so it works for logged-in users too.
  • The render cache — individual pieces of output, reused across pages.

The important consequence: the outer caches only help anonymous traffic. If your problem is logged-in users, no amount of CDN configuration will touch it, and effort spent there is effort not spent on the actual cause.

Cacheability Metadata Is the Whole Game

Every piece of Drupal output can declare three things: tags (what content it depends on), contexts (what varies it), and max-age (how long it stays valid). Get these right and Drupal caches aggressively and invalidates precisely. Get them wrong and you get one of two failures.

Declare too little and content is served stale — someone edits a node and the old version persists. Declare too much, or set max-age: 0, and the output is never cached, so every request pays full cost.

The second is far more common, because it is what a developer does when the first happens. A stale-content bug gets fixed by disabling caching, the bug goes away, and a permanent performance cost is introduced in its place.

// The problem is not caching; it is that the dependency was never declared.
$build['#cache']['max-age'] = 0;

// Cache freely, and invalidate exactly when this node changes.
$build['#cache']['tags'] = $node->getCacheTags();
$build['#cache']['contexts'] = ['user.permissions'];

Getting this right in the application is also what makes long edge-cache lifetimes safe further out. A page that declares its dependencies correctly can be cached at the edge for a long time and purged the moment its content changes.

The Anonymous and Authenticated Split

These are effectively two different performance problems.

Anonymous traffic can be served from a fully cached page and should be fast almost regardless of how complex the site is. If anonymous pages are slow, either page cache is disabled, something on the page is preventing it, or the first uncached request is genuinely expensive and every visitor is paying it.

Authenticated traffic bypasses page cache entirely. Here the wins come from dynamic page cache, from getting personalised elements isolated into placeholders so the rest of the page stays cacheable, and from the render cache. A site where every logged-in page is slow usually has personalisation smeared across the whole page rather than confined to the parts that need it.

Database: The Usual Suspects

Slow database time in Drupal usually comes from a small number of patterns.

The dominant one is queries inside loops — loading a list, then loading something related for each row. Twenty items become twenty-one queries. Drupal's storage supports loading many entities at once, and the fix is normally a few lines.

After that: queries with no usable index, which are fine on a development database with a hundred rows and fall over at fifty thousand; unnecessarily loading full entities when only a title or an ID is needed; and, in some cases, a database that has simply never been tuned for its workload.

The slow query log is the fastest route to the truth here, and it is frequently not switched on.

Views, and Why They Get Slow

Views is the most common source of slow pages, because it makes it easy to build something expensive without seeing the cost.

What makes a view slow: multiple relationships, filters on fields that are not indexed, sorting on a computed or joined value, rendering full entities where a few fields would do, and pagers that count total rows on a large table.

Practical improvements, in the order usually worth trying: render fields instead of full entities where the output allows it; check the view's own caching settings, since these default conservatively; index the fields being filtered and sorted on; and for very large result sets, consider whether the pager needs an exact total count at all — it is frequently the most expensive part of the query.

The Views UI can display the generated query. Reading it is often immediately clarifying, and it is a step people skip.

If the numbers on your own site point at the database or at Views, a performance audit profiles real pages and ranks the fixes by impact. Request a quote and say which pages are slowest.

Images Are Usually the Front-End Problem

When TTFB is fine and pages still feel slow, images are the first thing to check and by far the most common answer.

Drupal's image styles generate derivatives at appropriate sizes, and responsive image styles let the browser pick one. Sites that skip this serve a 3000-pixel original to a phone, which is often more bytes than the entire rest of the page.

Also worth doing: modern formats such as WebP where supported, loading="lazy" on images below the fold, and explicit width and height attributes so the browser can reserve space and avoid layout shift.

This is usually the highest-value front-end work available, and it requires no application changes at all.

CSS, JavaScript and the First Paint

Drupal aggregates CSS and JavaScript when asked to, and that should be on in production. Beyond that, what matters is how much is loaded and when.

Libraries attached globally rather than where they are needed mean every page pays for every feature. Render-blocking CSS delays the first paint. Web fonts loaded without font-display: swap can leave text invisible while they download. JavaScript that is not needed for the initial view should be deferred.

The measurement that matters is what a real visitor experiences on a real connection — a lab score on a fast machine can look excellent while a phone on mobile data has a very different time of it.

PHP, OPcache and the Runtime

Some performance problems are runtime configuration rather than code.

OPcache should be enabled and given enough memory to hold the codebase; without it, PHP recompiles files on every request, which is pure waste. The PHP version matters too — each recent major version has brought real performance improvements, so an old version costs speed as well as security coverage.

These are quick to check and occasionally explain an otherwise mysterious across-the-board slowness, particularly after a site has been moved between hosts.

Edge Caching and What It Can and Cannot Do

A CDN or edge cache serves cached responses close to the visitor, and for anonymous traffic on a content site the effect can be dramatic.

The two things to get right are what may be cached and how it gets invalidated. Pages that vary by user must never be cached at the edge, and the mechanism that decides this must be reliable rather than a guess based on a path pattern. And when content changes, the edge copy has to be purged — otherwise long cache lifetimes mean long-lived stale content.

Cache duration and cache invalidation are separate concerns that are easy to conflate; the combination that works is a long lifetime plus reliable purging on change, not a short lifetime chosen to limit the damage.

Search, and When the Database Stops Being Enough

Database-backed search is fine at small scale and degrades badly as content grows, particularly with faceting or complex filters.

The signal that it is time to move to a dedicated search backend is usually a search or filtered-listing page that is markedly slower than everything else on the site. Moving that workload out of the database is often the single largest improvement available on a large content site — and it also removes load from the database that everything else was competing with.

Common Performance Mistakes

  • Caching disabled to fix a staleness bug, turning a correctness problem into a permanent cost.
  • Optimising without profiling, so effort lands on whatever was easiest to change.
  • Testing only the homepage, which is the least representative page on the site.
  • Adding a CDN for a logged-in-user problem, which it cannot touch.
  • Full entities loaded where a field would do, especially inside Views.
  • Full-size images served to every device.
  • A bigger server bought to cover an N+1 query, which scales cost instead of fixing the cause.

When It Is Not the Code

Sometimes the application is fine and the environment is not: an undersized or contended server, a database on slow storage, PHP workers set too low so requests queue, or an external API the site calls synchronously on every page load.

That last one is worth calling out. A site that fetches from a third-party service during page rendering inherits that service's worst day. Anything that can be fetched in the background, cached and rendered from local data should be — and where a live call is genuinely required, it needs a timeout short enough that a slow dependency degrades the page rather than hanging it.

Next Steps

If you are investigating yourself, start with three numbers on a page that actually matters: TTFB, the query count for the request, and total page weight. Those three usually point straight at which of the four categories you are in, and prevent the most common waste — optimising the part that was already fast.

If you would rather have it diagnosed: a performance audit profiles real pages under real conditions and delivers findings ranked by expected impact against effort, covering application code, database, front end, caching strategy and runtime configuration. Implementation can follow as a defined piece of work.

Web development has been my work since 2005, and I am the author of Drupal modules and themes; you can find them on my drupal.org profile.

Request a quote with your Drupal version, whether the problem affects anonymous or logged-in users, and which pages are worst — that last detail usually narrows it considerably before anyone looks at the site. Or get in touch to talk it through. Related engineering detail is on the Drupal developer page.

Drupal Services
Drupal Caching

Footer menu

  • About
  • Privacy Policy
  • Terms & Conditions
  • Flash Web Center, LLC (opens in new tab)
  • Web Designer In Austin (opens in new tab)
  • Log in
  • Contact
  • Sitemap

Copyright © 2026 Flash Web Center, LLC | All rights reserved

Developed & Designed by Alaa Haddad