Why this is more than a report#
Advertising optimization changes live spend. A good model is insufficient unless the system also handles incomplete and delayed reports; cold-start keywords; exploration versus exploitation; campaign and account budget policy; API throttling and partial mutation failure; divergence between local desired state and remote actual state; intraday overspend before daily data is complete; and rollback, audit, and operator review.
Four control loops#
| Loop | Cadence | Responsibility |
|---|---|---|
| Structural discovery | periodic | sync campaigns, ad groups, product ads, keywords, and metadata so optimization operates on current account structure |
| Daily optimization | daily | performance history and policy propose bids and budgets; empirical-Bayes conversion reasoning with fitted priors by bucket |
| Desired-state sync | continuous | proposed state is written locally first; dirty differences are reconciled with Amazon by a dedicated, inspectable mutation path |
| Intraday throttle | independent | watches spend and can cut exposure before the next daily run - safety does not depend on the model completing successfully |
The key architectural decision: reasoning and side effects are separate loops. The optimizer proposes; the synchronizer mutates; the throttle protects. Each can be understood, audited, and retried on its own.
Exploration and cold start#
Unknown keywords need structured exploration, not a default bid pretending uncertainty does not exist. The design work covers cold-start priors, above-known-range extrapolation, dynamic top-N behavior, and conversion-rate change points. In production, the exploration cache scaled to roughly 2.54 million rows, daily keyword bid history processed 77,000-202,000 rows per day, backed by a comprehensive regression test suite.
Failure modes the loops absorb#
- Sparse data producing overconfident bids → priors.
- Behavior changes after price or listing changes → change-point analysis.
- Partially successful API mutations → desired/actual separation, inspectable retries.
- A remote user changing state outside the optimizer → structural discovery re-syncs.
- Reporting lag obscuring current spend → the independent throttle.
- A daily process failing while campaigns keep spending → again, the independent throttle.