Technology

Website Slow at Certain Hours? CPU, IO and MySQL

If your website is fast for most of the day but slows down at particular hours, record when it happens and which operation is affected. CPU or disk limits, database waits, traffic, scheduled jobs and external services are possible causes. A timestamped pattern helps you investigate; it does not establish the cause on its own.

In this article, we’ll walk through a troubleshooting approach for both shared hosting and VPS servers. You’ll learn how to recognize whether your bottleneck is CPU, disk IO or MySQL, which tools and panels to look at, and what to change in your application or hosting plan. We’ll stay practical: concrete metrics, control-panel graphs and SSH tools, and a checklist you can follow next time your site slows down at the same hour again.

Why Your Website Is Only Slow at Certain Hours

Persistent and periodic slowdowns can both involve code, resources, caching or external dependencies. For a repeating time window, compare the workload and the system state during normal and slow periods. Include scheduled tasks and infrastructure activity in that comparison.

Patterns to investigate include:

  • Peak visitor traffic: Lunch or evening peaks where CPU and MySQL connections spike simultaneously.
  • Shared hosting “neighbor noise”: Other accounts on the same server run backups, imports or cron jobs at predictable times.
  • Your own scheduled tasks: WordPress/WooCommerce crons, report generation, feeds, or synchronizations stacked at the same minute every hour.
  • Backup and antivirus windows: Full-server backups and malware scans can stress disk IO and CPU while running.
  • External systems: Payment gateways, shipping APIs or CRM integrations that respond slowly under their own peak load.

To fix the issue properly, you need to answer three questions:

  1. Exactly when is the site slow?
  2. Which resource or dependency is constrained at those times (CPU, IO, MySQL, memory, connections, external services)?
  3. What workload is causing that spike (visitors, bots, backups, crons, imports)?

Once you map the timing to a resource and a workload, the right solution (optimize, spread out tasks, cache better, or upgrade) becomes much clearer.

Step 1 – Confirm the Slowdown Pattern with Real Measurements

Before jumping into server metrics, confirm the pattern from the browser side. Time-based slowdowns can easily be masked by caching, or misinterpreted if you only test occasionally.

Use proper speed test tools at different hours

Run tests at different times of the day from tools such as GTmetrix, PageSpeed Insights or WebPageTest. Keep the tested URL, test location, device profile and cache conditions as consistent as possible. Compare individual test runs rather than historical aggregate metrics when investigating specific hours. We explain how to interpret these tools in detail in our guide on how to properly test your website speed.

Track at least:

  • TTFB (Time To First Byte) – time until the first response byte arrives. A spike warrants investigating server processing and the network path; it does not by itself prove a server-side bottleneck.
  • Fully loaded time – how long until all assets are loaded.
  • Number of requests and transferred bytes – whether the page’s request count or download size changes. Neither metric alone establishes a server capacity issue.

If front-end assets and total size are similar but TTFB jumps from, say, 200 ms to 2–3 seconds in peak hours, investigate CPU/IO/MySQL constraints and correlate them with server metrics before drawing a conclusion. You can also dive deeper into server-side causes in our article on fixing high TTFB on WordPress and PHP sites.

Correlate slow times with your business and tasks

Make a simple timeline:

  • When do visitors usually peak? (analytics)
  • When do you run imports, exports, feed generation or reports?
  • When do your email campaigns land in inboxes and drive traffic?
  • When are your backup jobs scheduled (site or external tools)?

Record the time zone for browser tests, panel graphs, OS metrics and database logs. Analytics sessions are not identical to server requests: bots, blocked tracking and cache paths can produce different counts. Compare request paths, durations and errors as well as total traffic and scheduled-job times.

Step 2 – Check CPU and PHP Bottlenecks on Shared Hosting and VPS

CPU is a useful starting point when a website slows down at defined hours. On PHP-based sites (WordPress, WooCommerce, Laravel, custom PHP), requests that execute PHP can consume substantial CPU under load; static files and pages served directly from a full-page cache may bypass PHP.

On shared hosting: read your control panel resource graphs

If your hosting panel provides a “Resource Usage” or “CPU and Concurrent Connections” section, use it to inspect account-level limits. We’ve explained those graphs in detail in our article understanding cPanel resource limits and the ‘Resource Limit Reached’ error.

During or right after a slowdown, open that page and look for:

  • CPU / SPEED: Compare usage with the actual allowance. CloudLinux SPEED uses 100% for one core of capacity; a panel may instead normalize a percentage to the package limit.
  • Entry Processes (EP): Counts entries into an LVE, not every child created inside it. Apache mod_hostinglimits can return 508 when a CGI/PHP request cannot enter. LiteSpeed accounting differs: in workgroup mode an lsphp master can fork children without increasing EP for each child. EP is not a visitor count, total PHP worker count or automatic queue guarantee.
  • NPROC: Limits processes and threads within the LVE. Once full, it prevents new process creation and can produce 500/503 failures. It is separate from PHP-FPM pool settings.
  • Physical memory: Review account PMEM and fPMEM. If reclaiming disk cache is insufficient, CloudLinux can terminate processes. PHP memory_limit is a different limit.
  • Faults: Match usage, limits, available maxima and fault counts to the incident and application logs. HTTP 503 or 508 alone does not identify a resource or root cause.

When CPU reaches the actual allowance during slow periods, investigate whether throttling contributes to the user-visible delay. An EP fault does not establish CPU saturation. Confirm the web server and PHP handler, and inspect what keeps entries active. These CloudLinux descriptions apply where that integration is enabled; cPanel alone does not provide the limits.

On a VPS: use SSH tools like top/htop

On a dedicated server or VPS where you have the necessary access, collect process and resource observations during the incident. A VPS does not expose the entire physical host. Start with:

top

or, if installed,

htop

Key things to look at while the slowdown is happening:

  • CPU usage: Compare the incident with a representative baseline and identify runnable work; one fixed 80–90% threshold is not a universal diagnosis.
  • Per-core use: A busy core can matter even when others are idle. Identify the process and its work before attributing it to PHP-FPM settings.
  • Processes and waits: Inspect the actual PHP, web-server and database processes alongside memory, IO and, for a VM, steal time. A high load average includes runnable and uninterruptible work; it is not a CPU percentage.

For PHP-FPM, pm selects the process-manager mode, pm.max_children limits simultaneously served requests, and pm.max_requests controls how many requests a child handles before respawning. Use a restricted FPM status endpoint to compare listen queue, active/idle processes and max children reached with the incident; do not expose it publicly. Interpret cumulative values against an earlier sample and the FPM restart time. More hosting articles are available on the DCHost blog. Too few available workers can contribute to queuing, while excessive concurrency can exhaust memory or increase CPU/database contention. These are separate from CloudLinux EP and NPROC.

What CPU saturation usually looks like from the website

These browser-side symptoms can accompany CPU issues in peak hours, but also occur with other bottlenecks. Correlate them with CPU metrics:

  • TTFB rises while directly served static assets remain quick.
  • Dynamic administration is slower than a confirmed full-page cache hit.
  • Errors occur under load. CPU/IO throttling, Apache EP refusal, memory/process limits, application failures and upstream timeouts need separate evidence; do not label every 503/508 as a CPU error.

Quick CPU-related mitigations on shared hosting

On a shared plan, you cannot directly add more CPU cores, but you can reduce peak CPU usage:

  • Caching: Test eligible public-page hits, invalidation and exclusions for login, account, cart, checkout, authorization and personalized responses. LiteSpeed Cache needs a compatible enabled server component or appropriate QUIC.cloud service; installing the plugin alone does not establish page caching.
  • Expensive components: Profile plugins and server-side calls, then compare changes in staging. Do not broadly disable payment or security features to reduce a graph.
  • Scheduled work: Verify the replacement scheduler before disabling page-triggered WP-Cron. Preserve deadlines and prevent overlapping jobs; see using real cron jobs instead of WP-Cron.
  • PHP limits: Set memory_limit and max_execution_time for legitimate work and investigate repeated failures. They do not directly allocate CPU or replace account PMEM. The guide to PHP memory and execution limits gives further context.

If you frequently hit CPU or EP caps despite optimizations, it may be time to upgrade your shared plan or move to a VPS. We discuss server-side signals in our article on 9 hosting upgrade signals based on server metrics.

Quick CPU mitigations on a VPS

  • Test PHP-FPM concurrency against actual worker memory, CPU, database capacity and required headroom.
  • Use OPcache to reuse compiled PHP code; measure its effect and respect deployment invalidation.
  • For full-page caching, verify public-only eligibility, private-response exclusions, hit rate and invalidation in the chosen nginx or LiteSpeed setup.
  • Spread scheduled work where deadlines allow and bound batch size, concurrency and retries. Off-peak timing does not remove resource use or backup requirements.

Step 3 – Detect Disk IO (IOwait) and Storage Bottlenecks

Disk-dependent work can delay an application even when CPU execution is not saturated. Inspect device latency, queue length and throughput alongside the workload. IOwait is a CPU-accounting signal with limitations, especially on multi-core systems; it is not a direct measurement of every storage delay.

On shared hosting: IO graphs and backup windows

If account IO metrics are available, distinguish CloudLinux disk throughput from IOPS, disk capacity and CPU iowait. IO limits throttle disk work; network traffic and disk-cache hits are different scopes. MySQL attribution depends on the database/LVE integration. Look for:

  • Spikes in IO usage (near your limit) during the exact time your website becomes slow.
  • “Resource limit reached” events mentioning IO or faults tagged as I/O-related.

Host-wide jobs may contribute to storage contention without appearing as your account’s own IO. A repeated window, such as 02:00–02:20, is an example to investigate rather than proof of a backup cause. Correlate application latency and your metrics with provider observations:

  • Ask support whether full-server backups or scans run in that window.
  • If yes, see whether schedules can be shifted, or if your account can be moved to a less busy node.

For a storage-heavy site, compare the actual throughput/IOPS allowance, latency under representative load and management conditions of alternative plans. An NVMe VPS label does not guarantee disk performance or dedicated CPU. Ask the provider to investigate host-level contention before treating a plan upgrade as the diagnosis.

On a VPS: check IOwait and disk activity

On Linux, run:

top

The wa field reports CPU idle time associated with outstanding IO. The CPU is not itself blocked until a disk request finishes; other runnable work may execute. Linux documents limitations in this accounting. Compare it with device and application measurements.

  • A rise during the incident supports investigating IO, but a threshold such as 20% does not prove a disk bottleneck. Low iowait does not rule one out either.
  • Compare await, queue length, read/write volume and process activity with a normal period. %util alone does not express the parallel capacity limit of modern SSDs or RAID.

Then use tools like:

iostat -y -x 1 10
vmstat 1 10
iotop -o

These tools require their packages and appropriate permissions. iostat shows device statistics; vmstat combines system fields, and its first CPU/IO report covers time since boot. Subsequent interval reports describe the current samples. iotop is an interactive process view; stop it after the observation window and remember cached/buffered writes can complicate attribution. In current iostat, await includes queue and service time, and aqu-sz is the average queue length. Historical sar analysis requires collection to have been enabled before the incident. Possible workloads include:

  • Database server flushing large InnoDB buffers or rewriting indexes.
  • Backup tools reading the entire filesystem.
  • Log files growing very quickly (debug logging enabled in production).
  • Image or video processing jobs.

Fixing IO-related slowdowns

Depending on what you find, options include:

  • Logging: Reduce unnecessary debug generation while retaining required security and incident evidence. Use supported rotation; do not clear active logs to start a test.
  • Backups: Reduce overlaps and consider supported incremental copies while preserving recovery objectives, coverage and restore tests.
  • Background processing: Moving media work to a worker service can isolate it, but still needs capacity, bounded concurrency, retries and completion checks.
  • Storage: Compare actual device/service limits and representative latency. Faster media or a larger allowance can help an established constraint; neither fixes every query or application delay.

Begin with observation during the incident. If active IO tests are needed, use an authorized test environment or agreed window with a disposable test file and clear limits; a benchmark can compete with production traffic. The new VPS CPU, disk and network benchmarking guide provides related testing context.

On a VPS with the required tracing permissions, “Diagnosing Linux Server Issues with eBPF” shows how to investigate kernel-level delays when standard CPU and disk checks are inconclusive.

Step 4 – Investigate MySQL/MariaDB Bottlenecks

For database-backed sites, include MySQL or MariaDB in the investigation. Query plans, data volume, locks, connection management and resources can change response times. Verify the actual product and version before applying configuration advice; the SQL logging example below is scoped to MySQL 8.4.

Symptoms of a database bottleneck

From the user’s perspective, MySQL issues look similar to CPU problems, but there are subtle clues:

  • The whole site (including cached pages) seems fine, but specific actions become slow: search, filtering, cart/checkout, dashboards.
  • Some pages with many queries (e.g. product listing with multiple filters) are much slower in peak hours than in the morning.
  • Short bursts of database errors or timeouts, especially under concurrent users.

On shared hosting: what you can see

On shared hosting, you usually have limited access to MySQL internals, but you can still:

  • Look for MySQL-related errors in your application logs (e.g. “too many connections”, lock wait timeouts).
  • Use plugins or admin tools to measure number of queries per page and detect very slow queries.
  • Ask support whether the database server load correlates with your slow periods.

Measure query duration and application impact before attributing an incident to SQL rather than PHP or external calls. The WooCommerce MySQL/InnoDB tuning guide provides further checks. Use profiling tools in a controlled window, account for their overhead and keep sensitive query text restricted.

On a VPS: use the slow query log and basic MySQL metrics

A MySQL administrator can collect a bounded slow-log window after recording the existing slow_query_log, long_query_time, min_examined_row_limit, log_output and slow_query_log_file settings. Confirm permissions, target, free space, access and retention first. The following MySQL 8.4 example enables logging and sets a one-second global threshold; it changes server settings and is not a read-only diagnostic:

SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 1;

A global long_query_time change initializes new sessions; it does not update existing application connections or even the session issuing the command. Verify effective session values and coordinate connection renewal without disrupting active work. Logging also depends on min_examined_row_limit and the configured FILE/TABLE output. Read the actual target instead of assuming /var/log/mysql/slow.log. Record the start/end time rather than deleting earlier logs, then restore the previous settings and account for affected sessions after collection. Suitable completed queries in the window can show:

  • Queries exceeding their effective duration and examined-row thresholds; the slow log is not a complete record of every wait.
  • Repeated expensive statements and rows examined. A non-indexed query is not automatically included unless the relevant logging conditions allow it.
  • Patterns to compare with application paths and query plans. Use normal EXPLAIN first; EXPLAIN ANALYZE executes the statement and needs a controlled environment for expensive work.

You can also run:

SHOW FULL PROCESSLIST;

This shows current thread operations, not incident history. PROCESS privilege controls visibility of other users’ threads, and FULL can expose sensitive SQL. Interpret command, state, time and statement together; a long-lived sleeping connection is not the same as a running slow query. For lock contention, identify the actual blocker and waiting transaction with the appropriate version-specific database tools. A state string or high connection count alone does not prove missing indexes or CPU exhaustion.

Database-related fixes that reduce peak-hour slowdowns

  • Queries and indexes: Review plans, rows examined and result correctness. Index selection, join changes and sort reduction need measurement; retain write and storage costs in the decision.
  • Caching: Use appropriate object or public-page caching with correct user scope and invalidation. Measure hits and actual query reduction.
  • Data lifecycle: Clean sessions, transient data or revisions only through supported application procedures after backup and dependency checks. Do not delete business or incident records indiscriminately.
  • Resources: Size innodb_buffer_pool_size with memory left for the OS, PHP and other work. Raising max_connections can increase memory pressure and contention. MySQL 8.4 redo capacity uses innodb_redo_log_capacity, a disk-capacity setting; match advice to the actual version.
  • Reporting: Consider a suitable window or replica with explicit freshness, replication-lag, permission and capacity checks. Moving a report does not remove its resource cost.

If database work remains the confirmed constraint, compare vertical scaling and service separation against network latency, consistency, administration and recovery needs. A cluster is not an automatic query-speed improvement. The guide to separating database and application servers discusses that architectural decision.

Step 5 – Look Beyond the Server

Not every time-based slowdown is purely internal. Some are triggered by patterns in traffic or third-party services.

Legitimate traffic peaks vs. abusive traffic

Use your analytics and server logs to see what’s happening during slow hours:

  • Compare page views and requests with business activity; a higher count may include bots or repeated failed work.
  • Inspect path, rate, status, duration and validated client attribution. A country, shared IP or claimed User-Agent alone does not establish abuse.

When evidence identifies expensive unwanted requests, test scoped rate limits or WAF rules and observe false positives. Preserve legitimate checkout, APIs, monitoring and approved crawlers; retain a way to reverse the rule. The guide to WAF and bot protection provides implementation context.

Third-party APIs and services

Some slowness originates outside your hosting:

  • Payment gateways that respond slowly during local business peak hours.
  • Shipping and ERP APIs that get overloaded when many merchants sync inventory at the same time.
  • External marketing and personalization scripts added to the page.

To diagnose this, compare:

  • Compare browser TTFB and the request waterfall. Browser timing includes the network path; it is not a pure server-processing measurement. If HTML arrives quickly but third-party assets delay rendering, investigate those requests.
  • For backend APIs, record call duration, timeout and response outcome in the application. Distinguish waiting for a payment or inventory service from local CPU execution.

Defer noncritical frontend work when appropriate. Backend timeouts, fallbacks or queues must preserve the operation’s meaning: do not report a payment or stock update as successful without confirmation. Bound retries, prevent duplicate actions and validate failed as well as successful cases. External waiting can occupy a PHP worker without saturating CPU.

Step 6 – When It’s Time to Scale Up or Change Architecture

If required work still causes unacceptable latency or errors after measured changes, compare capacity and architecture options. Continue checking configuration, workload and external dependencies; persistent symptoms do not by themselves prove that the hosting tier is too small.

Signals for a capacity review

  • Resource graphs consistently show CPU or IO usage near the limit during your normal, expected peak hours.
  • Even well-optimized pages and queries are slower in peak traffic compared to off-peak.
  • You’ve implemented caching correctly, but logins, carts and checkouts still struggle with modest concurrency.

Options to compare with the provider include:

  • A larger shared allowance: Confirm the actual CPU, PMEM, IO/IOPS and process limits rather than relying on the tier name.
  • A VPS: Confirm CPU sharing, memory, storage limits, management access and support scope. NVMe does not imply guaranteed latency or dedicated physical CPU.
  • A dedicated or separated service: Evaluate the identified workload, operational ownership, backups, migration and recovery. More complex architecture needs its own acceptance tests.

We also recommend monitoring and alerting on your VPS so that you can see trends before they turn into outages. Our guide on VPS monitoring and alerts with Prometheus, Grafana and Uptime Kuma is a good starting point if you manage your own servers.

Practical Troubleshooting Checklist for Time-Based Slowdowns

Here is a concise, repeatable checklist you can follow next time your site is slow only at certain hours:

  1. Record: Save exact start/end times, time zone, affected URL/operation and user-visible errors.
  2. Measure: Compare normal and slow periods using the same URL, location, device and cache conditions; inspect TTFB and the frontend waterfall separately.
  3. Inspect account data: Compare actual CPU, IO/IOPS, EP, NPROC and PMEM limits/faults where available. Confirm the web server and handler.
  4. Inspect VPS data: Use top/htop, iostat, vmstat and, where permitted, iotop. Separate interval samples, since-boot averages and previously collected historical records.
  5. Correlate: Match application/query measurements to cron, backup, scans, cache warmups, traffic and external calls. Preserve logs and check clock alignment.
  6. Change: Test one supported fix with cache privacy, task deadlines, backup coverage, permissions and a reversal plan intact.
  7. Verify: Repeat representative user operations and monitoring. Record whether the change fixed the measured problem; compare capacity options when a verified constraint remains.

If resource-limit faults recur, the shared-hosting resource-limit troubleshooting guide provides related checks. Account limits and application response are separate measurements; use both when assessing the result.

Keep an Evidence Record for the Next Decision

The useful outcome is a record linking incident time, affected operation, metrics, workload and tested change. External tests, panel graphs, process observations and database logs each describe a different layer. Together they can narrow the cause and show whether a fix improved the actual user operation.

For a provider discussion, prepare the time window, time zone, relevant URLs, status codes and resource observations, removing sensitive data before sharing. Ask for the host or service information you cannot observe yourself and confirm the available support scope. Use the resulting evidence to choose a configuration change, application fix, dependency adjustment or capacity plan.

Frequently Asked Questions

Compare the incident with a normal period before selecting a cause. Scheduled jobs, traffic, account limits, database waits and external services can all produce a repeating pattern. Align timestamps and time zones, then match the affected operation with metrics, request paths and job records. Timing alone does not establish a local capacity problem.

Compare actual CPU use and its allowance with the affected operation and process activity. CloudLinux SPEED and a panel percentage normalized to the package are different scales. An EP fault does not prove CPU saturation: EP counts LVE entries, NPROC counts processes/threads, and PHP-FPM has its own concurrency and queue settings. Use server/handler details and application evidence to narrow the cause.

IOwait is CPU idle time associated with outstanding IO in the accounting data; it is not a direct device-latency measurement or proof that the whole CPU is blocked. Linux documents limitations, especially on multi-core systems. Compare interval samples with await, queue length, throughput, processes and application latency. Neither a fixed 20% threshold nor low iowait establishes whether storage is the bottleneck.

Measure query duration, plans, locks and application impact rather than relying only on slow dynamic pages. On shared hosting, use controlled application profiling and provider observations. With MySQL administration access, collect a bounded slow-log window without deleting earlier evidence and interpret SHOW FULL PROCESSLIST as a current snapshot. Verify session thresholds, logging destination and privileges; a state string alone does not identify the cause.

Evaluate capacity when necessary work repeatedly causes unacceptable delay or errors at verified limits, alongside continuing checks for configuration and external dependencies. Compare the actual CPU-sharing model, RAM, IO/IOPS, management access and support scope. Test the proposed improvement and plan migration/recovery. A larger tier, NVMe label or separate database does not guarantee that the diagnosed problem is solved.
↑