Limit how many items a Liquid array fetches
Fetch only the items that you'll render. For collection.products and collections, a for loop's limit parameter is enough. Other Liquid arrays need the paginate tag.
Each product that a Liquid array loads carries database queries for variant data, images, pricing, and availability. Fetching 50 products to render 4 multiplies those queries, which increases TTFB and delays FCP and LCP.
How you avoid the extra fetch depends on the array.
Anchor to [object Object], and ,[object Object],: ,[object Object], is enoughcollection.products and collections: limit is enough
collection.products and collections: limit is enoughBoth of these arrays reduce the fetch to match a for loop's limit, so no paginate wrapper is needed:
The optimization applies when the loop isn't already inside a {% paginate %} block and the limit is below the array's default page size, which is 50 for collection.products and 1,000 for collections. Without a limit, the loop fetches the full default page size.
Don't reach for {% paginate %} to fix a one-off carousel or featured-products row. A {% paginate %} block responds to the page URL parameter, so a section that's wrapped in one renders different items, or none at all, on ?page=2. Use limit for fixed-size lists and reserve {% paginate %} for lists that a customer actually pages through.
Don't reach for {% paginate %} to fix a one-off carousel or featured-products row. A {% paginate %} block responds to the page URL parameter, so a section that's wrapped in one renders different items, or none at all, on ?page=2. Use limit for fixed-size lists and reserve {% paginate %} for lists that a customer actually pages through.
Anchor to Other arrays: use ,[object Object]Other arrays: use paginate
paginateblog.articles, search.results, product.variants, pages, customer.orders, customer.addresses, and article.comments don't reduce their fetch in response to limit. For these, limit controls iterations only, and {% paginate %} controls the fetch:
Keep both paginate by 4 and limit: 4. The paginate tag limits the database query, and limit caps the iterations.
Anchor to ExamplesExamples
Anchor to Featured productsFeatured products
A fixed-size row of products needs limit only. Adding {% paginate %} here would couple the row to the page URL parameter:
Anchor to Blog articlesBlog articles
blog.articles doesn't respond to limit, so this one needs the paginate wrapper:
Anchor to Recommended limits by section typeRecommended limits by section type
| Section type | Recommended limit | Reasoning |
|---|---|---|
| Featured products | 4 to 6 | Above the fold, highly visible |
| Carousels (initial load) | 4 to 8 | Only show what's initially visible |
| Product recommendations | 2 to 4 | Most relevant only |
| Grid sections | 8 to 12 | Balance between content and load time |
| Paginated collections | 24 to 50 | Per-page limit with pagination controls |
Anchor to TestingTesting
- Use the Theme Inspector to compare Liquid render time with different product limits.
- Measure TTFB in the Chrome DevTools Network panel with different query sizes.
- Check the
server-timingheader for database query counts.
Anchor to ReferencesReferences
paginatetagfortag- Dawn PR #3688: pagination pattern applied to the Dawn theme
- Avoid deeply nested Liquid loops
- Limit pagination depth
- Use the Section Rendering API