My blog isn’t particularly popular (or unpopular). I don’t really care too much about advertising it’s existence… that’s what google is for.
This blog originally started as way to tell friends and family about my adventures when I lived on my sail boat, Blue Macs. When I moved off the boat, I started writing about more technical things…
Before this, this is what the traffic looked like in Google Analytics:
As I started writing about more technical things, especially Docker, I got discovered.
However, this isn’t the important thing. None of this is important. In August of last year, I wanted to know something, did people actually read my blog? Which lead to other questions, such as: How do I know someone actually read an article? How long are they spending reading articles? etc. I wanted to make myself a better writer, and to do these things, I had to answer these questions.
More importantly, I wanted to know if site performance had anything to do with it. My hypothesis was that it would affect engagement. In fact, that’s what the rest of this article is about…
I quickly discovered that Time To First Byte (TTFB) would be my largest hurdle… Dynamically rendered pages don’t make a lot of sense for this blog, but it would take me a really long time to think outside the box on this. Therefore, I spent most of a year using Docker as my choice tool.
I figured out how to make WordPress in Docker more resilient, more “dockerable”, and faster over that year. I learned what parts need to be close to other parts. I used a heavily modified hyperdb plugin to prefer talking to the replica on the node in which the request was recieved. The object cache was through rethinkdb, with replicas on each node as well.
Docker and Rancher made deployments relatively easy, however I would quickly discover some shortfalls. Docker would crash randomly. It was as though I had the worst luck ever and I almost walked away from Docker altogether … but they fixed those bugs. These days, it would probably be much easier to build everything that I built, especially with some of the new Dockerfile language additions, like HEALTHCHECK. Those things didn’t exist then, so I’d sometimes end up in very bad states.
I’ve learned over the years that anything is scalable, as long as you have the money to scale it. Different frameworks and languages scale differently … it turned out that I just didn’t have the money to make it work.
I did eventually move to a Docker powered infrastructure, and it was a good bit faster than my single server instance.
You can actually see the bounce rate fall off in January, 2016 … this gave me hope that I was on the right track. It wouldn’t be long until a new coworker would join our team and tell us about hugo. I was stumped on how to make my blog faster without spending a ton of money. But I figured there had to be some way to serve plain-jane html pages with no php.
After experimenting with several other possibilities, it became clear that Hugo was my ticket, along with Caddy Server. However, I love WordPress. I wanted to use it to write in, to build my blog with and call it a day. In theory, I could just render my posts to html, and be done with it. In fact, there’s already plenty of plugins to do that.
So, why did I choose this route? There were several key lessons I learned while dockerizing WordPress for scale:
1. The cost of nginx –> php-fpm is higher than you’d think and like.
2. HTTP2 really changes the game.
3. Distributing “constantly” changing files is more difficult than you’d think.
So, I ended up using WordPress to write up my posts and having Hugo digest them and render them to html. This actually worked out exceptionally well.
My TTFB dropped from 1-4s to less than 100 milliseconds and more interestingly, my bounce rate dropped to the floor:
When I first saw this, I thought I’d done something wrong. I put sleep timers in hugo, to increase the TTFB … bounce rate went up. It makes very little sense to me. Why would people choose to read something they aren’t interested in just because the page loads faster? Or perhaps the question should be, why would someone wait for an article they may not be interested in reading? Interestingly, my conversion rate has stayed at approximately 30% since I implemented it over a year ago, however, since more people are staying on my blog, more people are reading my blog. How about them apples?
I’m not the first one to discover this little tidbit of information; I’m sure I won’t be the last. I will say that it’s interesting that it applies to this little blog.
This has been a fun experiment. I’ve learned a lot, which I’ve taken to my workplace. My next big goal is to release the code that powers this blog, to improve it, and to write in my blog more consistently.
If there’s one thing I’ve learned in the world, consistent releases results in good things.
So, the question still remains, did performance actually increase engagement? According to Google Analytics, yes, yes it did. The number of sessions that actually browsed the blog increased by over 100%, as well as the time spent on the blog itself.
There’s something else I’d like to point out. The content has changed over time, these stats aren’t apples to apples. However, I’ve done my best to prove any changes were actually causation and not correlation…
Also, page rendering time has been kept about the same (It’s steadily improved to 3s faster over the last year, most likely due to new, faster technology). Only TTFB has decreased substantially, due to engineering, in the last year…
Obviously, you may not see the same results on your own site or blog. I’m sure there are a lot of variables that go into conversions, engagement, and all that mess.