Estimated blog post reading time with Jekylls liquid

27 Aug 2021 - tsp
Last update 27 Aug 2021
Reading time 3 mins


There is a new feature on the block that is popping up in the blogsphere. This time it’s just something simple and small that everyone seems to want or adds to their blogs - it emerged on WordPress and similar solutions some time ago and got quite popular especially for political and philosophical as well as traditional hobby blogs - i.e. on blogs that are easy to read and one doesn’t have to take much time into understanding, processing and calculating. The mini information how large an article is measured in estimated time to read so one can decide in the subway or somewhere in between if they try it now or store the article for later on.

How do these estimates work? Well basically they’re based on the fact that there is an average reading speed. Of course this highly depends on the person who’s reading - a skilled reader can read up to 600/800 words per minute (world records are claimed for more than 2000 words per minute) - though the average native English speaking adult reads on average 238 per minute for non fiction and 260 words per minute for fiction. If one’s more interested in the theory I recommend as a starting point the meta study How many words do we read per minute? A review and meta-analysis of reading rate.

Implementing estimated reading time with Jekyll’s liquid

The Jekyll static site generator is a nice solution to build static webpages which is a perfect solution for personal blogs as well as newspapers, company blogs, documentation projects, companies, etc. - static webpages are great for everything that doesn’t have to display dynamic data. There is no need to run extensive processing to build the pages every time a user requests them - and even reduces attack surface on the service. There are of course drawbacks and depending on changes the page generator has to do some larger processing either periodical or on changes. But that’s easily automate-able - and running a static page reduces load on the service significantly especially for larger pages (and makes horizontal scaling much more easy).

Jekyll is one of the more commonly used generators - it’s also used by GitHub for their GitHub pages implementation. Tailoring one’s own extensions is +- simple but requires some Ruby skills and of course this is also what’s required on the machine that builds the pages. In case you’re not like me who likes dependency free long lasting solutions this might not pose the slightest concerns but even in this case - this page is at the time of writing built by Jekyll (and some shell scripts and external tools - all driven by Jenkins out of a git repository protected with GPG signatures).

Liquid is the markup language used by Jekyll and it provides an easy way to implement this feature - the number_of_words filter. I’m including the code in my article layouts as well as in my index page for loop. First one has to count the words contained in the respective blog posts:

{% assign postWordCount = page.content | number_of_words %}

Then one simply can calculate the read time in minutes by dividing by the average reading speed:

{% if postWordCount < 360 %} 1 min {% else %} {{ postWordCount | divided_by:238 }} mins {% endif %}

That’s it - one can simply implement this in one’s layout templates and gets the reading time displayed on every blog post. In case one wants to do this in an index generated from the posts array everything works the same - just access the content of the specific post. For example one could implement this in the following way:

{% assign items = site.posts %}
{% for post in items %}
  {% assign postWordCount = post.content | number_of_words %}
  <li> <a href="{{ post.url }}">{{ post.title }}</a> ({% if postWordCount < 360 %} 1 min {% else %} {{ postWordCount | divided_by:180 }} mins {% endif %} {% endif %} read) </li>
{% endfor %}

This article is tagged:

Data protection policy

Dipl.-Ing. Thomas Spielauer, Wien (

This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support