<p>I don't think you'll be able to avoid the database queries, but you'll definitely want to use cacheing here, and set a high cache time if possible.</p>

<p>Wrap your code in {% cache %} <a href="http://buildwithcraft.com/docs/templating/cache" rel="nofollow">tags</a> like below: </p>

<pre><code>{% cache globally for 1 month %}
{% nav category in craft.categories.group('...') %}
   {% set entryCount = craft.entries.relatedTo(category).total() %}
   {{ category.title}} ({{ entryCount }})
{% endnav %}
{% endcache %}
</code></pre>

<p>If this navigation appears on every page, use the "globally" tag.</p>

CC BY-SA 3.0
2015-02-03T18:00:27.797Z
2015-02-03T18:00:27.797Z
Aaron Berkowitz
<p>Another option would be to use the rarely talked about <a href="http://buildwithcraft.com/classreference/services/TemplatesService#hook-detail" rel="nofollow">template hook</a> feature in Craft.  The link shows some examples of how to use it and the control panel uses it in one or two places to speed things up.</p>

<p>But from the PHP side, you'd be able to grab all of the data you'd need from the database (using commandBuilder(), joins, etc.), then return it all to the template formatted in a way it can easily consume.</p>

CC BY-SA 3.0
2015-02-10T21:16:14.347Z
Thanks for the answer Brad. Is there an advantage to using a template hook vs a plugin variable to achieve this? Other than with the template hook you get access to the context?
Peter Tell
CC BY-SA 3.0
2015-02-10T21:20:56.333Z
Access to the context is the main difference, I think.
Brad Bell
CC BY-SA 3.0
2015-02-03T18:58:39.457Z
2015-02-03T18:58:39.457Z
Brad Bell
<p>Let's say I'm outputting a list/nav of categories, with the count of entries in each category, as described in <a href="https://craftcms.stackexchange.com/a/395/689">other</a> <a href="https://craftcms.stackexchange.com/a/6868/689">questions</a>:</p>

<pre><code>{% nav category in craft.categories.group('...') %}
   {% set entryCount = craft.entries.relatedTo(category).total() %}
   {{ category.title}} ({{ entryCount }})
{% endnav %}
</code></pre>

<p>On a site with plenty of categories (more than 100 in this case), that seems like <strong>a lot</strong> of relatedTo queries. Is there a way I could accomplish the same thing with fewer queries / better performance?</p>

<categories><relations><performance>
Performance of a categories list with post count
# Performance of a categories list with post count

(Asked by: username_0 on 2015-02-03)

Let's say I'm outputting a list/nav of categories, with the count of entries in each category, as described in other questions:
{% nav category in craft.categories.group('...') %}
   {% set entryCount = craft.entries.relatedTo(category).total() %}
   {{ category.title}} ({{ entryCount }})
{% endnav %}

On a site with plenty of categories (more than 100 in this case), that seems like a lot of relatedTo queries. Is there a way I could accomplish the same thing with fewer queries / better performance?

**Tags:** categories, relations, performance

---

## 2 answers

### Answer by username_1 on 2015-02-03. Score: 2

I don't think you'll be able to avoid the database queries, but you'll definitely want to use cacheing here, and set a high cache time if possible.
Wrap your code in {% cache %} tags like below: 
{% cache globally for 1 month %}
{% nav category in craft.categories.group('...') %}
   {% set entryCount = craft.entries.relatedTo(category).total() %}
   {{ category.title}} ({{ entryCount }})
{% endnav %}
{% endcache %}

If this navigation appears on every page, use the "globally" tag.


---

### Answer by username_2 on 2015-02-03. Score: 2

Another option would be to use the rarely talked about [template hook](http://buildwithcraft.com/classreference/services/TemplatesService#hook-detail) feature in Craft. The link shows some examples of how to use it and the control panel uses it in one or two places to speed things up.

But from the PHP side, you'd be able to grab all of the data you'd need from the database (using commandBuilder(), joins, etc.), then return it all to the template formatted in a way it can easily consume.

> **Comments:**
> **username_3**: Thanks for the answer Brad. Is there an advantage to using a template hook vs a plugin variable to achieve this? Other than with the template hook you get access to the context?  
> **username_2**: Access to the context is the main difference, I think.  

---

