0003 — All scheduled jobs on AWS EventBridge
- Status: Accepted (ADR-0012 temporarily amended this; superseded by ADR-0014 which restores 0003 in full)
- Date: 2026-04-17
- Deciders: Fede
Context
Scheduled jobs today live in four places:
- EC2
setIntervalloops fromsrc/instrumentation.ts(6 processors) - AWS Lambda + EventBridge (tour-reminder, outlook-subscription-renewer)
- macOS
launchd(com.propflow.wo-pipeline.plist, 8-hour interval) - An earlier Trello proposal to put listings sync on Vercel Cron
Four mechanisms to understand, debug, and monitor. Three of them have no proper observability.
Decision
Every scheduled job runs on AWS EventBridge Scheduler and invokes a Lambda under agents/.
| Job | Trigger | Lambda |
|---|---|---|
| Subscription renewal | rate(30 minutes) | agents/outlook-subscription-renewer |
| Tour reminder | rate(1 hour) | agents/tour-reminder |
| Listings sync | rate(15 minutes) | agents/listings-sync |
| Application link | one-shot on tour confirmation | agents/application-link |
| Work order pipeline | rate(8 hours) | agents/wo-pipeline (migrated from launchd) |
Inbox-poll was retired in ADR-0011 once the Microsoft Graph webhook took over real-time inbound delivery.
Vercel Cron is not used. If the web app ever needs its own scheduled job, it also goes to EventBridge.
Consequences
Easier
- One place to see all scheduled jobs (
aws scheduler list-schedules). - One alerting story (CloudWatch alarms on Lambda errors/timeouts).
- One way to pause a job during incidents (disable the schedule).
- No more jobs silently failing because PM2 on EC2 crashed.
Harder
- Migrating launchd jobs means they stop running on a developer Mac and start running in production AWS. Verify they actually fire the first time.
Follow-up work
- Delete
src/instrumentation.tssetInterval processors (see ADR-0006). - Uninstall
com.propflow.wo-pipeline.plistafter migrating. - Document EventBridge schedule management in the runbook.
Alternatives considered
Vercel Cron for listings sync. Proposed in Trello #762 v3 target doc. Rejected because listings sync is agent-side work (scrapes AppFolio, writes unit availability to DDB, consumed by Clara). Per ADR-0001, agent work doesn't run on Vercel.
Keep some EC2 setInterval jobs. Rejected because the whole point is one place for scheduling.
AWS Step Functions. Overkill. We have independent periodic jobs, not multi-step workflows.