<p>Both are essentially the same query, the only thing that differs is the WHERE statement.
The ID approach will always be the most efficient, since it uses the primary key index, thus finding the result faster. </p>

<p>You could also do the first example the same way you did the second one:</p>

<pre><code>{% set entry = craft.entries.section('information').slug('about').first() %}
&lt;h2&gt;{{ entry.title }}&lt;/h2&gt;
{{ entry.summary }}
</code></pre>

CC BY-SA 3.0
2016-11-28T21:04:37.567Z
I realised that but as you wrote I expected the ID to be the most efficient
Paul Frost
CC BY-SA 3.0
2016-11-28T13:06:05.480Z
2016-11-28T13:06:05.480Z
Gustavs
<p>Working with singles you can use them both. However, the set has the advantage that you can apply multiple filters etc. on it afterwards. Especially handy with more complex designs and when working with channels etc.</p>

CC BY-SA 3.0
2016-11-28T21:18:29.537Z
I do use set for some complex filters on some entries already and they are easy to build up.
Paul Frost
CC BY-SA 3.0
2016-11-28T16:50:47.013Z
2016-11-28T16:50:47.013Z
Jan_dh
<p>Personally I would pick the For loop to keep my code look equal plus you are looping over an entry so in my opinion you should use FOR</p>

CC BY-SA 3.0
2016-11-28T15:41:02.910Z
2016-11-28T15:41:02.910Z
Justin Dekkers
<p>Regardless of the number of elements involved, Craft will return an iterable <a href="https://craftcms.com/docs/templating/elementcriteriamodel" rel="nofollow noreferrer">ElementCriteriaModel</a> whenever you query for content (e.g. via <code>craft.entries</code>, or using relational FieldTypes like Assets, Entries or Categories).</p>

<p>This means that even if you <em>know</em> that there'll only be a single element returned (e.g. when you query for a Single section entry, or have a relational field restricted to a single element) using a <code>for</code> loop to actually access that element is totally viable and whether to actually use a loop or not in such cases, is mostly a matter of personal preference. </p>

<p>Looping on single-element query results may seem counter-intuitive, although you're not actually looping on a single element, but the ElementCriteriaModel (which just happens to "contain" a single element and not several). Personally I tend to only use loops when I actually <em>need</em> loops (i.e. there is or could be more than one element returned), but its up to you.</p>

<p>In any case, beyond personal preference there are a few minor differences to each approach.</p>

<p>Using a <code>{% for %}</code> loop, it's easy to render alternative content if the query doesn't return anything, by adding an <code>{% else %}</code> statement:</p>

<pre><code>{% for entry in craft.entries.section('mySingleSection') %}
    &lt;h1&gt;{{ entry.title }}&lt;/h1&gt;
{% else %}
    &lt;p&gt;Sorry, the entry wasn't found!&lt;/p&gt;
{% endfor %}
</code></pre>

<p>Using <code>.first()</code> and <code>{% set %}</code>, you should – in most cases – add an <code>{% if %}</code> statement testing the value returned, to avoid template errors if the query doesn't return a valid element:</p>

<pre><code>{% set entry = craft.entries.section('mySingleSection').first() %}
{% if entry %}
   &lt;h1&gt;{{ entry.title }}&lt;/h1&gt;
{% endif %}
</code></pre>

<p>Also using <code>.first()</code> and <code>{% set %}</code>, it's easy to declare fallback data if the query doesn't return anything, using the <code>|default</code> filter – this may negate the need for an <code>{% if %}</code> statement:</p>

<pre><code>{% set imageUrl = entry.assetsField.first().url|default('/assets/fallback.jpg') %}
&lt;img src="{{ imageUrl }}" /&gt;
</code></pre>

<p>Performance-wise, I doubt there'll be any real-world difference between the two methods, with only a single element involved.</p>

<p>As for the query part of your question; even if you're using a <code>for</code> loop, Craft won't run the <code>craft.entries</code> query in your example more than once – which is why you're seeing the same amount of queries in your profiling report. When talking about queries and performance, it's however worth noting that both the amount of queries and the <em>efficiency</em> of those queries are relevant. In your example, the first query will probably be a tiny, tiny bit faster than the second (Gustavs' answer explains why).</p>

CC BY-SA 3.0
2016-11-28T21:25:59.817Z
Thanks Mats, that's a useful summary of example uses. I hadn't thought about using the default filter in case it was empty.
It's the fact that there umpteen ways to do everything that I find it hard to know what is the BEST method.
Paul Frost
CC BY-SA 3.0
2016-11-28T18:16:31.490Z
2016-12-01T08:16:50.997Z
2016-12-01T08:16:50.997Z
Mats Mikkel Rummelhoff
<p>On my home page template I include a couple of extracts from single entries and I'm not sure which is the best/most efficient way to call them.</p>

<pre><code>{% for entry in craft.entries.section('information').slug('about') %}
    &lt;h2&gt;{{ entry.title }}&lt;/h2&gt;
    {{ entry.summary }}
{% endfor %}
</code></pre>

<p>or</p>

<pre><code>{% set entry = craft.entries.id(13).first() %}
&lt;h2&gt;{{ entry.title }}&lt;/h2&gt;
{{ entry.summary }}
</code></pre>

<p>They both generate the same amount of queries in the Chrome dev tools profile summary report, but I don't understand why, as the second looks like it's more specific and not a loop.</p>

<performance><best-practice>
Which is best practice, SET or FOR?
# Which is best practice, SET or FOR?

(Asked by: username_0 on 2016-11-28)

On my home page template I include a couple of extracts from single entries and I'm not sure which is the best/most efficient way to call them.
{% for entry in craft.entries.section('information').slug('about') %}
    {{ entry.title }}
    {{ entry.summary }}
{% endfor %}

or
{% set entry = craft.entries.id(13).first() %}
{{ entry.title }}
{{ entry.summary }}

They both generate the same amount of queries in the Chrome dev tools profile summary report, but I don't understand why, as the second looks like it's more specific and not a loop.

**Tags:** performance, best-practice


---

## 4 answers

### Answer by username_4 on 2016-11-28. Score: 8 | Accepted answer

Regardless of the number of elements involved, Craft will return an iterable ElementCriteriaModel whenever you query for content (e.g. via craft.entries, or using relational FieldTypes like Assets, Entries or Categories).
This means that even if you know that there'll only be a single element returned (e.g. when you query for a Single section entry, or have a relational field restricted to a single element) using a for loop to actually access that element is totally viable and whether to actually use a loop or not in such cases, is mostly a matter of personal preference. 
Looping on single-element query results may seem counter-intuitive, although you're not actually looping on a single element, but the ElementCriteriaModel (which just happens to "contain" a single element and not several). Personally I tend to only use loops when I actually need loops (i.e. there is or could be more than one element returned), but its up to you.
In any case, beyond personal preference there are a few minor differences to each approach.
Using a {% for %} loop, it's easy to render alternative content if the query doesn't return anything, by adding an {% else %} statement:
{% for entry in craft.entries.section('mySingleSection') %}
    {{ entry.title }}
{% else %}
    Sorry, the entry wasn't found!
{% endfor %}

Using .first() and {% set %}, you should – in most cases – add an {% if %} statement testing the value returned, to avoid template errors if the query doesn't return a valid element:
{% set entry = craft.entries.section('mySingleSection').first() %}
{% if entry %}
   {{ entry.title }}
{% endif %}

Also using .first() and {% set %}, it's easy to declare fallback data if the query doesn't return anything, using the |default filter – this may negate the need for an {% if %} statement:
{% set imageUrl = entry.assetsField.first().url|default('/assets/fallback.jpg') %}


Performance-wise, I doubt there'll be any real-world difference between the two methods, with only a single element involved.
As for the query part of your question; even if you're using a for loop, Craft won't run the craft.entries query in your example more than once – which is why you're seeing the same amount of queries in your profiling report. When talking about queries and performance, it's however worth noting that both the amount of queries and the efficiency of those queries are relevant. In your example, the first query will probably be a tiny, tiny bit faster than the second (username_1' answer explains why).

> **Comments:**
> **username_0**: Thanks Mats, that's a useful summary of example uses. I hadn't thought about using the default filter in case it was empty. It's the fact that there umpteen ways to do everything that I find it hard to know what is the BEST method.  

---

### Answer by username_1 on 2016-11-28. Score: 5

Both are essentially the same query, the only thing that differs is the WHERE statement.
The ID approach will always be the most efficient, since it uses the primary key index, thus finding the result faster. 
You could also do the first example the same way you did the second one:
{% set entry = craft.entries.section('information').slug('about').first() %}
{{ entry.title }}
{{ entry.summary }}

> **Comments:**
> **username_0**: I realised that but as you wrote I expected the ID to be the most efficient  

---

### Answer by username_2 on 2016-11-28. Score: 2

Working with singles you can use them both. However, the set has the advantage that you can apply multiple filters etc. on it afterwards. Especially handy with more complex designs and when working with channels etc.

> **Comments:**
> **username_0**: I do use set for some complex filters on some entries already and they are easy to build up.  

---

### Answer by username_3 on 2016-11-28. Score: 0

Personally I would pick the For loop to keep my code look equal plus you are looping over an entry so in my opinion you should use FOR


---

