<p>The <code>{% cache %}</code> tag only caches the HTML output.  That's it.</p>

<p>In your example above, nothing is cached, and <code>categoryProducts</code> will be an empty set.</p>

<p>One thing you could do is to cache each entry individually:</p>

<pre><code>{% set categoryProducts = craft.entries.section('products').relatedTo(category) %}
{% set categoryProducts = shuffle(categoryProducts) %}

{% for entry in categoryProducts %}
    {% cache globally using key 'product-' ~ entry.id %}
        ...
    {% endcache %}
{% endfor %}
</code></pre>

CC BY-SA 3.0
2015-11-18T18:14:19.083Z
I hope you didn't mind me messing around with your answer. But I felt sorry and wanted to give Katrin an answer to her caching problem, without adding an answer myself.
carlcs
CC BY-SA 3.0
2015-11-18T20:06:17.657Z
Khalwat, that looks very insightful; makes me wonder, though, if the SQL execution of the query is avoided, since the caching is within the results loop. And, would the shuffle be active; wouldn't  you get the same ordering of results each next time?  I may be missing the logic...
narration_sd
CC BY-SA 3.0
2015-11-19T08:48:04.867Z
@narration_sd no, the criteria models SQL will still run for each request. But each entry's queries don't fire if they are cached, and those queries can be really expensive. Imagine you loop 80 `categoryProducts` and there's three relation queries for each entry, a product category, a product tag and also a product assets query; this would add up to 240 not very small additional queries that you could avoid with this technique.
carlcs
CC BY-SA 3.0
2015-11-19T14:42:31.020Z
Brilliant explanations, thank you all! So, you can cache entry data queries but not ElementCriteriaModel queries - got it! :)
Katrin
CC BY-SA 3.0
2015-11-19T18:30:03.163Z
Not exactly.  The key take-away here is you can ONLY cache HTML output.
andrew.welch
CC BY-SA 3.0
2015-11-20T18:29:30.477Z
Ok, understood now - the answer is half and half. The key to understanding is that no in-loop query-generating lines were in the example. It's the HTML output from those that would be cached. It won't matter that their order was shuffled as their cache is keyed by a fundamental value. And indeed the cost remains for the outside query to get categoryProducts. If it were cached, then no shuffling would occur, so not to cache that is a design choice. Interesting discussion of potential nested cache is here http://craftcms.stackexchange.com/questions/9196/what-effect-does-nesting-cache-tags-have .
narration_sd
CC BY-SA 3.0
2015-11-20T18:33:57.863Z
P.s. This 'exchange' showing the value of careful discussion throughout for tricky topics, can be appreciated...
narration_sd
CC BY-SA 3.0
2015-11-18T14:37:34.350Z
2015-11-18T18:20:51.087Z
2015-11-18T18:20:51.087Z
andrew.welch
<p>I think I am not fully understanding how caching works.</p>

<p>Based on <a href="https://craftcms.stackexchange.com/a/4347/176">this answer</a> I thought I could cache my query and then shuffle the resulting array items. </p>

<p>So I ended up with this code:</p>

<pre><code>{% cache %}
  {% set categoryProducts = craft.entries.section('products').relatedTo(category) %}
{% endcache %}

{% set categoryProducts = shuffle(categoryProducts) %}
{% for entry in categoryProducts %}
  ...
{% endfor %}
</code></pre>

<p>But that does give me a <code>"categoryProducts" does not exist</code> error.</p>

<p>Could someone shed some light as to why caching the query doesn't work? I thought caching tags help to reduce the amount of queries being made and I've been studying the documentation, but I don't seem to fully grasp the concept.</p>

CC BY-SA 3.0
2015-11-18T18:02:17.637Z
I reached out to carlcs (author of the answer you linked to)... That answer contained some misinformation, and he has since deleted it. Caching is a complex and confusing subject, so you'll occasionally see it described inaccurately. But [khalwat is correct](http://craftcms.stackexchange.com/a/12446/45), **the `cache` tag needs to contain HTML output.** If your query was included within the cached segment, then it will be recorded for cache-busting purposes, and not run again unless the data changes.
Lindsey D
CC BY-SA 3.0
2015-11-18T18:08:43.633Z
Sorry Katrin, I actually did think you can cache a criteria model like so and get around that problem. But you can't.
carlcs
<cache>
Caching queries not working as expected
# Caching queries not working as expected

(Asked by: username_0 on 2015-11-18)

I think I am not fully understanding how caching works.
Based on this answer I thought I could cache my query and then shuffle the resulting array items. 
So I ended up with this code:
{% cache %}
  {% set categoryProducts = craft.entries.section('products').relatedTo(category) %}
{% endcache %}

{% set categoryProducts = shuffle(categoryProducts) %}
{% for entry in categoryProducts %}
  ...
{% endfor %}

But that does give me a "categoryProducts" does not exist error.
Could someone shed some light as to why caching the query doesn't work? I thought caching tags help to reduce the amount of queries being made and I've been studying the documentation, but I don't seem to fully grasp the concept.

**Tags:** cache
> **Comments:**
> **username_1**: I reached out to carlcs (author of the answer you linked to)... That answer contained some misinformation, and he has since deleted it. Caching is a complex and confusing subject, so you'll occasionally see it described inaccurately. But [khalwat is correct](http://craftcms.stackexchange.com/a/12446/45), **the `cache` tag needs to contain HTML output.** If your query was included within the cached segment, then it will be recorded for cache-busting purposes, and not run again unless the data changes.  
> **username_2**: Sorry Katrin, I actually did think you can cache a criteria model like so and get around that problem. But you can't.  

---

## 1 answers

### Answer by username_3 on 2015-11-18. Score: 8 | Accepted answer

The {% cache %} tag only caches the HTML output.  That's it.
In your example above, nothing is cached, and categoryProducts will be an empty set.
One thing you could do is to cache each entry individually:
{% set categoryProducts = craft.entries.section('products').relatedTo(category) %}
{% set categoryProducts = shuffle(categoryProducts) %}

{% for entry in categoryProducts %}
    {% cache globally using key 'product-' ~ entry.id %}
        ...
    {% endcache %}
{% endfor %}

> **Comments:**
> **username_2**: I hope you didn't mind me messing around with your answer. But I felt sorry and wanted to give Katrin an answer to her caching problem, without adding an answer myself.  
> **username_4**: Khalwat, that looks very insightful; makes me wonder, though, if the SQL execution of the query is avoided, since the caching is within the results loop. And, would the shuffle be active; wouldn't  you get the same ordering of results each next time?  I may be missing the logic...  
> **username_2**: @narration_sd no, the criteria models SQL will still run for each request. But each entry's queries don't fire if they are cached, and those queries can be really expensive. Imagine you loop 80 `categoryProducts` and there's three relation queries for each entry, a product category, a product tag and also a product assets query; this would add up to 240 not very small additional queries that you could avoid with this technique.  
> **username_0**: Brilliant explanations, thank you all! So, you can cache entry data queries but not ElementCriteriaModel queries - got it! :)  
> **username_3**: Not exactly.  The key take-away here is you can ONLY cache HTML output.  
> **username_4**: Ok, understood now - the answer is half and half. The key to understanding is that no in-loop query-generating lines were in the example. It's the HTML output from those that would be cached. It won't matter that their order was shuffled as their cache is keyed by a fundamental value. And indeed the cost remains for the outside query to get categoryProducts. If it were cached, then no shuffling would occur, so not to cache that is a design choice. Interesting discussion of potential nested cache is here http://craftcms.stackexchange.com/questions/9196/what-effect-does-nesting-cache-tags-have .  
> **username_4**: P.s. This 'exchange' showing the value of careful discussion throughout for tricky topics, can be appreciated...  

---

