The JSON Facet API can currently stream facets (use method=stream) from a single node. Each facet bucket is calculated as it is written out, so field cardinality has no effect on memory.
This is only from a single node - normal distributed search/faceting does not stream... But that's what streaming expressions are for anyway!
One current caveat: streaming currently only works with "sort=index asc" (the term order in the Lucene index).
Future work could allow more complex sorts, at the cost of some memory to calculate the sort criteria for each bucket prior to streaming out. Of course more complex sorts would require more complex merging logic (i.e. even a sort by bucket count is not a simple merge sort and requires more buffering in the merging node).