Each room the sweep looks at costs a live /messages fetch of up to 50 events, and the sweep ran for every joined room after every sync response, so a busy account fetched thousands of times an hour whatever the sync itself carried. The sweep now covers the rooms the response names (sliding sync's UpdateSummary rooms, classic's joined rooms), with a full pass first and every five minutes.
The sdk sends the crypto store's next_batch_token as extensions.to_device.since. Classic /sync writes its own token there, which the homeserver refuses (400, should look like an int), so every start fell back to /sync and wrote the classic token again. The daemon now replaces a non-integer token with 0 before the client opens the store.