Guides

Slow website: identify server, database or plugin issues in 10 minutes

Three-step method to pinpoint where time is lost on a slow site: TTFB, MySQL slow query log, PHP profiling. Commands for Ubuntu 24.04, cPanel and Plesk.

UptimeMag editorial team · 15 October 2026 · 5 min read

Wikimedia Tampa datacenter fall 2007, cabling

Your site is responding sluggishly or not responding at all. First question, before touching any setting: is the problem on the server side or on the network/browser side of the visitor? You can resolve this in less than a minute by measuring TTFB (time to first byte, the elapsed time from request to the server's first response) from a location outside the server.

From the command line, on any system with curl installed:

curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s - Total: %{time_total}s\n" https://thesite.it/

If the time_starttransfer value is high (above 1 second) the time is being lost on the server. If it's low but time_total is high, the problem is in content delivery (heavy images, missing compression), not in the application server. It's worth repeating the test from two or three different networks (home, mobile, a VPS in another region) before drawing conclusions: a high TTFB from only one specific network indicates a routing or CDN problem, not a server problem.

Case 1: the delay is in the web server

On Ubuntu 24.04 with Nginx and PHP-FPM, the first place to look is Nginx's error log. The paths are /var/log/nginx/access.log and /var/log/nginx/error.log on Ubuntu, Debian, RHEL, CentOS and Fedora when Nginx is installed from the distribution package or official repository. If a previous admin has changed the path, the way to know for certain without guessing is to ask the binary itself:

nginx -V 2>&1 | tr ' ' '\n' | grep error-log-path

To watch errors in real time while reloading the page:

sudo tail -f /var/log/nginx/error.log

The line that matters is the one with a timestamp close to when the slow request occurred: if "upstream timed out" errors appear, the problem is in the handoff to PHP-FPM, not in Nginx itself.

On cPanel, Apache/Nginx logs for a single account are normally found in /usr/local/apache/domlogs/ (or equivalent path shown in WHM under "Apache Status" and "Error Log"); on Plesk, the control panel exposes logs per domain from Websites and domains > Logs, without needing SSH. In both cases the logic is identical: you search for the slow request in the vhost log, not the global one.

If TTFB remains high even with a test static site (a blank HTML page loaded in the same vhost), the problem is not in the application but in the server itself: CPU saturation, disk I/O at the limit, too many PHP-FPM processes queued. Here you need to check the load (uptime, top, iostat -x 1) before continuing to search in the code.

Case 2: the delay is in the database

If the static site is fast but dynamic pages are slow, suspicion shifts to MySQL/MariaDB. The right tool is the slow query log, which is not enabled by default. The MySQL slow query log records queries exceeding a specified threshold (long_query_time) and is the main tool for identifying performance bottlenecks and queries that need optimisation.

To enable it without restarting the service (valid on both MySQL and MariaDB):

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

These settings take immediate effect but are lost on restart. To make them permanent, they should be written to the configuration file (/etc/mysql/my.cnf or a file in /etc/mysql/mysql.conf.d/) under the [mysqld] section.

On the threshold, the official documentation is clear: by default MySQL logs every query that takes more than 10 seconds to execute, and technically the minimum and default value of long_query_time are 0 and 10 respectively. Ten seconds is a useless value for understanding why a page that should respond in 300 milliseconds takes 3: for day-to-day diagnostic work it's better to lower the threshold to 1 second, watch what appears for a couple of hours, then raise it again. Warning: the log_queries_not_using_indexes parameter is OFF by default, so a slow query because it doesn't use an index might not appear at all unless you explicitly enable this parameter too.

After collecting a few dozen lines, the command mysqldumpslow -s t -t 10 /var/log/mysql/slow.log sorts queries by total time and shows the ten worst: that's where you'll find the unindexed query that's blocking everything, not by scrolling through the file manually.

Case 3: the delay is in the code (plugin, theme, application)

If the database is responding well (no lines in the slow log with a 1-second threshold, even under load) but the page is still slow, the time is being lost in PHP execution: a plugin making external calls, a theme recalculating queries on every load, unoptimised code. The simplest free tool to isolate the culprit on WordPress is the SAVEQUERIES option plus a debug plugin that shows time per hook (e.g. Query Monitor), or, at server level, the profiler built into PHP-FPM that logs calls stuck beyond a threshold: it needs to be configured in the pool file (typically /etc/php/8.3/fpm/pool.d/www.conf on Ubuntu, or the pool section in the control panel on Plesk/cPanel) by setting a timeout and a dedicated log file, and restarting the PHP-FPM service to activate it.

Without one of these two tools you're just guessing: disabling plugins one by one at random is a method, but it requires repeating the TTFB measurement with each disabling, otherwise you won't know if the improvement is real or network noise.

What does NOT help before measuring

Switching hosting without doing any of the three measurements above is the most common way to spend money without solving anything: if the problem is an unindexed query, it's identical on any server, even the most powerful. Similarly, installing three different caching plugins together on WordPress doesn't sum the benefits: it often cancels them out, because more plugins intercept the same requests and create conflicts that you only see in the PHP error log, not in perceived speed.

If the problem might be the provider's fault

If TTFB is high even on a blank static page and the machine load (uptime, top) shows nothing anomalous, suspicion shifts to the infrastructure outside your control: slow shared storage, noisy neighbour on a VPS, network problems towards the data centre. In this case open a ticket with the provider attaching: the exact time of TTFB measurements taken from multiple locations, the output of uptime and iostat -x 1 5 at the same moment, and if possible a traceroute (traceroute thesite.it or mtr thesite.it) to rule out a routing problem before it reaches the server. Without this data support can't distinguish a problem on their side from one inside your machine, and the request stays in the queue longer than necessary.

Written with the help of artificial intelligence and checked by the editors (EU AI Act, art. 50).