Every time you make an async call there is a whole state machine that has to be instantiated and managed. The only situations I would argue justify async over sync:
1. You are making an I/O bounded call and most of the CPU time would otherwise be spent idle.
2. You are making a CPU bounded call that the UI thread cannot directly await.
3. You need to propagate an asynchronous call context for one of the 2 above scenarios.
There are situations where you can put yourself in a position where it seems async needs to be everywhere (i.e., sharding a monolith to a bunch of separate networked elements).
1. You are making an I/O bounded call and most of the CPU time would otherwise be spent idle.
2. You are making a CPU bounded call that the UI thread cannot directly await.
3. You need to propagate an asynchronous call context for one of the 2 above scenarios.
There are situations where you can put yourself in a position where it seems async needs to be everywhere (i.e., sharding a monolith to a bunch of separate networked elements).