Not the small item the draft assumed — there is no scheduler to wire.
sync_interval_secs is stored and validated and nothing reads it. main.rs spawns exactly two timers: the outbox drain (5s) and an opt-in update check (24h). Mail sync happens only when a client calls Mail.Sync.
The outbox opens a fresh connection per mutation — mail_backend() rebuilds the engine, and apply_remote_mutation connects and logs in each call. Worst case 50 connect/login cycles per 5s per engine; ×10 engines = 500 authentications per 5s against one account. Providers rate-limit authentications far harder than concurrent connections, and some respond with a temporary lockout.
calculate_backoff_ms is dead code.
Scope
A real per-account scheduler driven by sync_interval_secs, with jitter.
One mutex-guarded connection per (engine, account) with mutation priority. Sharing naively queues a mark-read behind a 300-second per-account sync timeout; not sharing needs 2 per account per engine, which exceeds provider caps at fleet scale. Chunk sync per folder so it yields.
Drain the outbox grouped by (account, folder) — one SELECT serving N commands.
Budget on bandwidth, not connections. Gmail publishes 15 simultaneous connections and 2,500 MB/day download, per account; on ladder rungs 2–3 the byte cap binds first.
A fleet_size setting — cross-engine rate limiting is impossible without the coordination layer we decline to build, so each engine's budget is provider_cap / fleet_size.
Honour Retry-Afterwith jitter proportional to fleet_size; ten engines honouring the same deadline retry in the same instant, which is worse than uncoordinated.
Politeness primitives currently unused: LIST-STATUS (RFC 5819, Gmail advertises it) probes every folder's change state in one round trip; COMPRESS=DEFLATE (RFC 4978) reduces metered bytes; NOTIFY (RFC 5465) watches many mailboxes on one connection.
Isolate poison collections — one folder that always fails must not burn the account's 300s timeout every cycle.
Largely parallelizable, but the outbox-grouping half depends on #391.
**Not the small item the draft assumed — there is no scheduler to wire.**
- `sync_interval_secs` is stored and validated and **nothing reads it**. `main.rs` spawns exactly two timers: the outbox drain (5s) and an opt-in update check (24h). Mail sync happens only when a client calls `Mail.Sync`.
- The outbox opens a **fresh connection per mutation** — `mail_backend()` rebuilds the engine, and `apply_remote_mutation` connects and logs in each call. Worst case 50 connect/login cycles per 5s per engine; ×10 engines = 500 authentications per 5s against one account. Providers rate-limit *authentications* far harder than concurrent connections, and some respond with a temporary lockout.
- `calculate_backoff_ms` is dead code.
### Scope
- A real per-account scheduler driven by `sync_interval_secs`, with jitter.
- **One mutex-guarded connection per (engine, account) with mutation priority.** Sharing naively queues a mark-read behind a 300-second per-account sync timeout; not sharing needs 2 per account per engine, which exceeds provider caps at fleet scale. Chunk sync per folder so it yields.
- Drain the outbox grouped by (account, folder) — one `SELECT` serving N commands.
- **Budget on bandwidth, not connections.** Gmail publishes 15 simultaneous connections *and* 2,500 MB/day download, per account; on ladder rungs 2–3 the byte cap binds first.
- A `fleet_size` setting — cross-engine rate limiting is impossible without the coordination layer we decline to build, so each engine's budget is `provider_cap / fleet_size`.
- Honour `Retry-After` **with jitter proportional to `fleet_size`**; ten engines honouring the same deadline retry in the same instant, which is worse than uncoordinated.
- Politeness primitives currently unused: `LIST-STATUS` (RFC 5819, Gmail advertises it) probes every folder's change state in one round trip; `COMPRESS=DEFLATE` (RFC 4978) reduces metered bytes; `NOTIFY` (RFC 5465) watches many mailboxes on one connection.
- Isolate poison collections — one folder that always fails must not burn the account's 300s timeout every cycle.
Largely parallelizable, but the outbox-grouping half depends on #391.
Design: [ADR 0002](https://github.com/KofTwentyTwo/nuncio/blob/dev/docs/adr/0002-multi-engine-sync-model.md) · [review evidence](https://github.com/KofTwentyTwo/nuncio/blob/dev/docs/reviews/2026-08-10-multi-engine-design-review.md) (PR #385)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Not the small item the draft assumed — there is no scheduler to wire.
sync_interval_secsis stored and validated and nothing reads it.main.rsspawns exactly two timers: the outbox drain (5s) and an opt-in update check (24h). Mail sync happens only when a client callsMail.Sync.mail_backend()rebuilds the engine, andapply_remote_mutationconnects and logs in each call. Worst case 50 connect/login cycles per 5s per engine; ×10 engines = 500 authentications per 5s against one account. Providers rate-limit authentications far harder than concurrent connections, and some respond with a temporary lockout.calculate_backoff_msis dead code.Scope
sync_interval_secs, with jitter.SELECTserving N commands.fleet_sizesetting — cross-engine rate limiting is impossible without the coordination layer we decline to build, so each engine's budget isprovider_cap / fleet_size.Retry-Afterwith jitter proportional tofleet_size; ten engines honouring the same deadline retry in the same instant, which is worse than uncoordinated.LIST-STATUS(RFC 5819, Gmail advertises it) probes every folder's change state in one round trip;COMPRESS=DEFLATE(RFC 4978) reduces metered bytes;NOTIFY(RFC 5465) watches many mailboxes on one connection.Largely parallelizable, but the outbox-grouping half depends on #391.
Design: ADR 0002 · review evidence (PR #385)