Element Query Builder
Build Craft CMS element queries for entries, assets, users, and categories.
// Configure options on the left to generate your element query
Craft CMS Element Query Builder — How It Works
Craft CMS uses a powerful element query system to fetch content from the database. Every content type in Craft — entries, assets, categories, tags, and users — is an element, and each element type has a dedicated query class with a fluent method-chaining API. This builder generates both Twig and PHP versions of your query so you can drop the code directly into your templates or modules.
In Twig templates, element queries are built using the global service objects: craft.entries(), craft.assets(), craft.categories(), craft.users(), and craft.tags(). Each method returns an element query object that you chain with criteria like .section('blog'), .limit(10), and .orderBy('postDate DESC'), ending with .all(), .one(), or .count().
PHP Element Queries
In PHP modules and plugins, element queries use the static ::find() method on the element class: Entry::find(), Asset::find(), Category::find(), User::find(), and Tag::find(). The criteria methods are identical to Twig — the same ->section('blog'), ->limit(10) chain works in both contexts, making it easy to convert between template and PHP code.
Eager Loading for Performance
The most important performance optimization for Craft queries is eager loading. When you loop over entries and access a relational field (like an Assets or Entries field) inside the loop, Craft fires a separate SQL query for each entry — an N+1 problem. Solve it by using the .with(['fieldHandle']) parameter on your query. The builder's "Eager Load" field accepts comma-separated field handles and wraps them in the correct .with([...]) syntax. Nested eager loading is also possible using dot notation: relatedEntries.heroImage.
Status and Visibility
By default, Craft element queries only return live (enabled and within date range) elements. Set .status(null) or use 'any' to include disabled entries in your results — useful for admin previews or draft content workflows. For entries, the live status checks both the enabled flag and the post/expiry date. The disabled status returns only explicitly disabled entries.