Solving Time to First Byte ( TTFB ) in WordPress

Written by codeforgeek | Published 2017/01/12
Tech Story Tags: nginx | web-development | wordpress | programming | website

TLDRvia the TL;DR App

Do you use WordPress?

Do you use Nginx as the Web Server?

Do you use SSL as well, because hey it’s ranking factor.

And your website loads like this?

Well that’s probably because your Server is taking too much time to respond in the first request, which in technical terms called Time to First byte or TTFB in short.

Not sure what is the TTFB of your website? Visit here and find it out. If it is less than 300 millisecond, then you don’t need to read it further ( You can of course) else if it is anything more than that, pay good attention now!

Explaining TTFB

Here is how it works.

  • You hit the website address from your browser ( say https://codeforgeek.com)
  • Now browser first contact your name server, and then finds out the location of web server.
  • Web Server upon getting the request, process the response ( This one is the problem ) and send it back to browser ( It’s called Server loading time).
  • Browser then starts rendering ( This is your browser loading time).

If you have static content, say few HTML then Web Server will return it in few milliseconds. Quick like a lightning bolt!

But WordPress ain’t a static thing, it’s very complex software and since there is PHP involved which in turns execute the code behind the scene to generate the response for your request.

The time your PHP and Web Server is taking to prepare the first byte or first response to the browser is TTFB or Server response time in SEO terms.

What is my TTFB?

I own a blog called https://codeforgeek.com and here is the TTFB of my blog.

it’s 210 ms, < 300 ms.

What it was?

And what was the TTFB before solving the issue? Here it is.

Yup! 3 f**ing seconds

It was 3 seconds! Too far from the recommended one.

Why you should care?

Because Google does.

Google recommends server response time to less than or equal to 200 ms. I still got a work to do, but I am very near to it.

You can check out the Google recommendation here.

How did I solve it

Let’s get to work!

To solve any programming or infrastructure problem, we need to get into roots of the problem.

There are generally two approach to get to the root of the problem:

  • Forward Engineering
  • Reverse Engineering

I personally, most of the time prefer Reverse Engineering. So here too, I applied same.

The problem: TTFB is 3 seconds.

Root cause: This could be due to following:

  • Domain provider name server is slow.
  • Web hosting provider taking time to respond.
  • Nginx is not properly configured.
  • May be MySQL is taking time and running slow on load.
  • May be PHP is rendering slow.
  • May be Server configuration is not proper!

List can go on and on.

To solve I first reverse engineered the problem and looked from the bottom and classified the solution in following section:

  • Infrastructure issue ( Nameserver, Networking etc)
  • Server issue ( Nginx + PHP + MySQL)
  • Caching ( Server + Browser side)

Ok!

So I started from Infrastructure.

I asked my hosting provider about this issue and they replied that static files are working fine so it might be your Server configuration.

Then I looked over the waterfall diagram of the webpagetest result and nameserver result seems fine!

Clearly this was not infrastructure issue.

Moving right along!

Instead of going to the Server first, I went to check caching. I already had caching plugin Installed plus Redis to cache frequent MySQL queries and OpCache of PHP. So Server side seems fine.

For browser side, I chose cloudflare and added my site over there. Well it did’t work ! TTFB was still same :(

Clearly there was something wrong with Server configuration.

Here is what I did in steps:

  • Optimised MySQL — TTFB got reduced few millisecond.
  • Checked Nginx Redirection from HTTP to HTTPS. It was correct.
  • Checked PHP configuration, seems fine!

And I was lost, if everything seems right! What is wrong then.

Days go on and problem persists.

One thing which I missed is:

Check SSL and Nginx.

I researched a little and find out that PHP and SSL requires some tuning!

Gave this a shot.

First, Enabled HTTP/2 on Nginx

server {  listen 443 ssl http2;  #rest of your config here}

Then, Set up fastcgi cache.

First in nginx.conf

fastcgi_cache_path /etc/nginx-cache levels=1:2 keys_zone=phpcache:100m inactive=60m;fastcgi_cache_key "$scheme$request_method$host$request_uri";

Then in HTTP block.

location ~ [^/]\.php(/|$) {fastcgi_cache phpcache; # The name of the cache key-zone to usefastcgi_cache_valid 200 30m; # What to cache: 'Code 200' responses, for half an hourfastcgi_cache_methods GET HEAD; # What to cache: only GET and HEAD requests (not POST)add_header X-Fastcgi-Cache $upstream_cache_status; # Add header so we can see if the cache hits or misses# the rest of your existing stuff to handle PHP files here}

Restarted the Server.

sudo service nginx restart

Then checked the result! And I got the TTFB under 300 ms.

Just WOW moment!

I also deleted some unused plugin and cleaned up WordPress.

Let me know if it helps. You can check my blog codeforgeek where I post lots of programming related content.


Published by HackerNoon on 2017/01/12