Who this is for. The developer whose product finder is fast on a test catalogue and slow on the real one, and the one sizing a finder before it is built. Afterwards you can say what every count on the page costs, and choose between counting less and caching more.
What a count costs
Every facet marked Renderable on a Faceted Search view is one aggregation: Elasticsearch groups every product that matches the current query and filters by that facet's values, counts each group, sorts the groups by the facet's Order and returns as many as its Limit. It does this for every renderable facet, on every request, over the whole matching set, not only the page of results shown. So the cost grows with three things: the number of renderable facets, the number of matching products, and the number of distinct values in each facet. A browse page with no query and no filters matches the whole catalogue, which makes it the most expensive page of the finder, and often the most visited.
Two habits multiply the cost: true counts within a facet, which add a full search for each facet with a selection (Facets with a text query), and a facet with many distinct values, such as a product code, made renderable when it is only ever filtered on. Measure before mitigating: compare the search page's response time with and without facets on a copy of the real catalogue (Measure first).
Mitigation 1: count only the facets the page shows
Only renderable filter fields are aggregated, so the count you do not ask for costs nothing:
- Mark Renderable only the facets this page displays, and give a page that shows fewer facets its own view: a category landing page with three facets does not need the twelve of the full finder.
- Do not make a Hidden facet renderable. A facet marked Hidden but still renderable on the view is counted and then thrown away, never displayed. Filter on it without Renderable.
- Keep each facet's Limit to what the interface lists. A facet that shows ten options does not need fifty buckets.
The trade-off: a facet that is not counted cannot be shown with counts on that view, and every extra view is one more record to keep in step with the templates that call it.
Mitigation 2: cache the counts
A search page whose template declares every parameter that changes it can be stored by the page cache, one copy per combination, for signed-out visitors (Caching: declare every parameter the page reads). Declare q, page, orderBy and every facet parameter the finder uses, with PHP's underscore for the dot: fields.brand is declared as fields_brand. Declare the same list on every render, by name rather than from the facets returned: the cache keeps one list of parameters for each path, and a render that declares a different list replaces it. To bound how stale a stored copy can be, give the page a shorter life than the site's default of a day: