Era Host hosting
EraHost – Free Domain, Cheap Hosting!
Client Area
Support 24/7
Menu

How to Diagnose and Fix Server-Side Core Web Vitals Issues

27 min read
30.08.2026

Quick Summary

Many website owners begin improving Core Web Vitals by compressing images, removing JavaScript, or changing the site's theme. Sometimes that works, but not always. Support teams regularly see cases where several days of front-end optimisation produce almost no improvement in PageSpeed because the real bottleneck is much earlier in the request lifecycle. The server takes too long to generate the page, PHP spends excessive time processing requests, the database is overloaded, Redis is not being used, static assets are served without proper caching, or compression is disabled entirely.

Before making any changes, identify where the delay actually occurs. If Google PageSpeed Insights reports a high Initial Server Response Time and Chrome DevTools shows that most of the request time is spent in the Waiting (TTFB) phase on the Network tab, the problem is unlikely to be in the front end. Start by examining server response time, PHP-FPM performance, database execution, Redis object caching, HTTP cache headers, HTTP/2 or HTTP/3 support, and your SSL configuration. Only after these components have been verified should you move on to optimising images, CSS, and JavaScript.

This approach prevents one of the most common optimisation mistakes. Many administrators spend hours reducing image sizes to improve LCP while the server still needs more than a second just to generate the initial HTML document. Until that delay is removed, most front-end optimisations deliver far less benefit than expected. When working on Core Web Vitals, the first priority should always be making sure the server generates and delivers HTML as quickly as possible. Only then does it make sense to optimise everything the browser loads afterwards.

During performance investigations at Era.Host, this order of diagnosis often identifies the real cause within minutes, avoiding hours spent optimising resources that were never responsible for the poor Core Web Vitals scores in the first place.

Article plan

How to Measure TTFB and Determine Whether the Server Is the Problem

If Google PageSpeed Insights reports a slow Initial Server Response Time or poor LCP, don't start by changing your site's theme or compressing images. The first step is to identify where the delay actually occurs. In many cases, the browser spends a second or more simply waiting for the first byte of HTML. At that stage, CSS, JavaScript, images, and fonts have not even started loading. When that happens, the bottleneck is almost always on the server or within the application itself.

Start with Google PageSpeed Insights. If the report includes the recommendation Reduce initial server response time or shows an unusually high Initial Server Response Time, open the same page in Chrome DevTools. Go to the Network tab, disable the browser cache, reload the page, and select the initial HTML request. Open the Timing tab and look at the Waiting (TTFB) phase. This value shows how long the browser waited between sending the request and receiving the first byte of data from the server.

Next, measure TTFB directly with curl. This removes the browser, extensions, and DevTools interface from the equation, making it easier to assess the server itself.

curl -o /dev/null -s -w \
"DNS: %{time_namelookup}\n\
Connect: %{time_connect}\n\
TLS: %{time_appconnect}\n\
TTFB: %{time_starttransfer}\n\
Total: %{time_total}\n" \
https://example.com/

Review each value individually rather than looking only at the total time. time_namelookup measures DNS resolution, time_connect shows how long it takes to establish the TCP connection, time_appconnect measures the TLS handshake for HTTPS, time_starttransfer is the actual TTFB, and time_total is the complete request duration. If DNS, TCP, and TLS complete quickly but time_starttransfer is significantly higher, the delay is happening while the server is generating the page.

Do not limit testing to the homepage. Run exactly the same command against several URLs. Check the homepage, a product category, a product page, the login page, and a dynamic page such as search results or a filtered catalogue. Execute each test several times. If the homepage consistently returns a TTFB of 180–250 ms while product pages take 900–1200 ms, the problem is almost certainly in dynamic page generation rather than the network or hosting infrastructure.

If the numbers vary between tests, repeat the measurements at different times of day. Test during the morning, afternoon, and evening using the same URLs. Large fluctuations in TTFB often point to resource contention, an overloaded database, PHP-FPM process exhaustion, or scheduled background jobs consuming CPU and I/O during specific periods.

While testing, inspect the server logs at the same time. Open the Nginx error log and the PHP-FPM log, then look for messages such as upstream timed out, PHP slow log entries, or warnings that all PHP-FPM workers are busy. If those errors appear while TTFB is high, there is little value in optimising images or front-end assets until the HTML generation delay has been resolved.

The diagnosis is complete once you have measured TTFB using multiple methods and compared several page types. If time_starttransfer remains consistently high in both Chrome DevTools and curl, while static assets load quickly, the bottleneck is usually PHP execution, database performance, server-side caching, or the server configuration itself. Only after reducing that delay should you move on to optimising images, CSS, JavaScript, and the remaining factors that influence Core Web Vitals.

How to Distinguish Network Latency from Slow Page Generation

When a website starts responding slowly, it's easy to assume PHP or the database is to blame. In reality, the delay may occur before the server even begins generating HTML. Slow DNS resolution, a lengthy TCP connection, TLS handshake delays, or poor network routing can add hundreds of milliseconds before the application receives the request. Before optimising the wrong part of the stack, determine exactly where the time is being spent.

Start by measuring the request with curl. Run the following command against the homepage and save the results.

curl -o /dev/null -s -w \
"DNS: %{time_namelookup}\n\
Connect: %{time_connect}\n\
TLS: %{time_appconnect}\n\
TTFB: %{time_starttransfer}\n\
Total: %{time_total}\n" \
https://example.com/

Examine each timing separately. If time_namelookup is unusually high, investigate your DNS provider. If time_appconnect takes significantly longer than expected, inspect your TLS configuration, certificate chain, or SSL settings. If both values are low but time_starttransfer accounts for most of the delay, the server is spending too much time generating the page, and the investigation should move to PHP, the database, or application logic.

The next step is to compare static and dynamic content. Run the same TTFB test against a CSS file, an image, and the HTML page.

curl -o /dev/null -s -w "TTFB: %{time_starttransfer}\n" https://example.com/style.css
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}\n" https://example.com/images/logo.webp
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}\n" https://example.com/

Now compare the results. If the CSS file and image begin downloading almost immediately while the HTML page has a much higher TTFB, the network is performing normally and the delay starts after the request reaches the application. Common causes include slow PHP execution, expensive SQL queries, missing object caching, exhausted PHP-FPM workers, or resource-intensive background jobs.

If both static files and HTML respond slowly, continue with network diagnostics. Run traceroute or mtr from one or more locations if possible.

traceroute example.com

or

mtr example.com

Look for high latency, packet loss, or unstable routing. Repeat the same tests from different geographical locations using remote servers or external testing platforms. If every resource is slow regardless of file type or test location, the issue is more likely to be related to network connectivity, web server configuration, an overloaded physical host, or data centre infrastructure rather than the application itself.

At the same time, inspect the request breakdown in Chrome DevTools. Open the Network tab, select the HTML document, and compare the time spent in DNS Lookup, Initial Connection, SSL, Waiting (TTFB), and Content Download. The browser timeline should closely match the values reported by curl. If both tools indicate that the delay occurs during Waiting (TTFB), your investigation should focus on server-side processing rather than networking.

The diagnosis is complete once you have separated connection latency from page generation time. If static assets consistently respond much faster than dynamic HTML, continue investigating PHP, MySQL or MariaDB, Redis, PHP-FPM, and server-side caching. If every request is slow regardless of content type, resolve the network, TLS, web server, or infrastructure issues before spending time optimising the application itself.

How to Improve LCP with Gzip or Brotli Compression

When Google PageSpeed reports a poor LCP score, many administrators immediately start compressing images or deferring JavaScript. Quite often, the real bottleneck appears much earlier. The browser spends too long downloading the HTML, CSS, and JavaScript because the server either serves them uncompressed or uses an inefficient compression configuration. This is particularly noticeable on mobile devices and slower network connections, where a few hundred extra kilobytes can significantly delay the first screen from rendering.

Start by checking whether compression is enabled at all. If your server uses Nginx, review the configuration and verify that gzip or brotli is enabled. On Apache, make sure mod_deflate or mod_brotli is loaded and active. If compression is configured through .htaccess, confirm that the required directives are present. Compression should be applied to HTML, CSS, JavaScript, SVG, XML, and JSON responses. At the same time, verify that the server is not attempting to compress JPEG, PNG, WebP, AVIF, ZIP, MP4, or other formats that are already compressed. Recompressing these files rarely reduces their size and simply wastes CPU resources.

Once you have updated the configuration, validate it before restarting the web server. For Nginx, run:

nginx -t

If the configuration passes validation, reload or restart the service.

systemctl restart nginx

For Apache, first check the configuration:

apachectl configtest

If no errors are reported, restart Apache.

systemctl restart apache2

Do not stop after restarting the service. Confirm that browsers are actually receiving compressed responses. Open the site in Chrome, launch DevTools, switch to the Network tab, disable the browser cache, and reload the page. Select the HTML document, a CSS file, or a JavaScript file, then inspect the Headers section. Look for the Content-Encoding response header. Text-based resources should display either gzip or br. If the header is missing, the file is still being transferred uncompressed regardless of the server configuration.

Next, compare the amount of data being transferred. In DevTools, examine the Transferred and Resource Size columns. For HTML, CSS, and JavaScript, the transferred size should be noticeably smaller than the original resource size once compression is working. If both values remain almost identical, compression is either disabled or not being applied to the correct content types.

After enabling compression, repeat the same performance tests. Run Google PageSpeed Insights again and measure the page in DevTools using the same URL as before. Compare the loading time for the HTML document, CSS, and JavaScript files. If those resources download more quickly and the LCP score improves without changing images or the site's theme, the bottleneck was data transfer rather than PHP execution or browser rendering.

The configuration can be considered successful if HTML, CSS, JavaScript, SVG, XML, and JSON responses include the Content-Encoding: gzip or Content-Encoding: br header, transferred file sizes are smaller than the original resources, already compressed images and media are excluded from compression, and both PageSpeed Insights and DevTools show shorter download times for the resources that contribute to LCP. At that point, the server is delivering content more efficiently, allowing the browser to render the first screen sooner.

How to Configure Cache-Control and Expires for Static Assets

If Google PageSpeed repeatedly recommends Serve static assets with an efficient cache policy, don't assume the problem lies with your CMS or CDN. In many cases, the browser simply isn't being told how long it can cache CSS, JavaScript, images, fonts, and other static resources. As a result, returning visitors download the same files every time they open a page, while the server continues to process identical requests that could have been avoided.

Start by checking which cache headers your server is already sending. Open your website in Chrome, launch DevTools, go to the Network tab, and perform a full page reload. Select a CSS file, JavaScript file, image, or font, then inspect the Headers section. Look for the Cache-Control and Expires response headers. If they are missing, or if you see values such as no-cache or max-age=0, the browser has no choice but to request those files again on every visit, even if they rarely change.

The next step is to configure caching on the web server itself. For Nginx, add cache rules for static file types. For Apache, configure mod_expires together with mod_headers. If the project relies on .htaccess, make sure the relevant directives are actually being applied. Resources that use versioned filenames, such as style.8f4c21.css or app.2d71.js, can safely be assigned long cache lifetimes. Whenever the file changes, the filename or version string changes as well, causing browsers to download the updated version automatically instead of using an outdated cached copy.

Once the configuration has been updated, validate it before restarting the web server. For Nginx, run:

nginx -t

If the configuration is valid, restart the service.

systemctl restart nginx

For Apache, first verify the configuration.

apachectl configtest

If the test succeeds, restart Apache.

systemctl restart apache2

Now confirm that the changes are actually working. Open DevTools, go back to the Network tab, and load the same page twice. During the second load, check where the browser retrieves the static assets. CSS, JavaScript, images, and fonts should show disk cache or memory cache in the Size or Transferred column. Open the response headers again and verify that the server is returning the expected Cache-Control value with an appropriate max-age.

It is also worth checking the response directly with curl.

curl -I https://example.com/css/style.css

The response should include a valid Cache-Control header and, where applicable, an Expires header. If these headers are missing, browsers will continue requesting the file from the server regardless of any caching settings configured within the CMS.

The configuration can be considered successful if repeat page loads retrieve static assets from disk cache or memory cache, the server consistently returns the expected Cache-Control and Expires headers, and Google PageSpeed no longer reports inefficient browser caching. At that point, repeat visits require significantly less data transfer, page load times improve for returning users, and the server handles far fewer requests for files that have not changed.

Linux VDS
High performance for your projects
  • Root access and flexible setup
  • Control panel
  • NVMe disks
  • DDR5
Linux VDS

How to Enable Redis Object Cache for WordPress and Other CMS Platforms

If Google PageSpeed reports a high Initial Server Response Time, the WordPress dashboard feels sluggish, or TTFB continues to increase despite low traffic, don't assume you need a larger server. In many cases, the real bottleneck is the database. Every page request forces the CMS to execute dozens or even hundreds of identical SQL queries, even though the results rarely change. This is particularly common in WordPress with WooCommerce, OpenCart, Drupal, and other dynamic platforms where menus, product catalogues, configuration data, and user information are repeatedly loaded from MySQL or MariaDB.

Start by confirming that Redis is installed and running. Connect to the server via SSH and check the service status.

systemctl status redis

If Redis is not installed, install it using your Linux distribution's package manager, enable it to start automatically during boot, and verify that the service enters the active (running) state after a reboot.

The next step is to connect your application to Redis. For WordPress, install the Redis Object Cache plugin, open its settings page, and enable object caching. For Laravel, configure Redis in the .env file, clear the configuration cache, and restart the application. For other CMS platforms and frameworks, enable the Redis cache driver in the application's cache configuration and verify that it replaces file-based caching or direct database lookups.

Do not assume the job is finished just because the Redis service is running. A common support issue is a Redis server that is healthy while the application continues querying MySQL because of an incorrect cache driver, a missing PHP Redis extension, connection failures, or object caching simply not being enabled. Until you confirm that the application is actively using Redis, the configuration is incomplete.

Begin the verification from the command line.

redis-cli ping

The expected response is:

PONG

Next, confirm that Redis is actually storing application data.

redis-cli info stats

Review the keyspace_hits and keyspace_misses counters. After browsing several pages, the number of cache hits should steadily increase. If the counters barely change, the application is probably bypassing Redis and continuing to query MySQL directly.

The next step is to compare database activity before and after enabling object caching. On WordPress, this is easy with Query Monitor. Open the same page with Redis disabled and note the number of SQL queries together with the page generation time. Then enable Redis Object Cache, clear the application cache, reload exactly the same page, and compare the results. Repeated database queries should decrease noticeably.

Now measure the page again using Chrome DevTools or curl and compare the TTFB with the previous test. If Redis is working correctly, HTML generation should become more consistent and the Waiting (TTFB) phase should decrease. At the same time, inspect the MySQL or MariaDB slow query log. After object caching has been enabled, repeated slow queries often become far less frequent.

The configuration can be considered successful if the Redis service is in the active (running) state, redis-cli ping returns PONG, keyspace_hits continues to increase during normal browsing, the CMS is demonstrably using Redis Object Cache, the number of SQL queries is lower than before, and TTFB for the same page becomes both shorter and more consistent. At that point, Redis is doing more than simply running as another service on the server. It is actively reducing database load and accelerating the generation of dynamic pages.

How to Check PHP-FPM and the Database When INP or TTFB Remain High

If Redis is already enabled, Gzip or Brotli compression is working, browser caching is configured correctly, and Google PageSpeed still reports a high TTFB or poor INP score, the bottleneck is likely deeper in the server stack. Support engineers often find that PHP workers remain busy for too long, request queues gradually build up, or a handful of expensive database queries block other requests from completing. From the user's perspective, the site simply feels slow, while the real cause lies in the server environment.

Start by checking the PHP-FPM service. Connect to the server via SSH and confirm that the service is running correctly.

systemctl status php-fpm

On Ubuntu, the service name may include the PHP version.

systemctl status php8.3-fpm

If the service is repeatedly restarting or reports a failed status, resolve that issue before continuing. Once PHP-FPM is running normally, inspect its recent log entries.

journalctl -u php-fpm -n 100

Look carefully for recurring messages such as:

server reached pm.max_children
upstream timed out
child exited
Allowed memory size exhausted

Each message points to a different problem. server reached pm.max_children means every PHP worker is busy and new requests are waiting in the queue. upstream timed out indicates that PHP could not finish processing before the web server timeout expired. Allowed memory size exhausted shows that PHP ran out of memory, while repeated child exited messages may indicate crashes or unstable processes.

The next step is to examine the PHP-FPM slow log. If it is not already enabled, configure slowlog and set a sensible request_slowlog_timeout value for the relevant PHP-FPM pool. Restart PHP-FPM, reproduce the slow operation, and inspect the log again. Open the same product page, perform the same catalogue search, or run the same import process that users report as slow. If the slow log repeatedly records the same PHP scripts, the bottleneck is no longer the server itself but the application code or one of its extensions.

Now move to the database. Open the MySQL or MariaDB slow query log and identify the queries consuming the most time. Look for expensive SELECT statements with multiple JOIN operations, large table scans, filesorts, or long-running UPDATE statements during imports. These queries can dramatically increase HTML generation time. Redis may reduce repeated database lookups, but it cannot compensate for poorly optimised SQL that must still be executed.

While reproducing the issue, monitor the server in real time. In one terminal window, run:

top

or

htop

In a second terminal, monitor storage performance.

iostat -x 1

Then monitor memory and process activity.

vmstat 1

Watch several metrics simultaneously while the slow operation is running. If CPU utilisation remains low but iowait becomes consistently high, the server is waiting on storage rather than processing requests. If swap usage starts increasing, the system no longer has enough physical memory for the workload. If one or more PHP processes remain active much longer than the others, the delay is usually caused by slow application code or expensive database queries.

Do not forget to inspect the web server log.

tail -100 /var/log/nginx/error.log

Repeated messages such as upstream timed out, connect() failed, or recurring PHP-FPM connection errors indicate that Nginx is spending an excessive amount of time waiting for the application to respond.

The investigation is complete once you can identify exactly where the delay occurs. If the PHP-FPM slow log consistently records the same scripts, the MySQL or MariaDB slow query log highlights the same SQL statements, pm.max_children is no longer being exhausted, swap remains unused, iowait stays low, and both the Nginx and PHP-FPM logs are free from repeated upstream timed out errors, you have identified the root cause. Only then should you decide whether the next step is optimising application code, improving database indexes, adjusting PHP-FPM settings, or increasing server resources.

How to Enable HTTP/2 and Verify the TLS Handshake

A website running over HTTPS is not necessarily using the connection efficiently. During performance investigations, it is common to find browsers opening multiple separate connections, CSS, JavaScript, and font files loading more slowly than expected, and Google PageSpeed reporting delays related to resource delivery. Before looking for problems in the application, verify that the server is actually using HTTP/2 and that the TLS connection is configured correctly.

Start by checking your web server configuration. If you are using Nginx, open the virtual host configuration and confirm that the HTTPS listener includes the http2 parameter.

listen 443 ssl http2;

If the server runs Apache, verify that the mod_http2 module is enabled and that the configuration contains the following directive.

Protocols h2 http/1.1

After making any changes, validate the configuration before restarting the service. For Nginx, run:

nginx -t

If no errors are reported, restart Nginx.

systemctl restart nginx

For Apache, first validate the configuration.

apachectl configtest

If the test succeeds, restart Apache.

systemctl restart apache2

The next step is to verify that the website is actually serving traffic over HTTP/2. Run the following command:

curl -I --http2 https://example.com

If the connection succeeds, the response should be served over HTTP/2. If the command fails or the server still responds using HTTP/1.1, check whether your installed web server version supports HTTP/2 and confirm that the feature has not been disabled by the TLS configuration.

Now verify the browser's behaviour. Open the website in Chrome, launch DevTools, switch to the Network tab, and enable the Protocol column if it is not already visible. Reload the page and inspect the requests for the HTML document, CSS, JavaScript, fonts, and images. They should all display h2 in the Protocol column. If you still see http/1.1, the browser is not using HTTP/2 despite the server configuration.

At the same time, inspect the TLS certificate. Click the padlock icon in the browser's address bar and confirm that the certificate is valid and trusted. Check that the complete certificate chain is installed correctly. An incomplete chain or certificate configuration issues can increase connection setup time and may even cause certificate validation failures for some clients.

It is also worth measuring the TLS handshake directly with curl.

curl -o /dev/null -s -w \
"TLS: %{time_appconnect}\n\
TTFB: %{time_starttransfer}\n" \
https://example.com/

Review the results carefully. If time_appconnect is significantly higher than expected while the remaining stages complete quickly, investigate the TLS configuration, OpenSSL version, certificate chain, supported cipher suites, and web server settings before looking elsewhere.

The configuration can be considered successful if Nginx or Apache validates without errors, curl --http2 confirms HTTP/2 support, Chrome DevTools shows the h2 protocol for page resources, the TLS certificate is trusted without warnings, and the TLS handshake completes quickly. At that point, you can be confident that HTTPS configuration is not introducing unnecessary latency and that the browser is using modern protocols to download page resources as efficiently as possible.

How to Decide Whether Your Website Needs HTTP/3

If Redis is already configured, PHP-FPM has been tuned, HTTP/2 is enabled, compression is working, and browser caching is correctly configured, yet some users still report slow page loads, don't rush to enable HTTP/3. Support engineers regularly see administrators expecting one new protocol to solve a performance problem when the real bottleneck is still HTML generation or slow database queries. HTTP/3 can reduce the impact of unstable network conditions, but it will not speed up slow PHP execution or compensate for an inefficient CMS.

Start by confirming that HTTP/2 is working correctly. Verify that the server is delivering content over HTTP/2, your TLS configuration is healthy, static assets are cached properly, Gzip or Brotli compression is enabled, and TTFB is already within an acceptable range. If server response time remains high, resolve that issue first. HTTP/3 is worth considering only after the server is generating pages quickly and the remaining delays occur during data transmission across the network.

The next step is to verify whether your infrastructure actually supports HTTP/3. If you use a CDN, open its management console and confirm that HTTP/3 support is enabled. If the website runs directly on a VPS, check the documentation for your web server and verify that your installed version of Nginx, OpenLiteSpeed, or another supported server includes HTTP/3 and QUIC support. At the same time, confirm that UDP traffic is permitted on port 443, as HTTP/3 relies on QUIC rather than TCP.

Once HTTP/3 has been enabled, verify that browsers are actually using it. Open the website in Chrome, launch DevTools, switch to the Network tab, and enable the Protocol column if it is not already visible. Reload the page several times. If the configuration is correct, the HTML document and most resources should display h3 as the protocol. If you continue to see h2 or http/1.1, the browser is still falling back to the previous protocol.

If your version of curl includes HTTP/3 support, perform an additional verification from the command line.

curl --http3 -I https://example.com

If the command succeeds and the server responds normally, HTTP/3 is available. If the connection cannot be established, check your web server configuration, confirm that QUIC support is enabled, and verify that your firewall allows UDP traffic on port 443.

The final evaluation should not be performed only from a wired office connection. HTTP/3 provides its biggest advantages on unstable or high-latency networks. Test the same page over a wired connection, a home Wi-Fi network, and a mobile network. Measure TTFB, total page load time, and overall responsiveness under each condition. If packet loss or fluctuating network quality has less impact, page loads become more consistent, and repeated retransmissions decrease without increasing TTFB, HTTP/3 is delivering a measurable benefit. If performance remains unchanged, the remaining bottleneck is most likely within the application or server rather than the transport protocol.

The deployment can be considered successful if Chrome DevTools reports the h3 protocol, curl --http3 connects successfully, HTTP/2 remains available as a fallback for clients without HTTP/3 support, and testing across mobile and unstable networks shows more consistent page loading without an increase in TTFB. At that point, HTTP/3 is improving content delivery rather than simply being another enabled feature in the server configuration.

How to Choose a Hosting Package for Better Core Web Vitals

After measuring TTFB, tuning PHP-FPM, enabling Redis, configuring HTTP/2 or HTTP/3, and setting up compression and browser caching, it usually becomes clear that website performance depends on much more than the CMS itself. At this stage, further optimisation is often limited by the capabilities of the hosting infrastructure. If your hosting platform does not support current PHP versions, Redis, high-performance NVMe storage, or flexible PHP-FPM configuration, maintaining consistently good Core Web Vitals becomes increasingly difficult regardless of how well the application is written.

Before you choose a hosting package, identify the limitations that are already affecting your project. If PageSpeed consistently reports a high TTFB, PHP-FPM regularly reaches its process limits, the database becomes the main source of latency, or Redis Object Cache is unavailable because of hosting restrictions, disk space is not the real issue. The platform itself has become the bottleneck, and that is what should be evaluated first.

Begin by reviewing the software environment. Confirm that the hosting plan supports current PHP releases and allows timely upgrades without long delays. Check whether Redis Object Cache is available, whether HTTP/2 and HTTP/3 are supported, whether the platform uses NVMe storage, and whether PHP settings can be adjusted when the application requires higher memory limits or longer execution times.

Next, evaluate the resources that have the greatest impact on Core Web Vitals. Do not focus only on CPU cores and RAM. Look at storage performance, database responsiveness, support for object caching, and whether the platform provides enough resources for PHP-FPM to handle concurrent requests efficiently. On dynamic websites, these components have a much greater influence on HTML generation speed and TTFB than raw storage capacity.

It is equally important to examine the operational capabilities of the platform. Check whether automatic backups are included, whether memory, CPU resources, or storage can be upgraded without migrating the website, whether server logs are accessible for troubleshooting, whether current versions of MySQL or MariaDB are available, and whether the hosting environment provides the tools needed to diagnose performance issues without relying on technical support for every investigation.

Before making the final decision, perform a practical assessment. Ask yourself a few questions. Does the hosting plan support Redis? Can you run the latest PHP version? Are HTTP/2 and HTTP/3 available? Does it use NVMe storage? Is there enough RAM for PHP-FPM, the database, and object caching? Can the server be scaled without migrating the project? Are automatic backups included? Can you access the logs and diagnostic tools needed to troubleshoot performance problems? If the answer to any of these questions is no, those limitations are likely to affect your Core Web Vitals as the project grows.

A well-chosen hosting package is defined not by the amount of disk space it offers, but by how effectively its infrastructure supports fast page generation and delivery. A platform that provides modern PHP versions, Redis, HTTP/2, HTTP/3, NVMe storage, a high-performance database environment, reliable backups, and straightforward scalability will help maintain strong Core Web Vitals not only when the site launches, but also as traffic, content, and application complexity continue to increase.

Frequently asked questions
TTFB (Time to First Byte) measures the time between the browser sending a request and receiving the first byte of the server's response. During this period, DNS resolution, TCP connection establishment, the TLS handshake, PHP execution, database queries, and HTML generation all take place. If the server does not begin returning HTML for 800–1500 ms, the browser cannot start downloading the remaining resources, which often leads to poorer LCP and other Core Web Vitals metrics.
Connect to your server via SSH, or run the following command from any computer with curl installed. curl -o /dev/null -s -w "DNS: %{time_namelookup}\nTCP: %{time_connect}\nTLS: %{time_appconnect}\nTTFB: %{time_starttransfer}\nTotal: %{time_total}\n" https://example.com Run the test several times against different pages, including the homepage, product pages, category pages, and other dynamic URLs. If time_starttransfer is consistently much higher than for static assets, the bottleneck is usually within the application or server rather than the network.
Measure TTFB first, then open Chrome DevTools and examine the Waiting (TTFB) phase on the Network tab. If the delay occurs before CSS, JavaScript, fonts, or images even begin downloading, investigate PHP-FPM, the database, Redis, server logs, and resource utilisation. If HTML is delivered quickly but the page still loads slowly, the bottleneck is more likely to be in the front end.
Yes, provided the main bottleneck is slow page generation. Redis reduces repeated database queries by storing frequently requested objects in memory, allowing HTML pages to be generated more quickly and reducing TTFB. After enabling Redis, verify the configuration with redis-cli ping, confirm that the application is actually using Redis, and compare both TTFB and SQL query counts before and after the change.
If both the server and browsers support Brotli, it is generally the better option because it compresses text-based resources more efficiently. If Brotli is unavailable, Gzip still provides a significant improvement over serving uncompressed content. After enabling compression, open Chrome DevTools, go to the Network tab, and confirm that the Content-Encoding header contains either br or gzip.
Long cache lifetimes are typically appropriate for versioned CSS, JavaScript, images, fonts, SVG files, and other static assets. HTML pages usually require shorter cache lifetimes because their content changes more frequently. After configuring browser caching, reload the page and confirm in DevTools that static assets are being served from disk cache or memory cache.
Images are not always the reason for a poor LCP score. If the server takes too long to generate HTML, the browser cannot even discover which image should be loaded first. In that situation, optimise server response time by checking TTFB, PHP-FPM, database performance, and server-side caching before focusing on image optimisation.
The simplest method is to run: curl -I --http2 https://example.com If the server supports HTTP/2, the command should complete successfully. You can also open Chrome DevTools, go to the Network tab, enable the Protocol column, and verify that resources are being delivered over h2.
Not necessarily. First ensure that HTTP/2, Redis, PHP-FPM, browser caching, compression, and TTFB have already been optimised. HTTP/3 can improve performance on mobile and unstable networks, but it will not speed up slow PHP execution, database queries, or an inefficient CMS. After enabling it, verify that DevTools reports the h3 protocol and compare page loading behaviour under real network conditions.
Begin by measuring TTFB with both curl and Chrome DevTools. Then inspect PHP-FPM logs, the database slow query log, Redis usage, CPU utilisation, available memory, and swap activity. If HTML generation is slow, resolve that issue before optimising CSS, JavaScript, or images.
Test multiple pages at different times of day. If TTFB remains high even after optimising the application, PHP-FPM repeatedly reaches its limits, Redis is functioning correctly, the database is healthy, and the server still responds slowly, the hosting infrastructure may be the limiting factor. If possible, compare the same application on a different server or hosting plan to confirm the diagnosis.
Look beyond storage capacity and CPU specifications. Check whether the hosting platform supports current PHP versions, Redis Object Cache, HTTP/2, HTTP/3, NVMe storage, sufficient memory for PHP-FPM and database workloads, reliable backups, and straightforward resource scaling. These infrastructure capabilities usually have a far greater impact on maintaining low TTFB and consistently strong Core Web Vitals than the advertised disk space or processor count alone.
Related articles
How a Linux VPS Improves Website Performance
Solving apache_request_headers Issues on NGINX: A Professional Server Administrator's Guide
Unable to Resolve Target System Name with Tracert: Steps to Resolve