A Drupal site consistently taking ~5 seconds to generate a page is almost always waiting on one of these:
- Database
- PHP execution
- External HTTP requests
- Cache disabled/misconfigured
- Slow custom code
First, let's determine if it's transport layer or the backend. From the server:
curl -o /dev/null -s -w \
'connect: %{time_connect}\nstarttransfer: %{time_starttransfer}\ntotal: %{time_total}\n' \
https://example.com
If time_starttransfer is around 5 seconds, the backend is slow.
Is Drupal cache actually working?
drush statusCheck:
- Render cache
- Dynamic page cache
- Page cache
Then inspect:
drush cget system.performanceIf you're logged in, page cache won't help, but render and dynamic page cache should.
Enable database logging
If MySQL/MariaDB:
SHOW FULL PROCESSLIST;while loading a page.
Or enable the slow query log:
SET GLOBAL slow_query_log=1;
SET GLOBAL long_query_time=0.2;Then inspect:
/var/lib/mysql/*-slow.logA single query taking several seconds is common.
Profile Drupal
Install modules devel and profiler:
composer require drupal/webprofilerWebProfiler will show
- routing
- twig
- SQL
- services
- hooks
- render time
Usually you'll immediately see the culprit.
Check for HTTP requests
One forgotten call can cost 5 seconds.
Search:
grep -R "http" web/modules/custom
grep -R "curl" web/modules/custom
grep -R "Guzzle" web/modules/custom
grep -R "file_get_contents(" web/modules/custom
Anything contacting another server during page generation is suspicious.
Check cache backend
If using database cache:
drush ev "print_r(\Drupal::service('cache.default'));"Redis is dramatically faster on busy sites.
Make sure to Disable Twig debug
Development settings easily add seconds. Check:
development.services.ymlLook for
twig.config:
debug: true
auto_reload: true
cache: falseProduction should be
debug: false
auto_reload: false
cache: trueOPcache
Verify:
php -i | grep opcache.enable
php -i | grep opcache.validate_timestampsProduction typically uses
opcache.enable=1
opcache.validate_timestamps=0Xdebug
Check:
php -m | grep xdebugor
php -i | grep xdebug.modeIf enabled, disable it.
Measure SQL count
Enable query logging:
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';or use WebProfiler.
A normal cached page is often:
- 20–80 SQL queries
Several hundred queries indicates a problem.
Identify expensive hooks
Search custom modules for
hook_page_attachments()
hook_preprocess_page()
hook_preprocess_node()
hook_entity_view()
hook_views_pre_render()
hook_views_query_alter()These frequently introduce delays.
Check Views
A large View can consume the entire 5 seconds.
Enable SQL preview on the View and run:
EXPLAINLook for
- Using temporary
- Using filesort
- full table scans
Measure PHP
Install XHProf, Tideways, or Blackfire.
A flame graph immediately identifies where execution time is spent.
Check the logs
drush watchdog:showor
tail -f web/sites/default/files/php.logRepeated warnings can significantly slow page generation.
Benchmark without Drupal
Create a simple PHP file:
<?php
echo "hello";Compare:
time curl https://example.com/test.php
time curl https://example.com/If test.php is fast and Drupal is slow, the problem is in Drupal rather than PHP, the web server, or TLS.