# Performance Expectations

**URL:** <https://discourse.gohugo.io/t/performance-expectations/8541>\
**Category:** support\
**Created:** [September 27, 2017, 2:28pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541 "2017-09-27T14:28:38Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![nraboy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nraboy/32/4261_2.png) [@nraboy](https://discourse.gohugo.io/u/nraboy)\
**Post date:** [September 27, 2017, 2:28pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/1 "2017-09-27T14:28:38Z")

</div>

Hi,

I was wondering what the performance expectations for building with Hugo were. On Google I’ve seen it discussed, but nothing really pointed to what was realistic expectations.

When I build with no metric flags, I get the following:

```
0 of 28 drafts rendered
0 of 5 futures rendered
0 expired content
407 regular pages created
2496 other pages created
0 non-page files copied
1455 paginator pages created
52 categories created
1191 tags created
total in 4996 ms

```

When I build with `stepAnalysis` enabled:

```
Go initialization:
	801.569904ms (802.261564ms) 8.90 MB 101326 Allocs
initialize:
	73.453µs (802.367181ms) 0.01 MB 173 Allocs
load data:
	1.503525ms (803.929172ms) 0.14 MB 2387 Allocs
load i18n:
	133ns (803.957055ms) 0.00 MB 0 Allocs
read pages from source:
	52.48363ms (856.547989ms) 23.38 MB 163964 Allocs
convert source:
	31.045602ms (887.773711ms) 52.75 MB 210810 Allocs
build Site meta:
	4.06214ms (891.897982ms) 0.89 MB 25172 Allocs
prepare pages:
	73.702331ms (965.685529ms) 26.19 MB 96679 Allocs
render and write aliases:
	46.122µs (965.766131ms) 0.00 MB 7 Allocs
render and write pages:
	4.203848535s (5.169665738s) 1015.35 MB 29377419 Allocs
render and write Sitemap:
	41.759725ms (5.211484544s) 5.90 MB 116640 Allocs
render and write robots.txt:
	10.317µs (5.211545297s) 0.00 MB 7 Allocs
render and write 404:
	11.535675ms (5.223144317s) 1.05 MB 29569 Allocs
render and write pages:
	575.293142ms (5.79856103s) 103.74 MB 1290925 Allocs

```

Finally, when I build with `templateMetrics` enabled:

```
Template Metrics:

     cumulative average maximum         
       duration duration duration count template
     ---------- -------- -------- ----- --------
   9.155789234s 4.844332ms 36.233396ms 1890 theme/partials/widgets/sidebar/recent.html
    8.68188007s 5.866135ms 16.486078ms 1480 theme/_default/list.html
   2.934280275s 7.209533ms 38.949899ms 407 theme/_default/single.html
   678.216743ms 543.442µs 56.470446ms 1248 theme/_default/rss.xml
   560.940901ms 296.637µs 12.752235ms 1891 theme/partials/head.html
   246.858965ms 606.533µs 3.369278ms 407 theme/_default/single.content.html
   148.629501ms 78.639µs 5.318497ms 1890 theme/partials/widgets/sidebar/adsense2.html
   140.074754ms 74.113µs 835.09µs 1890 theme/partials/widgets/sidebar/social.html
   123.329631ms 65.253µs 1.599514ms 1890 theme/partials/widgets/sidebar/adsense1.html
   112.173083ms 59.35µs 963.263µs 1890 theme/partials/widgets/sidebar/donate.html
   111.962994ms 59.239µs 1.019162ms 1890 theme/partials/navigation/navigation-fixed.html
   107.786412ms 57.029µs 4.250513ms 1890 theme/partials/widgets/sidebar/subscribe.html
    95.226925ms 50.357µs 1.250092ms 1891 theme/partials/footer.html
    76.275361ms 40.335µs 896.228µs 1891 theme/partials/foot.html
    55.756381ms 136.993µs 552.89µs 407 theme/partials/widgets/content/tags.html
     53.73365ms 133.665µs 1.536781ms 402 theme/partials/widgets/content/share.html
    50.128526ms 25.064263ms 42.581587ms 2 theme/_default/terms.html
    38.706963ms 38.706963ms 38.706963ms 1 _internal/_default/sitemap.xml
    36.409754ms 24.601µs 400.251µs 1480 theme/partials/pagination.html
    28.189216ms 14.914µs 889.3µs 1890 theme/partials/widgets/sidebar/search.html
     22.72955ms 55.846µs 1.35901ms 407 theme/partials/widgets/content/author.html
     9.365041ms 23.009µs 716.354µs 407 theme/partials/disqus.html
     8.112286ms 8.112286ms 8.112286ms 1 theme/404.html
     3.272399ms 25.565µs 140.569µs 128 _internal/shortcodes/youtube.html
     2.480729ms 1.312µs 198.671µs 1890 theme/partials/widgets/sidebar/youtube.html
     1.050769ms 1.050769ms 1.050769ms 1 theme/index.html
      401.648µs 26.776µs 61.383µs 15 theme/shortcodes/audio.html
          229µs 229µs 229µs 1 theme/partials/navigation/navigation.html
      189.612µs 189.612µs 189.612µs 1 theme/shortcodes/slideshare.html
       53.603µs 53.603µs 53.603µs 1 theme/shortcodes/codepen.html

```

That is a lot of information, most of which I am not sure how to decipher. If I had to guess, I’d say I have two problems:

1. I have a lot of taxonomy terms which is resulting in a lot of pages being built.
2. I have a `partial` for displaying my five most recent posts on the sidebar of each page.

Are those the reasons why my build time is nearly 5 seconds? Based on my number of pages and taxonomy information, what should my build time be? Are there any tips and tricks that can be used to optimize my Hugo site or theme to improve the build time?

Any information on how to properly troubleshoot the metrics and apply changes would be helpful. My site is found here:

[https://www.thepolyglotdeveloper.com/blog](https://www.thepolyglotdeveloper.com/blog)

That should give you an idea on what I’m trying to accomplish in case you need a visualization.

Thanks,

---

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [September 27, 2017, 4:40pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/2 "2017-09-27T16:40:43Z")

</div>

Based upon the step analysis, it looks like most of your build time (4.2 seconds) is spend rendering pages, which appears to be a result of the number of categories and tags you have.

If I were you, I’d first look at the top entries from the Template Metrics output. The cumulative duration column lists the **CPU time** spend executing a given template. Things to consider:

- Use [cached partials](https://gohugo.io/functions/partialcached/) where possible. For example, you probably only need to execute `theme/partials/widgets/sidebar/donate.html` once.

- See if you can optimize some “related content” areas with Hugo’s new [Related Content](https://gohugo.io/content-management/related/) features. It was added in v0.27.

You can always reduce the number of tags and taxonomies, but I’m assuming you’re using them wisely. 🙂

---

<div class="post-metadata">

**Author:** ![nraboy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nraboy/32/4261_2.png) [@nraboy](https://discourse.gohugo.io/u/nraboy)\
**Post date:** [September 27, 2017, 4:58pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/3 "2017-09-27T16:58:59Z")

</div>

Interesting on the cached partials! I do have a question on it though. How do I know whether I need something to be re-rendered on every invocation? It isn’t obvious to me what is an acceptable scenario for `partial` vs `partialCached`.

Can you clear the above up because it looks promising!

I don’t believe related content applies to me. I’m showing recent content, but not related. My recent content widget on every page simply uses the following:

```
{{ range first 5 (where .Site.Pages "Type" "post") }}
                        <li><a href="{{ .Permalink }}">{{ .Title }}</a></li>
                    {{ end }}

```

I am working on reducing my taxonomy terms. Back when I was on WordPress I got out of control. I’m thinking I can shave off about 25% of them.

---

<div class="post-metadata">

**Author:** ![budparr](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/budparr/32/749_2.png) [@budparr](https://discourse.gohugo.io/u/budparr)\
**Post date:** [September 27, 2017, 5:04pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/4 "2017-09-27T17:04:33Z")

</div>

You can use partialCached, I believe, on any partial that will have the same result on every template it’s on.

---

<div class="post-metadata">

**Author:** ![nraboy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nraboy/32/4261_2.png) [@nraboy](https://discourse.gohugo.io/u/nraboy)\
**Post date:** [September 27, 2017, 5:06pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/5 "2017-09-27T17:06:44Z")

</div>

I’m probably not a Hugo power user, but do you have an example where a partial would not be the same on every page?

---

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [September 27, 2017, 5:07pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/6 "2017-09-27T17:07:41Z")

</div>

A cached partial is only executed/generated once. If you have a partial that generates the same output 1800 times, you should cache that puppy.

You can also use cached variants. So, if a menu renders the same output for all pages under the same section, you could do something like:

```auto
{{ partialCached "menu.html" . .Section }}

```

That causes the `menu.html` partial to only be rendered once for each value of `.Section`.

---

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [September 27, 2017, 5:13pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/7 "2017-09-27T17:13:03Z")

</div>

A partial that included something unique about the page calling it shouldn’t be cached.

Your “recent content” partial is a **great example** of a partial that should be cached. It should generate the same results on every page, so you really only need to render it once.

---

<div class="post-metadata">

**Author:** ![nraboy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nraboy/32/4261_2.png) [@nraboy](https://discourse.gohugo.io/u/nraboy)\
**Post date:** [September 27, 2017, 5:15pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/8 "2017-09-27T17:15:50Z")

</div>

Awesome!

I swapped out my `partial` with `partialCached` and it dropped the build time from 5000ms to 500ms. I feel like this should be more heavily promoted because those are huge changes in performance.

Thanks for the performance tips!

---

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [September 27, 2017, 5:19pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/9 "2017-09-27T17:19:08Z")

</div>

Funny. I started working on a [Build Performance](https://github.com/gohugoio/hugoDocs/pull/216) page yesterday. 🙂

Was the above explanation about cached partials helpful? I’ll try to work in a clearer explanation.

---

<div class="post-metadata">

**Author:** ![nraboy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nraboy/32/4261_2.png) [@nraboy](https://discourse.gohugo.io/u/nraboy)\
**Post date:** [September 27, 2017, 5:21pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/10 "2017-09-27T17:21:04Z")

</div>

Yes, I think it was very helpful!

I think I need to play around with it some more so I don’t mess something up, but for the most part the performance improvements are great.

Thanks for the help!

---

<div class="post-metadata">

**Author:** ![nraboy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nraboy/32/4261_2.png) [@nraboy](https://discourse.gohugo.io/u/nraboy)\
**Post date:** [September 27, 2017, 5:24pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/11 "2017-09-27T17:24:43Z")

</div>

Side question though.

Say my partial has something like this:

`{{ if eq .Type "post" }}`

Will the conditional logic still apply to every page, whether it be `post` or `page`? For example, within my Disqus partial I have it first check to see if it is a `page` or a `post`. If it is a `post` then apply Disqus. I include the partial on every template regardless of what will show.

In this scenario, will it cache and then always be one or the other regardless of the type?

Does that make sense?

---

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [September 27, 2017, 5:37pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/12 "2017-09-27T17:37:36Z")

</div>

You don’t want to cache that partial outright because the output **varies** based upon `.Type`. If that template really outputs the same thing based only upon `.Type`, I’d use a cached **variant** :

```auto
{{ partialCached "disqus.html" . .Type }}

```

That will execute the template once for each value of `.Type`.

What happens in the background is that we use TemplateName+Variants as the cache key.

---

<div class="post-metadata">

**Author:** ![nraboy](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nraboy/32/4261_2.png) [@nraboy](https://discourse.gohugo.io/u/nraboy)\
**Post date:** [September 27, 2017, 5:39pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/13 "2017-09-27T17:39:25Z")

</div>

Interesting!

I need to play around with this some more. Definitely include everything we discussed in your documentation. I’m sure people are smarter than me at this, but I’m sure it will help.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [September 27, 2017, 5:52pm UTC](https://discourse.gohugo.io/t/performance-expectations/8541/14 "2017-09-27T17:52:53Z")

</div>

The promotional tag line of Hugo is “1 ms per rendered page” (it is on the front page of [gohugo.io](http://gohugo.io)). Your site produces around 5000 pages built in 5 seconds, which sounds about in line with the promotion – it is also very, very fast compared to most other static site generators on the planet.

There are plenty ways to create slow Hugo sites, though. The new template metrics feature is gold to spot these – often `cachedPartial` will be a fix.
