---
title: Cache repeated Liquid filter results with assign
description: >-
  Cache filter results in variables using `assign` instead of calling the same
  filter multiple times to eliminate redundant per-call overhead.
source_url:
  html: >-
    https://shopify.dev/docs/storefronts/themes/best-practices/performance/avoid-repetitive-filter-calls
  md: >-
    https://shopify.dev/docs/storefronts/themes/best-practices/performance/avoid-repetitive-filter-calls.md
api_name: liquid
---

# Cache repeated Liquid filter results with assign

Cache filter results in variables using [`assign`](https://shopify.dev/docs/api/liquid/tags/assign) instead of calling the same filter multiple times with the same arguments.

***

## Why

Some filters have a performance cost. Individual calls might be fast (microseconds), but repeated calls add up. The [Theme Inspector](https://shopify.dev/docs/storefronts/themes/tools/theme-inspector) can show you filters called thousands of times in a single page render, accumulating to 100 ms or more.

***

## How

Use [`assign`](https://shopify.dev/docs/api/liquid/tags/assign) to store filter results in variables, and reuse them instead of calling the filter multiple times. Use the **Theme Inspector** sandwich view to identify which filters are called most frequently.

***

## Examples

Less performant:

```liquid
{%- for product in collection.products -%}
  <img src="{{ product.featured_image | image_url: width: 300 }}" />
  <img src="{{ product.featured_image | image_url: width: 300 }}" />
  {%- comment -%} Calls image_url twice for the same result {%- endcomment -%}
{%- endfor -%}
```

More performant:

```liquid
{%- for product in collection.products -%}
  {% assign product_image = product.featured_image | image_url: width: 300 %}
  <img src="{{ product_image }}" />
  <img src="{{ product_image }}" />
{%- endfor -%}
```

Using the Theme Inspector sandwich view:

1. Generate a flame graph for your page.
2. Switch to sandwich view.
3. Sort by **Self** time to see cumulative impact.
4. Look for operations called hundreds or thousands of times.
5. Optimize by caching results or moving operations outside loops.

For example, you might see `filter:image_url` take 50 µs per call, but it's called 2,000 times (100 ms total).

***

## Testing

* Use the **Theme Inspector** Chrome extension sandwich view to identify repetitive filter calls.
* Sort by **Self** time to see cumulative impact.
* Compare TTFB before and after caching filter results.

***

## References

* [`image_url`](https://shopify.dev/docs/api/liquid/filters/image_url) filter
* [`assign`](https://shopify.dev/docs/api/liquid/tags/assign) tag
* [`for`](https://shopify.dev/docs/api/liquid/tags/for) tag
* [`product.featured_image`](https://shopify.dev/docs/api/liquid/objects/product#product-featured_image)
* [Debugging common causes for slow loading in Shopify Liquid storefronts](https://performance.shopify.com/blogs/blog/debugging-common-causes-for-slow-loading-in-shopify-liquid-storefronts)
* [Avoid deeply nested Liquid loops](https://shopify.dev/docs/storefronts/themes/best-practices/performance/avoid-deeply-nested-liquid-loops)
* [Move operations outside loops](https://shopify.dev/docs/storefronts/themes/best-practices/performance/move-operations-outside-loops)
* [Cache `block.settings` in a variable](https://shopify.dev/docs/storefronts/themes/best-practices/performance/assign-block-settings-to-variable)

***
