Aggregation pipelines are where most MongoDB performance problems either get solved or get born. The order of stages, the shape of your indexes, and how early you can discard documents all compound quickly at scale.
The single highest-leverage habit is pushing $match stages as early as possible, ideally as the very first stage, so the query planner can use an index before any documents are transformed. Every stage after a $project that reshapes fields loses the ability to use indexes on those fields for the rest of the pipeline.
For GetMeChai's creator dashboard, moving a $match ahead of a $lookup cut aggregate response times from around 900ms to under 150ms on the payments collection, because the lookup no longer had to join against the full unfiltered set.
$facet is powerful for building dashboards that need multiple shapes of the same underlying data (totals, breakdowns, and a paginated list) in a single round trip, but it runs each sub-pipeline independently, so it is not a shortcut around indexing each branch correctly.
Finally, explain plans are non-negotiable. Running .explain('executionStats') on any pipeline touching more than a few thousand documents should be part of the review checklist before it ships.