Thanks for posting with lots of details.
We do have a reference page related to best practices for analytics: https://dev.twitter.com/ads/analytics/best-practices
For cases where you are primarily concerned with back filling total spend, it might be appropriate to focus on using async (for the wide windows), or even with granularity=TOTAL as a special call. However generally our standard advice is to maintain lowest granularity bucket that you would need to reference later on your end so that you don’t have to re-request for same data over and over.
Backfilling data will be somewhat complicated process with the sync endpoint so it’s strongly recommending to use Async, and for something like ‘realtime stats’ or the equivalent of data you would see when looking at the campaign performance page on ads.twitter.com, it should be appropriate to fetch the latest stats with Sync endpoint. That’s basically the intention we have, to fill data in your DB with async but be able to either do realtime optimization or UI rendering with the sync endpoint (and the rate limit is low so very difficult to do much more than that).
If your data is not matching up for async you may need to work from a smaller example and just go step by step to make sure the smaller chunks of data are adding up to the correct total (even 1 second overlapping can make it off in aggregate).