It can be tempting to lean on them for broader use cases. For example, it can be unperformant to query something like "select all foos with at least one bar", where foos has_many
bars. However, in this case, rather than using a counter cache as a proxy for what you want, you can model what you want better. For example, oftentimes the question you're really trying to answer is "select all foos that have transitioned to a certain state", e.g. "created" to "started". Then, you can simply select by that status, which is much closer to the business logic.