Skip to main content
.com domains from $2.99 — free WHOIS privacy on every name

Benchmark bench · Intermediate · an afternoon

How to reduce server response time — TTFB: Decompose It Before You Try to Cut It

A 900-millisecond first byte has a specific cause, and it is usually one uncached template, one unindexed query or one blocking API call — not the whole stack.

The short answer

Split the number before you spend an afternoon on it: curl reports DNS, TCP connect, TLS handshake and time to first byte separately, and 20 milliseconds of DNS with 800 milliseconds of server compute is a completely different job from the reverse.

Once you know it is server compute, there are only a few places it can be. Either the page is not being served from cache when it could be, or the uncacheable path is slow — and on the uncacheable path the two habitual culprits are an unindexed database query and a synchronous call to somebody else's API during render.

By the HostingFast team · Reviewed 24 August 2026

Intermediate

Assumed level

5

Stages to done

Free

Support cost

Proven

Verified on production

An afternoon, worked in order, with a measurement after each change. The order matters more than the individual techniques: cache first, runtime second, queries third, external calls fourth.

PHP version switching per site, OPcache, Redis object caching and NVMe-backed MySQL are all available here, and PHP X-Ray on CloudLinux Pro on the Nitro tier will name the slow function rather than leaving you to bisect.

Split the number first

One command, four answers: curl -o /dev/null -s -w 'dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer}\n' https://example.com. Subtract each from the next and you have the cost of resolution, of the TCP handshake, of TLS negotiation, and of the server actually producing your response.

Read it honestly. A slow DNS lookup is a nameserver problem and no amount of PHP tuning touches it. A long TLS phase on a first connection is normal and mostly disappears with session resumption. What matters for this page is the gap between time_appconnect and time_starttransfer, because that is your server thinking, and that is the number you can move.

The cheapest millisecond is the one PHP never runs

When the LiteSpeed page cache answers a request, neither PHP nor MySQL is involved: the response comes out of the server's own store. No other single change reliably takes a response from hundreds of milliseconds into double digits, which is why cache verification comes before tuning. Confirm it with curl -sI and look for x-litespeed-cache: hit on a repeat request.

Then size the remaining problem by comparing cached and uncached. TTFB logged out is a cache hit; TTFB logged in is your application running in full. If the logged-out number is already fine, your work is entirely on the uncacheable path, and that is a much narrower problem than it felt like an hour ago.

Making the uncacheable path fast

Some requests must compute every time: a cart, a checkout, an admin screen, any logged-in session. Give those the best runtime available. A current PHP release with OPcache holds compiled bytecode in memory so your code is not re-parsed on every request, and per-site PHP switching means you can move one application forward without touching another on the same account.

Then reduce the database round trips. Redis object caching keeps the results of repeated queries in memory instead of asking MySQL again, and MySQL itself sits on NVMe storage on every tier here. On Nitro, PHP X-Ray on CloudLinux Pro will attribute slow time to a specific URL and function, which turns a vague slow admin into a named call.

The two habitual 800-millisecond culprits

First, the unindexed query. A plugin that stores its own data in its own table and queries it without an index will scan the lot on every page load, and the cost grows with your content. Query Monitor in the browser or PHP X-Ray at server level will name it; adding the index, or removing the plugin, is usually a small change with a large number attached.

Second, the blocking external call. A synchronous request to a payment, feed, licensing or social endpoint during page render holds your entire response hostage to somebody else's latency, and when their service has a bad afternoon so do you. Cache the payload with a sensible lifetime, or move the fetch to a cron job and read the stored result during render. Either way, it leaves the request path.

A performance-test needle sweeping hard to the right

The stack these figures were taken from

Every technique here runs on the platform we operate: LiteSpeed Enterprise page caching, per-site PHP switching with OPcache, Redis object caching, NVMe-backed MySQL, and PHP X-Ray on CloudLinux Pro on the Nitro tier.

How a platform is engineered — NVMe disks, LiteSpeed, restrained account density per machine — matters far more to response time than which city the datacentre is in.

  • The four-part curl breakdown, printed in full
  • Cache verified before anything gets tuned
  • Runtime, queries and external calls in cost order
  • Engineers who will read the profile with you

Why HostingFast

Standard on every plan

Decomposition first

Four numbers from one command, so you spend the afternoon on the component that is actually large.

Cache before tuning

The single largest available change is verified first, because tuning an uncached site is optimising the wrong thing.

Cached versus uncached sized

Comparing logged-out and logged-in TTFB tells you how much of the problem remains after caching.

Runtime specifics

Current PHP with OPcache, per-site switching, Redis object caching and NVMe-backed MySQL, named rather than implied.

Profiling, not guessing

Query Monitor and PHP X-Ray on CloudLinux Pro turn slow admin into a named function and a line number.

The external call, called out

A synchronous third-party request during render is the failure mode that makes your uptime depend on theirs.

Quick Start

From order to online

  1. 1

    Measure the four components, logged out and logged in

    curl -o /dev/null -s -w 'dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer}\n' https://example.com. Three runs each way. You now know whether this is a DNS, TLS, cache or compute problem.

  2. 2

    Confirm the cache is answering what it should

    curl -sI on your key templates, looking for x-litespeed-cache: hit on a repeat request. Anything important reporting a permanent miss is the first fix, and it is usually worth more than everything after it.

  3. 3

    Bring the runtime forward and keep OPcache warm

    Switch PHP per site from the control panel and confirm OPcache is enabled. Compiled bytecode held in memory removes the parse cost from every uncacheable request, which is the cheapest win on this path.

  4. 4

    Profile the queries on the uncacheable path

    Query Monitor in the browser, or PHP X-Ray on CloudLinux Pro on Nitro. Look for the single call owning most of the time — an unindexed lookup or one talkative plugin usually accounts for the bulk. Add Redis object caching for the repeated reads.

  5. 5

    Get blocking third-party calls out of the request

    Any synchronous fetch to an external endpoint during render is your response time plus theirs. Cache the payload, or move the fetch to a cron job and read the stored copy. Then re-measure and write the number down.

Built In

Loaded onto every plan

  • LiteSpeed caching built into the server rather than patched in by plugin
  • NVMe SSD storage behind that cache, and behind MySQL, on every tier
  • Per-site PHP version switching with OPcache from the control panel
  • Redis object caching for the repeated queries a page cache cannot help
  • PHP X-Ray on CloudLinux Pro on the Nitro tier for slow-request attribution
  • Full SSH access with Git, Composer and WP-CLI on every shared plan
  • Cron jobs, so a blocking external call can be moved off the request path
  • In-place upgrades from shared through VPS to dedicated with no migration
  • Money-back cover: 30 days on hosting plans, 7 on reseller
  • Human support on duty every hour of every day

Frequently Asked

What people ask us most often

How do I split TTFB into DNS, TLS and server time?

curl gives you all of it: -w 'dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer}\n'. Each figure is cumulative from the start of the request, so subtract each from the next to get the phase cost. DNS is your nameservers, connect is network round-trip time, the gap to time_appconnect is TLS, and the gap from there to time_starttransfer is your server producing the response. Only the last one is yours to optimise in code.

Which PHP settings actually move the number?

OPcache is the big one: with compiled bytecode held in memory, your code is not re-parsed on every request, which on a framework-heavy application is a substantial share of the compute time. A current PHP release matters too, because each has been measurably faster than the last on real workloads. Beyond those, memory_limit only helps if you were hitting it, and most other directives are noise next to caching and query work.

Why is my cached TTFB fine but the checkout slow?

Because they are different code paths. A cached page is served from the store with no PHP; a checkout must compute — session, basket, taxes, stock, often a payment gateway call — and is correctly excluded from the page cache. Optimise it as its own problem: current PHP with OPcache, Redis object caching for repeated reads, indexes on the queries a profiler names, and any external API call moved out of the render path.

Will moving to a bigger plan reduce TTFB?

Only if you are resource-constrained, so check before you spend. If the Resource Usage graphs show you hitting the CPU or entry-process ceiling, more cores and RAM will help directly — Nitro doubles Sprint and Turbo to two cores and 4 GB, and the business tiers and VPS go further. If the graphs are flat and one unindexed query owns 600 milliseconds, a bigger plan runs that same query slightly faster and nothing else. Upgrades here are in-place and require no migration, so either way the change is an account setting rather than a move.

Keep reading

Changing hosts? Run through our checklist first.

A straightforward sequence for a switch your visitors never feel: which files move first, how to shift email across without losing a single message, the right moment to repoint DNS, and the two mistakes behind almost all the downtime we get asked to rescue.

You'll get the checklist email, then occasional pointers on keeping a site running fast. Unsubscribe the moment you want out — the privacy policy covers the rest.

Put the first byte on faster ground.

LiteSpeed in front of NVMe, per-site PHP with OPcache, Redis object caching, PHP X-Ray on Nitro, and in-place upgrades with no migration.

View Business Hosting plans