Facets, grouping and highlighting are what make a search page useful, and what make a query expensive.
These three components do more work per request than the search itself, and all three scale with something other than the number of results returned.
Never send facet.limit=-1 on a high cardinality field
It asks Solr to count and return every distinct value in the field. On a field with a million distinct values that is a million counters built and a million entries serialized, for a menu nobody can read. Ask for the twenty you display.
Set facet.mincount=1
Without it, Solr returns values with zero matches, which is both larger and less useful. It is one parameter and it is almost always right.
Prefer the JSON Facet API for anything nested
It is the newer implementation, it streams better on docValues fields and it avoids the multi-pass work the old parameters do for sub-facets.
Grouping is heavier than it looks
Result grouping keeps per-group state for the whole result set. On a large collection, collapse and expand does the same job with far less memory in most cases.
Highlight the field you display, not every field
Each field in hl.fl is re-analyzed per returned document. A wildcard hl.fl on a wide schema multiplies that by every field in it.
Solr best practices
Faceting, grouping and highlighting (this page)