Deferred ops decision from the #243 reliability review (orbit-ui-mobile#243 iteration 2).
Context
All 13 recurring background jobs are verified idempotent (Sent* unique constraints + convergent mutators), so flipping BackgroundServices__UseDurableQueue=true (Hangfire, Postgres-backed) is safe from double-effects. Hangfire is already fully wired; the flip is a pure env-var change.
Why held (2026-07-11)
- Prod is a single Render instance (starter plan), so the "double-fire on scale" motivation does not apply.
- The in-process scheduler loops already self-heal on restart (each tick re-scans from the DB), so the only gain today is marginal restart-durability.
- The session pool is hard-capped at
SessionMaxPoolSize=2 and is shared with the Hangfire durable queue (2 workers) — tight on the starter plan.
Action when scaling to 2+ instances
- Bump
SessionMaxPoolSize (and/or the Render plan / Supabase pool) to give Hangfire's 2 workers + scheduler headroom above migrations.
- Set
BackgroundServices__UseDurableQueue=true on the orbit-api Render service.
- Verify a rollout: no double-notifications / double-XP (idempotency guards already cover this), and pool saturation stays healthy.
Refs thomasluizon/orbit-ui-mobile#243
Deferred ops decision from the #243 reliability review (orbit-ui-mobile#243 iteration 2).
Context
All 13 recurring background jobs are verified idempotent (Sent* unique constraints + convergent mutators), so flipping
BackgroundServices__UseDurableQueue=true(Hangfire, Postgres-backed) is safe from double-effects. Hangfire is already fully wired; the flip is a pure env-var change.Why held (2026-07-11)
SessionMaxPoolSize=2and is shared with the Hangfire durable queue (2 workers) — tight on the starter plan.Action when scaling to 2+ instances
SessionMaxPoolSize(and/or the Render plan / Supabase pool) to give Hangfire's 2 workers + scheduler headroom above migrations.BackgroundServices__UseDurableQueue=trueon the orbit-api Render service.Refs thomasluizon/orbit-ui-mobile#243