...

Why a Website Is Slow: How to Tell Whether the Problem Is the VPS, Database, CMS, or Code

Martin Klein

Reading time 1 minute

If a website is slow, you should not immediately upgrade your VPS plan or install yet another optimization plugin. First, determine exactly where the delay occurs: on the server, in the database, the CMS, the code, the frontend, an external API, or because of a spike in requests.

Basic diagnostics are based on symptoms:

  • High TTFB — check PHP, the database, the cache, the external API, and the request queue;
  • 100% CPU usage — inspect processes, PHP-FPM, MySQL, cron jobs, bots, and background operations;
  • Insufficient RAM — check free, swap, PHP processes, MySQL, and Redis;
  • Slow disk — check available space, I/O, and iostat;
  • Long-running SQL queries — enable or review the MySQL slow log;
  • 502 and 503 errors — check Nginx, PHP-FPM, memory, and application logs;
  • A sudden increase in requests — check the access log, bots, DDoS activity, wp-login, xmlrpc, and suspicious URLs;
  • Normal TTFB but slow page loading — look for the issue on the frontend: images, JavaScript, CSS, fonts, and third-party scripts.

The minimum toolset for an initial check includes top or htop, free, df, iostat, Nginx logs, PHP-FPM status, and the MySQL slow log. These tools are often enough to show exactly what is hitting its limit: CPU, RAM, disk, the database, PHP, or the flow of requests.

PageSpeed and Core Web Vitals are useful, but they do not replace server-side diagnostics. They can show that users are seeing a slow page, but they do not always explain why the server is taking a long time to respond or why PHP processes are queued.

The right sequence is: first record the symptom, then check VPS metrics, then review the web server, PHP, and database logs, and only after that examine the CMS, plugins, code, cron jobs, and external APIs.

Moving to a more expensive VPS is justified only when diagnostics show an actual shortage of resources. If the website is slow because of slow queries, a heavy plugin, poorly written code, an external API, or frontend issues, a new plan may only hide the problem temporarily.

Why You Shouldn’t Guess at the Cause

When a website starts slowing down, it is tempting to take immediate action: enable caching, disable a couple of plugins, switch VPS plans, or start optimizing images. Sometimes this helps, but more often this approach only makes troubleshooting harder.

If you change several settings at once, it becomes difficult to understand what actually affected performance. Even worse, the site may become temporarily faster while the root cause remains unresolved; a week later, or after the next traffic spike, the problem will return.

A single symptom can have different causes

The same visible issue can occur for different reasons. For example, a user may experience slow page loading, but the source of the delay can be entirely different.

A high TTFB may indicate an overloaded PHP-FPM, a slow database, lack of caching, waiting for a response from an external API, or insufficient resources on the VPS.

502 and 503 errors may occur due to PHP-FPM crashing, insufficient RAM, overly long requests, incorrect timeout settings, or a sudden spike in bot requests.

A slow admin area may be related to the database, a heavy plugin, cron jobs, a large autoload in the CMS, or an external service that takes a long time to respond when the dashboard is opened.

That is why you cannot diagnose the problem based only on the impression that “the site is slow.” First, you need to determine at which level the delay occurs: network, VPS, web server, PHP, database, CMS, code, or browser.

PageSpeed Does Not Show the Full Picture

PageSpeed and similar tools are useful, but they do not replace server diagnostics. They are good at identifying client-side loading issues: images, JavaScript, CSS, fonts, LCP, CLS, and other frontend metrics.

However, a PageSpeed report does not always explain why a PHP process is taking too long to execute, why MySQL is bottlenecked by disk I/O, or why a VPS has run out of memory.

You may receive a low score because of heavy JavaScript even though the server responds quickly. Conversely, a page may look reasonably good from a frontend perspective but still have a high TTFB because of a slow database or lack of caching.

That is why PageSpeed should be used as one tool among others, not as the single source of truth. If the issue appears to be server-side, you need to check VPS metrics, Nginx logs, PHP-FPM status, and the database slow log.

Otherwise, you may start by minifying CSS even though the actual delay occurs before the browser has even received the HTML.

Troubleshooting should proceed from metrics to hypotheses

Proper troubleshooting starts not with a guess, but with measurement. First, the symptom is recorded, then the metrics are checked, and only after that is a hypothesis formed.

For example, if TTFB is high, you need to check CPU load, RAM, PHP-FPM, MySQL, and the logs. If the CPU is idle, there is enough RAM, and the slow log shows long-running SQL queries, the hypothesis shifts toward the database or a plugin.

If the CPU stays at 100%, you need to determine what is consuming it: PHP, MySQL, cron, an archiver, a bot attack, or another process, up to and including cryptomining malware.

If RAM is exhausted and swap is being used heavily, the cause may be too many PHP processes, an overloaded database, Redis, a memory leak, or a background process that is consuming resources.

This approach saves time. Instead of trying fixes at random, the administrator gradually narrows down the possible causes and validates each new hypothesis against the facts.

Next, you can move on to a practical workflow: which symptoms are most common and which commands help you quickly understand where to look.

Diagnostic Algorithm: From Symptom to Cause

High TTFB

High TTFB means the browser waits a long time for the first response from the server. At this stage, the page has not started rendering yet: the user is waiting for the backend to prepare the HTML, or at least to start sending it.

The cause may be the VPS, PHP, the database, the CMS, the code, an external API, or a lack of caching.

What to checkPossible cause
CPU and RAMthe server is hitting resource limits
PHP-FPM statusrequests are waiting for an available PHP process
MySQL slow logthe database takes a long time to execute SQL queries
Nginx/PHP logserrors, timeouts, process crashes
external APIthe application is waiting for a response from a third-party service
cachethe page is regenerated on every request

If TTFB is high only for specific pages, the issue is most likely in a particular piece of code, a database query, a plugin, or an external integration. If TTFB is high across the entire site, start with the VPS, PHP-FPM, the database, and caching.

100% CPU

Sustained CPU usage at 100% indicates that the server lacks sufficient computing resources or that a process is consuming them too aggressively.

First, identify what exactly is loading the CPU: PHP-FPM, MySQL, Node.js, a cron job, an archiver, antivirus software, a parser, a bot, or another process.

For an initial check, use top or htop. They show processes, CPU usage, memory usage, and overall system load.

If PHP-FPM is consuming the CPU, the cause may be a large number of dynamic requests, a heavy CMS, plugins, a lack of caching, or bots. If MySQL is consuming the CPU, check the queries, indexes, table sizes, and the slow log.

A brief spike during a backup or import does not always indicate a problem. The more serious case is when the CPU stays at its limit continuously or under normal traffic.

Insufficient RAM and active swap usage

When RAM is insufficient, the system starts using swap—a disk area where data from RAM is temporarily paged out. For a website, this almost always results in a noticeable slowdown.

You can check memory with the following command: free -h

If available memory is low and swap is being used heavily, you need to identify what is consuming RAM: PHP-FPM, MySQL, Redis, background tasks, the CMS, the control panel, or a third-party service.

A common mistake is configuring too many PHP-FPM processes. In theory, this should allow the server to handle more requests, but in practice each process consumes memory. If the number of processes exceeds what the VPS can handle, the server starts swapping.

Insufficient RAM can appear as a slow admin interface, 502 and 503 errors, MySQL crashes, stuck PHP processes, and unstable website performance under load.

Slow Disk

Even if CPU and RAM usage look normal, a website can still slow down because of disk performance. This is especially noticeable with databases, caches, logs, backups, file uploads, and CMS platforms that actively read and write data.

First, check free disk space: df -h

If the disk is nearly full, issues start to occur with logs, cache, temporary files, uploads, and the database.

Use iostat to assess disk load. It helps determine whether the server is bottlenecked by read and write operations.

High iowait often indicates that processes are waiting on disk I/O. From the outside, this can look like the “site is thinking,” even though the CPU is not fully loaded.

Possible causes include a slow disk type, heavy SQL queries, frequent backups, a large volume of logs, active swap usage, or multiple background tasks running at the same time.

Long-running SQL queries

If the database responds slowly, the site may slow down even on a good VPS. This is especially noticeable in CMS-based sites, online stores, catalogs, user account areas, search, and admin panels.

The MySQL slow query log is used for diagnostics. It shows queries that take longer than a specified threshold to execute.

Long-running SQL queries can be caused by:

  • Missing required indexes;
  • Large tables;
  • Complex filters;
  • Resource-intensive plugins;
  • Poorly designed JOINs;
  • Bloated logs and temporary data;
  • A large volume of autoload settings in the CMS.

If slow queries recur regularly, upgrading the VPS plan may only have a temporary effect. You need to identify which page, module, plugin, or part of the code is putting load on the database.

An external API is slowing down the response

Sometimes a site is slow not because of the VPS, CMS, or database, but because it is waiting for a response from an external service. This could be a payment system, CRM, delivery service, analytics service, map service, anti-fraud system, exchange rate API, or any other integration.

If the code waits for an external API synchronously, the user will not receive the page until that service responds or a timeout is triggered.

This scenario often appears as high TTFB while CPU, RAM, and database load remain normal.

You should check the application logs, HTTP request timeouts, and the pages where the integration is connected. If only checkout, the user account area, or the request form is slow, the external API becomes one of the first suspects.

Some of these tasks are better moved to background queues: the user receives a response quickly, while synchronization with the external service runs separately.

Cron Jobs Create Load Spikes

Cron jobs run background operations such as backups, product imports, email campaigns, cache cleanup, report generation, inventory updates, CRM synchronization, and other recurring processes.

If cron is poorly configured, several resource-intensive tasks can start at the same time and suddenly place a heavy load on the CPU, RAM, disk, or database.

A typical example is a backup, catalog import, and product recalculation all starting at night. During this time, the website may slow down even though it works normally during the day.

Cron logs, load history, error timing, and the list of processes running at the time of the slowdown can help diagnose these spikes.

Cron jobs should be staggered, limited by resource usage, and scheduled so that heavy operations run outside peak traffic periods. For CMS platforms, it is also important to check built-in task schedulers because they may be triggered by site visits.

DDoS, bots, and request spikes

A sharp increase in requests does not always mean an increase in real visitors. A site may be loaded by search engine bots, scrapers, vulnerability scanners, password brute-force tools, DDoS attacks, or aggressive integrations.

The first source of information is the Nginx access log. It can show IP addresses, URLs, request frequency, response codes, and user agents.

Suspicious indicators:

  • A large number of requests to wp-login.php, xmlrpc.php, or administrative URLs;
  • A sharp increase in 404 errors;
  • Frequent POST requests;
  • Repeated requests from the same IP address or subnet;
  • Unusual user agents;
  • A spike in requests to resource-intensive search, filter, or cart pages.

If the site slows down only during these spikes, the issue may not be the VPS plan, but the lack of request limits, a WAF, rate limiting, caching, or bot protection.

After this initial analysis, you can move on to specific VPS tools: top, htop, free, df, iostat, Nginx logs, PHP-FPM status, and the database slow log.

What to Check First on a VPS

CPU and Processes Using top or htop

The first thing to check on a VPS is which processes are consuming CPU right now. For this, use top or the more convenient htop. These commands show running processes, CPU usage, memory usage, and overall system load.

In these utilities, you should look not only at the overall CPU utilization percentage, but also at the process list. It is important to identify exactly what is causing the load: PHP-FPM, MySQL, the web server, Node.js, a cron job, an archiving tool, antivirus software, an import script, or another process.

If PHP-FPM is consuming CPU resources, the cause may be a large number of dynamic requests, a heavy CMS, bots, lack of caching, or long-running PHP code.

If MySQL is consuming the CPU, you need to move on to the slow query log, indexes, table sizes, and the queries generated by the CMS or application.

You should also check the load average. If the value is consistently higher than the number of available vCPUs, the server may not be able to process tasks fast enough. A one-time spike is not always critical, but sustained high load during normal traffic is a reason to continue troubleshooting.

After checking CPU, check memory: many performance issues start not with the processor, but with insufficient RAM.

Checking memory with free

You can quickly check RAM with the following command: free -h

It shows the total amount of RAM, used memory, cache, available memory, and swap.

The key is not to panic over the used value. Linux actively uses free memory for cache, and that is normal. It is more important to look at available memory and swap usage.

If swap is barely being used and there is enough available memory, RAM is most likely not the main bottleneck.

If swap is heavily used and continues to grow, the server does not have enough RAM. In this case, the site may slow down even with moderate CPU load because some data is being moved to disk.

Common causes of insufficient RAM:

  • Too many PHP-FPM processes;
  • Heavy CMS plugins or modules;
  • MySQL is consuming too much memory;
  • Redis is configured without taking limits into account;
  • Backups, imports, and cron jobs are running at the same time;
  • Unnecessary software or a control panel is running on the VPS.

If there is not enough memory, increasing pm.max_children in PHP-FPM will only make the situation worse. First, you need to identify which processes are consuming RAM and eliminate the unnecessary load.

The next basic layer is the disk: even available CPU and RAM will not save a site if the VPS has run out of space or the disk cannot read and write data fast enough.

Disk usage and free space with df

You can check free disk space with the following command: df -h

It shows which partitions are mounted, how much space is used, and how much is still available.

If a disk is almost full, the website may start behaving unpredictably. Issues can occur with logs, cache, temporary files, uploads, sessions, backups, and the database.

The situation is especially risky when the partition where the following are stored runs out of space:

  • Website files;
  • Database;
  • System logs;
  • Temporary files;
  • Cache;
  • Backups.

Sometimes a VPS slows down not because the plan is underpowered, but because archives, old logs, database dumps, caches, and unnecessary backups have been accumulating on it for months.

After running df -h, check not only the overall usage percentage but also what is causing it to increase. If the space fills up again quickly, simply deleting files will not solve the problem: you need to configure log rotation, backup retention rules, and temporary data cleanup.

However, free space is only part of the picture. A disk may not be full and can still perform slowly under load.

Disk Load with iostat

iostat is used to assess disk load. If the utility is not available, it is usually installed as part of the sysstat package.

Command for real-time monitoring: iostat -xz 1

It helps show how actively the disk is reading and writing data, whether there are delays, and whether processes are waiting for I/O operations.

Pay particular attention to iowait. If it is high, processes are spending time waiting for the disk. To users, the site may appear slow even though the CPU does not look fully utilized.

High disk load can have different causes:

  • MySQL is actively reading large tables;
  • The site is using swap because there is not enough RAM;
  • A backup and an import are running at the same time;
  • Logs are being written too intensively;
  • The cache is constantly being created and deleted;
  • The VPS disk is too slow for the current workload.

If the disk load is related to the database, check slow queries and MySQL settings. If swap is the cause, look at RAM again. If backups or cron jobs are causing the problem, they need to be scheduled at different times.

After CPU, memory, and disk, the next step is to check the network: sometimes slowdowns are caused not by the code or the VPS, but by a spike in requests.

Network Connections and Traffic Spikes

If the site suddenly slows down, check whether the number of incoming requests has increased. This may be legitimate traffic, or it may be search bots, scrapers, vulnerability scanners, password brute-force attempts, or a DDoS attack.

The first source of information is the web server access log. For a quick check of network connections, however, you can use commands such as ss -tunap or netstat -tunap.

These commands show active connections, ports, and the processes handling them.

If you suspect a spike in HTTP requests, review the Nginx logs: which URLs are requested most often, which IP addresses the requests come from, which response codes are returned, and which user agents appear repeatedly.

The following may be suspicious:

  • Frequent requests to the login page;
  • Repeated requests for non-existent URLs;
  • A large number of 404 responses;
  • Many POST requests;
  • Frequent requests to resource-intensive search or filter pages;
  • A spike in requests from a single subnet;
  • Unusual user agents.

In these cases, the issue may not be code performance, but the lack of rate limiting, a WAF, caching, or bot rules.

After the initial VPS check, move on to the web server and application logs. These logs show which requests are reaching the site and where errors occur.

Web Server and Application Logs

Nginx access log

The access log shows which requests are reaching the site. It is one of the first files to check if the site suddenly slows down, the load increases, or bot activity is suspected.

The log is usually located at a path such as: /var/log/nginx/access.log

or in a separate file for a specific site: /var/log/nginx/example.com.access.log

You can quickly view the latest lines with the command: tail -f /var/log/nginx/access.log

In the access log, you should look at:

  • Which URLs are requested most often;
  • Which IP addresses the requests are coming from;
  • Which response codes the server returns;
  • How many requests arrive per minute;
  • Which user agents recur;
  • Whether there is a spike in requests to resource-intensive pages.

If the log contains many requests to the login page, search, filters, shopping cart, xmlrpc.php, API, or nonexistent URLs, the load may be caused not by real users but by bots, scanners, or brute-force tools.

The access log helps you understand what is happening externally. However, if requests are arriving normally but the server is still returning errors, you need to check the error log.

Nginx error log

The error log shows web server errors and issues that occur when forwarding requests to the backend. This is often where you can see the causes of 502 Bad Gateway, 504 Gateway Timeout, PHP-FPM issues, file permission problems, and timeouts.

The file is usually located here: /var/log/nginx/error.log

You can view the latest errors as follows: tail -n 100 /var/log/nginx/error.log

In the error log, look for messages about:

  • PHP-FPM being unavailable;
  • Timeouts being exceeded;
  • Access permission errors;
  • Requests that are too large;
  • SSL issues;
  • Missing files;
  • Failure to connect to the backend;
  • Proxying errors.

For example, if Nginx reports that the upstream is unavailable, the issue may be with PHP-FPM, the application, or the socket. If timeout messages appear frequently, the backend may be taking too long to process requests.

The error log does not always provide the definitive answer, but it points you in the right direction: whether the issue is with Nginx, PHP-FPM, the application, access permissions, or timeouts.

After checking the Nginx logs, you should check PHP-FPM itself, because it is often the bottleneck for CMS platforms and PHP applications.

PHP-FPM status and slowlog

PHP-FPM status shows how the PHP process pool is operating: how many processes are busy, how many are idle, whether there is a queue, and whether there are enough workers for the current load.

If the status page is configured, you can use it to see whether requests are waiting for an available PHP process. A queue in PHP-FPM often explains high TTFB and intermittent 502 or 503 errors.

The following signs are especially important:

  • All processes are busy;
  • There is a request queue;
  • The number of slow requests is increasing;
  • Processes run for too long;
  • The pool frequently reaches its limit.

PHP-FPM slowlog helps identify which PHP code is taking too long to execute. This is useful when the site does not go down, but specific pages, plugins, or actions in the admin area are consistently slow.

Slowlog can show that the delay is not in Nginx or the network, but inside PHP: in a specific script, function, plugin, CMS module, or call to an external API.

If PHP-FPM is operating at its limit, you do not always need to increase pm.max_children immediately. Check RAM first: an overly large process pool can lead to swapping and make the site even slower.

When Nginx and PHP-FPM do not reveal an obvious cause, you should move on to the logs of the CMS or application itself.

CMS and Application Errors

A CMS or application can perform poorly even on a properly functioning VPS. The cause may be a plugin, theme, module, custom code, version conflict, external API, or background task.

In the application logs, look for:

  • fatal errors;
  • warnings and notices that occur too frequently;
  • database connection errors;
  • external API timeouts;
  • authorization errors;
  • file permission issues;
  • failed cron jobs;
  • recurring exceptions.

For WordPress, it is useful to temporarily enable debug logging safely so that errors are written to a file instead of being displayed to users. Other CMSs and frameworks typically have their own logs in the project directory or in the system log.

It is important to look not only at the presence of an error, but also at its frequency. A single rare warning may not affect performance, while an error repeated a thousand times can overload the disk, logs, and application.

If the application logs show that the issue is related to the database, CMS queries, or a specific module, the next step is to diagnose MySQL, the slow query log, indexes, and the data structure.

The Database as a Source of Slowdowns

MySQL slow query log

The MySQL slow query log shows SQL queries that take longer than a specified amount of time to execute. It is one of the main tools to use when a site is slow in the admin panel, catalog, search, user account area, or checkout.

The slow query log is especially useful when the issue appears to be simply a “slow site,” but CPU, RAM, and Nginx do not provide an obvious answer. In this case, the delay may be inside the database.

In the slow query log, look at:

  • Which query took a long time to execute;
  • How long execution took;
  • How many rows were examined;
  • How often the query is repeated;
  • Which page, module, or action it is associated with.

A one-off slow query is not always critical. For example, an import, report, or infrequent administrative operation may take longer than a request for a regular page.

The problem starts when similar queries are repeated frequently and occur during normal user actions. In that case, the database can become a bottleneck for the entire site.

After reviewing the slow query log, you need to determine why the query is slow: whether it is resource-intensive, lacks an index, or is working with tables that have grown too large.

Expensive queries and missing indexes

An SQL query may be slow not because the server is underpowered, but because the database has to scan too many rows.

A common cause is a missing index. If a query filters, sorts, or joins tables on a field without an index, MySQL may perform a full table scan. This is not noticeable with small datasets, but as the database grows, the latency increases.

Expensive queries often occur in:

  • Search;
  • Product filters;
  • Catalogs;
  • Reports;
  • User account areas;
  • Admin panels;
  • Recommendation blocks;
  • Statistics plugins;
  • Custom queries in code.

EXPLAIN is used for analysis: it helps identify which tables are involved in the query, whether indexes are used, and how many rows the database plans to scan.

However, indexes should not be added indiscriminately. Unnecessary indexes take up space and can slow down data writes. First, you need to identify the specific recurring slow query, and only then decide which index or change in logic it needs.

Sometimes the problem is not a single query, but the fact that the database has accumulated unnecessary data over the years.

Bloated Tables and autoload

Over time, a CMS accumulates data: revisions, logs, temporary records, sessions, cache, statistics, orders, events, module settings, and traces of removed plugins.

As a result, tables grow larger, queries take longer to run, backups take more time, and the database uses disk and memory more heavily.

In WordPress, a separate common issue is bloated autoload data in the wp_options table. Autoloaded entries are loaded on every request. If there are too many of them, the site spends time and memory on data that may not be needed for a particular page.

Other CMS platforms use similar logic: some settings and module data are loaded automatically, so clutter in configuration tables affects not only the admin area but also public pages.

Before cleaning up the database, you must create a backup. Do not delete large records simply because they are large: they may contain important settings for the theme, CMS, payment module, cart, security, or integrations.

The right approach is to identify the owner of the record or table, determine whether the module is still in use, and only then delete obsolete data.

If the tables have been cleaned up and the queries are clear, but the database is still slow, check whether it is running up against VPS resource limits.

When the database runs into disk or RAM bottlenecks

A database makes heavy use of both RAM and disk. RAM is needed for caches, buffers, and query processing, while disk is used to read tables, write changes, store logs, and handle temporary files.

If there is not enough RAM, the database has to access the disk more often. If the disk is slow or overloaded, queries start waiting for I/O operations. From the outside, this shows up as high TTFB, a slow admin area, and unstable dynamic pages.

Signs of the problem:

  • High iowait;
  • Active swap usage;
  • Slow queries even without complex logic;
  • Increasing response times under normal traffic;
  • Long-running backups and imports;
  • Delays in the admin area and search;
  • Database connection errors under load.

In this case, you need to look not only at the slow log, but also at the overall VPS metrics: free, iostat, MySQL load, table sizes, and the database memory settings.

Sometimes it is enough to clean up tables, add the necessary index, or reduce the load generated by plugins. But if the database has genuinely grown and is constantly running into RAM or disk bottlenecks, you may need a more powerful VPS, a dedicated database server, or a managed database.

After the database, the next logical area to examine is the CMS, plugins, and code: these are often what create heavy queries, long-running PHP operations, and calls to external services.

CMS, Plugins, and Code

Resource-intensive plugins and modules

A CMS rarely slows down on its own. More often, the load is created by plugins, modules, extensions, and additional features that run every time a page is loaded.

Pay particular attention to:

  • Page builders;
  • Product filters;
  • Search;
  • Statistics;
  • SEO modules;
  • Security plugins;
  • Backups;
  • Multilingual support;
  • Recommendations and “related content”;
  • Integrations with CRM, shipping, and payment systems.

The issue is not always the number of extensions. A single resource-intensive module can generate more database queries and consume more CPU than ten simple plugins.

If the site is slow only on certain pages, you need to identify which plugins and modules are running there. For example, a catalog may be slow because of filters, checkout because of a payment integration, and the admin area because of statistics or background checks.

Disabling everything indiscriminately on a production site is risky. It is better to test hypotheses on a staging copy, review logs, use the CMS profiler, and check slow queries. If response time drops sharply after disabling a specific plugin, the cause becomes clearer.

However, even without resource-intensive extensions, a site can still be slow because of the theme or templates themselves.

Inefficient themes and templates

A theme is responsible for more than just appearance. It can run database queries, load scripts, render widgets, generate recommendation blocks, load fonts, and call additional CMS functions.

A poorly designed template may run several unnecessary queries inside a loop, recalculate data each time, load too many records, or include the same resources on every page.

On a small site, this is barely noticeable. But as traffic, the catalog, or the volume of content grows, these issues start to affect TTFB, the database, and CPU usage.

Signs of a theme-related issue:

  • Pages of the same type are slow;
  • Response time changes after switching templates;
  • The page runs many identical queries;
  • The theme loads unnecessary CSS and JavaScript;
  • Recommendation blocks and related-post sections are too slow;
  • The admin area is fast, but the public-facing templates are slow.

If the theme is purchased, it is worth checking for updates and known issues. If the theme is custom-built, you need to review the template code, the number of queries, and how loops work.

If the slowdown is caused not by the theme but by custom logic, the next area to check is code errors.

Code Errors and Infinite Loops

Code can slow down a site even when the server is powerful and the database is performing normally. Common causes include infinite loops, repeated queries inside loops, incorrect file handling, overly resource-intensive data processing, or a lack of caching where it is needed.

For example, a page may recalculate a report on every request, iterate through thousands of records, query the database inside a loop, or reload data that could have been stored in the cache.

Errors that do not completely break the site but occur continuously are also dangerous. A PHP warning or notice may seem minor, but if it appears thousands of times, the application spends resources writing logs and handling exceptions.

Check the following:

  • PHP error log;
  • CMS or application log;
  • PHP-FPM slowlog;
  • Repeated warnings and fatal errors;
  • Code paths that run on every page;
  • Loops with database queries;
  • Resource-intensive operations performed during page load.

If the code runs a long task synchronously, the user has to wait for it to finish. It is better to move such operations to background jobs, a queue, or pre-generated data.

A separate variation of this problem is waiting for a third-party API.

Third-Party APIs and Long Response Times

A website may depend on external services: payment systems, CRM platforms, delivery services, maps, analytics, anti-fraud systems, exchange rates, marketing platforms, or the company’s internal APIs.

If the application waits for one of these services to respond before serving the page, the external API’s latency becomes website latency.

This is especially noticeable when the VPS is not overloaded and the database responds normally, but TTFB is still high on specific pages: the checkout form, user account, cart, product page, or request page.

The issue may be a slow API response, missing timeouts, retries, slow DNS, network latency, or an integration error.

In the logs, look for HTTP requests to external services, their duration, response codes, and timeouts. If the same API regularly takes several seconds to respond, it should not remain in the critical path for page loading.

Some integrations are better handled asynchronously: first accept the user action, return a response quickly, and perform synchronization with the CRM, delivery service, or analytics system in the background.

After checking the CMS, plugins, theme, and code, the remaining task is to separate backend issues from frontend issues. Sometimes the server is already responding quickly, but the user still sees a slow page because of the browser, images, CSS, JavaScript, and external scripts.

How to Tell Frontend Slowdowns from Server-Side Issues

When the Server Is to Blame

A server-side issue begins before the browser receives the page. The user opens the site, but the first HTML response is delayed. In this case, TTFB usually increases.

The cause may be the VPS, PHP-FPM, the database, the CMS, the application code, an external API, or a lack of caching. In this situation, the browser can do almost nothing: it waits while the backend prepares the response.

Server-side slowdowns are often noticeable not only on the homepage, but also in the admin area, the user account area, search, the shopping cart, forms, and other dynamic sections.

If CPU load increases during the slowdown, RAM runs out, swap usage appears, the PHP-FPM queue grows, or long-running queries appear in the MySQL slow log, the issue should be investigated on the backend side.

From the outside, this may look like “the site just takes a long time to open.” Technically, however, the delay occurs before images, CSS, and JavaScript are loaded.

When the first HTML response arrives quickly but the page still takes a long time to become usable for the user, attention shifts toward the browser and the frontend.

When the Browser Is to Blame

A frontend issue begins after the server has already returned the HTML. The browser has received the page, but it still needs to load stylesheets, scripts, images, fonts, and external resources.

In this case, TTFB may be normal, but the user still experiences slow loading: the main section takes a long time to appear, the page shifts, buttons respond with a delay, and content is rendered gradually.

Common causes include large images, render-blocking JavaScript, unnecessary CSS, web fonts, ad scripts, maps, chat widgets, analytics, and social media widgets.

These issues cannot be fixed by upgrading the VPS. A more powerful server may return the HTML faster, but it will not reduce the size of the hero image, speed up a third-party ad script, or fix an unstable layout.

That is why it is important to separate the metrics. TTFB says more about the server and the backend. LCP, CLS, and INP usually help determine what is happening in the user’s browser.

For this, it is useful to look at the waterfall in DevTools.

How to read the waterfall in DevTools

The waterfall shows the order in which the browser loads page resources and how long each stage takes. You can open it in the Network tab of the browser’s developer tools.

Start by looking at the request for the main HTML document. If that request spends a long time waiting for a response, the problem is more likely on the server side: PHP, the database, the CMS, the code, the cache, or an external API.

If the HTML is delivered quickly, but images, CSS, JavaScript, fonts, and resources from external domains then take a long time to load, the cause is more likely on the frontend.

It is useful to look not only at the largest files, but also at dependency chains. Sometimes one script blocks another, a font delays text rendering, or an external widget creates a long wait before the page finishes loading.

The waterfall also helps identify third-party domains. If a slow resource is not loaded from your server, upgrading the VPS will not affect it directly.

This type of analysis helps you avoid confusing different kinds of slowdown. If the first response is slow, check the server, PHP, the database, and the code. If rendering is slow after a fast response, work on images, CSS, JavaScript, fonts, and external scripts.

Common Diagnostic Mistakes

Diagnostic mistakes are dangerous because they lead you away from the real root cause. A site may be slow due to the database, PHP, disk, an external API, or bots, while the owner is changing images, installing a caching plugin, or buying a more expensive VPS.

To avoid wasting time and money, it is important to check not just a single metric, but the entire chain: the browser, network, web server, PHP, database, CMS, and code.

Relying only on PageSpeed

PageSpeed is useful for assessing user-facing load performance, but it does not show the full server-side picture. The service can flag large images, render-blocking JavaScript, and LCP or CLS issues, but it will not always explain why PHP takes a long time to generate the page.

If a site receives a low score, that does not necessarily mean the issue is with the VPS. Conversely, a page may have acceptable frontend metrics but a high TTFB because of the database, the PHP-FPM queue, or an external API.

PageSpeed is best used together with server-side metrics. First, you need to determine where the delay occurs: before the server sends its first response, or only after the HTML has loaded in the browser.

If you rely on a single report, you may start optimizing CSS and images even though the site is slow because of slow queries or insufficient RAM.

Not checking logs

Logs often provide more information than visual speed tests. They show which requests are reaching the site, which errors keep recurring, which pages return 500, 502, or 504 responses, and where the backend fails to respond in time.

Without logs, diagnostics turn into guesswork. You might assume the site is slow because the VPS is underpowered, while the access log shows thousands of bot requests at that moment. Or you might think Nginx is to blame, while the error log shows PHP-FPM crashing.

At a minimum, you should check the web server access log and error log, PHP errors, the PHP-FPM slow log, and the MySQL slow log. For CMS platforms and frameworks, the application’s own logs are also important.

Logs do not always provide a ready-made answer, but they significantly narrow down the possible causes. Instead of “the site is sometimes slow,” you get specifics: which URL, which response code, which process, which query, and at what time.

Confusing frontend slowdowns with server-side issues

The user sees one general symptom: the site is slow. Technically, however, the delay can occur in different places.

If the server takes a long time to return the initial HTML, the issue is more likely to be related to the VPS, PHP, the database, the CMS, the code, or an external API. In this case, you need to check TTFB, PHP-FPM, MySQL, logs, and server resources.

If the HTML arrives quickly but the page takes a long time to render, the cause is more often on the frontend: images, CSS, JavaScript, fonts, ads, maps, widgets, and third-party scripts.

The mistake is treating these two scenarios in the same way. For example, upgrading the VPS plan when the page is slow because of a huge hero image. Or minifying CSS when the server takes two seconds to respond before the page even starts loading.

Distinguishing between backend and frontend issues helps you choose the right course of action. Server-side problems are investigated through metrics and logs, while frontend issues are analyzed using the waterfall, Core Web Vitals, and page resource analysis.

Moving Straight to a More Expensive VPS

Moving to a more powerful VPS is sometimes necessary, but it should be the result of diagnostics, not the first step.

If the CPU is consistently under heavy load, RAM is running out, swap is active, the disk cannot keep up, and the site has already been optimized, increasing resources can indeed resolve the issue.

But if the slowdown is caused by a resource-heavy plugin, a slow SQL query, an external API, a misconfigured cron job, or bot traffic, a new plan will only temporarily mask the root cause.

After some time, the site will start slowing down again because the inefficient code, database, or external dependencies will remain unchanged. They will simply have more resources available for the same inefficient work.

The correct sequence is different: first record the symptom, check the metrics, review the logs, identify the bottleneck, and only then decide whether a VPS upgrade is needed.

This turns diagnostics from a set of guesses into a clear process: from symptom to cause, and from cause to a specific solution.

Quick diagnostic checklist

If the site starts slowing down, first record the symptom: high TTFB, slow rendering, 502 or 503 errors, a slow admin panel, long-running requests, a sharp increase in load, or intermittent spikes.

Next, check the VPS:

  • top or htop — which processes are consuming CPU;
  • free -h — whether there is enough RAM and whether swap is being used;
  • df -h — whether disk space is running out;
  • iostat -xz 1 — whether there is high disk load and iowait;
  • network connections and the access log — whether there is a spike in requests, bots, or a DDoS attack.

After that, move on to the logs:

  • Nginx access log — which URLs are requested most often;
  • Nginx error log — whether there are 502, 504, or timeout errors, or backend issues;
  • PHP-FPM status — whether there is a queue and available worker processes;
  • PHP-FPM slowlog — which PHP code takes too long to execute;
  • MySQL slow log — which SQL queries are causing slowdowns;
  • CMS or application logs — whether there are fatal errors, recurring warnings, API timeouts, or cron errors.

Then separate the issue into backend and frontend. If the initial HTML response is slow, check the VPS, PHP, database, CMS, code, cache, and external APIs. If the HTML arrives quickly but the page takes a long time to render, check images, CSS, JavaScript, fonts, and third-party scripts.

Do not change multiple settings at the same time. After each action, measure again to understand what actually affected performance.

Conclusion

The cause of a slow website cannot be reliably determined from the vague impression that “the page takes a long time to load.” The same symptom may point to the VPS, the database, the CMS, the code, an external API, the frontend, cron jobs, bots, or disk issues.

That is why diagnostics should be performed systematically. First, identify the symptom; then check the server metrics, followed by the web server, PHP, database, and application logs. Only after that can you form a hypothesis and choose a solution.

PageSpeed, Core Web Vitals, and waterfall charts help you understand what the user sees in the browser. But they do not replace top, free, df, iostat, the access log, the error log, PHP-FPM status, or the MySQL slow log.

A VPS upgrade should be considered only when the metrics clearly show a resource shortage. If the site is slow because of slow queries, a heavy plugin, an infinite loop, an external API, or bots, a more expensive plan will not address the cause.

Good diagnostics do not start with buying a new server. They start with the question: where exactly does the delay occur, and which metric confirms it?

FAQ

What should you check first if a website has become slow?

First, determine where the delay occurs: before the server responds or in the user’s browser.

If the page waits a long time for the first response, check TTFB, the VPS, PHP-FPM, the database, cache, logs, and external APIs. If the HTML arrives quickly but the page renders slowly, check images, CSS, JavaScript, fonts, and third-party scripts.

For an initial check on a VPS, it is usually enough to open top or htop, check memory with free -h, available disk space with df -h, and disk I/O load with iostat, then move on to the Nginx, PHP-FPM, and MySQL logs.

The key is not to change everything at once. Start with the symptom, then review the metrics, form a hypothesis, and only then apply a fix.

How can you tell if RAM is insufficient?

Insufficient RAM is usually indicated by heavy swap usage. You can check memory with the following command: free -h

If available memory is low and swap is used continuously and keeps growing, the server does not have enough RAM. In this situation, the site may run slowly even when the CPU is not fully loaded, because some data is being moved to disk.

Insufficient RAM can also be indicated by 502 and 503 errors, MySQL crashes, processes being terminated by the OOM killer, a slow admin panel, and unstable site performance under load.

The cause should be investigated in the processes: PHP-FPM, MySQL, Redis, cron jobs, the control panel, backups, or other services running on the VPS.

What does a high TTFB mean?

A high TTFB means the browser waits a long time for the first byte of the server response. In other words, the issue occurs before the page has even begun to load properly.

The cause may be PHP, the database, the CMS, application code, an external API, the PHP-FPM queue, insufficient VPS resources, or a lack of caching.

If a high TTFB is observed across all pages, start with the VPS, PHP-FPM, MySQL, and caching. If only a specific page is slow, the issue is more likely in a particular module, SQL query, external integration, or section of code.

TTFB does not explain everything, but it is useful for distinguishing server-side delays from frontend issues.

Can the database slow down the entire site?

Yes, the database can slow down the entire site, especially if the CMS frequently queries MySQL or MariaDB on every request.

This often happens with online stores, catalogs, sites with user accounts, search, filters, a large number of records, or heavy plugins.

The issues may be related to slow queries, missing indexes, oversized tables, excessive autoloaded data, insufficient RAM, or a slow disk.

If the database responds slowly, it affects not only public pages but also the admin panel, cron jobs, imports, checkout, and API operations.

When is it really time to switch VPS plans?

You should switch VPS plans when diagnostics show a genuine shortage of resources and basic issues have already been ruled out.

Reasons to upgrade may include consistently high CPU usage, insufficient RAM, active swap usage, high iowait, slow disk performance, a PHP-FPM queue, or 502 or 503 errors under normal load.

But if the site is slow because of a heavy plugin, a slow SQL query, an external API, bots, an infinite loop, or the frontend, a more expensive VPS will not fully solve the problem.

The right sequence is: first review the metrics and logs, then eliminate the bottleneck, and only then decide whether to change the plan.

Sources

1. Nginx Documentation — Logging

2. Nginx Documentation — ngx_http_log_module

3. PHP Manual — FPM configuration

4. PHP Manual — Runtime configuration

5. MySQL Documentation — The Slow Query Log

6. MySQL Documentation — EXPLAIN Statement

7. Linux man-pages — top

8. Linux man-pages — free

9. GNU Coreutils — df invocation

10. Sysstat Documentation — iostat

11. Web.dev — Web Vitals

12. Google Search Central — Core Web Vitals

Subscribe to our newsletter and receive articles and news

    Check out our other materials

    Seraphinite AcceleratorOptimized by Seraphinite Accelerator
    Turns on site high speed to be attractive for people and search engines.