Rules — best practices for scaling and protecting

Last updated: May 19, 2026

Rules — best practices for scaling and protecting

Recipes for the 4 most useful rule patterns + practices that prevent automation surprises. All recipes use verified Wevion enums (no invented metrics or operators) + conservative protection defaults. Each recipe is a starting point — tune thresholds to your account's typical performance.

Who is this for

Anyone designing rules beyond the first one. Reference patterns to copy-and-tune.

The 4 essential recipes

Recipe 1: Kill losers

Pause ad sets where CPA has clearly broken the target.

entity_level: adset
condition_logic: AND
conditions:
  - metric: cpa, operator: gt, value: <target × 1.5>, time_range: last_7d
  - metric: spend, operator: gt, value: 50, time_range: last_7d
actions: [pause]
cooldown_minutes: 360
max_executions_per_day: 5
notify_on_execution: true

Why both conditions: CPA alone fires on low-volume ad sets where 1-2 conversions create noise. Pairing with spend > 50 ensures meaningful data.

Why × 1.5: gives natural variance room; you want to kill clearly-broken ad sets, not borderline.

Recipe 2: Scale winners

Increase budget on ad sets where ROAS clearly beats target.

entity_level: adset
condition_logic: AND
conditions:
  - metric: roas, operator: gt, value: <target × 1.2>, time_range: last_3d
  - metric: spend, operator: gt, value: 50, time_range: last_3d
actions:
  - type: increase_budget_pct, params: {pct: 20}
cooldown_minutes: 720
max_executions_per_day: 3
budget_change_limit_pct: 50
budget_daily_cap: <choose per workspace>
notify_on_execution: true

Why last_3d (not 7d): scale faster on winners.

Why +20% (not +50%): conservative; ramps over multiple days. Auction systems prefer gradual changes.

Why budget_daily_cap essential: prevents 3× +20% in one day from compounding to +73% if rule fires multiple entities.

Recipe 3: Protect daily spend

Alert when daily budget is mostly consumed early in the day.

entity_level: campaign
condition_logic: AND
conditions:
  - metric: budget_spent_pct, operator: gt, value: 80, time_range: today
actions: [notify_only]
schedule_type: interval
interval_minutes: 30
cooldown_minutes: 360
notify_on_execution: true
notify_channels: {in_app: true, telegram: true}

Why notify_only: budget-protection decisions usually require human judgment (raise budget vs let it cap).

Why interval: 30 min: faster detection on critical alert.

Recipe 4: Frequency cap

Pause ad sets when frequency signals creative fatigue.

entity_level: adset
conditions:
  - metric: frequency, operator: gt, value: 5, time_range: last_7d
actions: [pause]
cooldown_minutes: 720
notify_on_execution: true

frequency > 5 is platform-specific guidance — adjust per your audience size + relaunch cadence.

Practices

Preview before activating (always)

Every new rule + every significant edit: preview first. See rul-109.

If you skip preview: you're activating against unknown scope.

Start narrow

First version of a new rule: one ad account, tight name_contains filter, single condition. Watch execution history for a week. Then expand.

Don't ship a rule that scans all accounts on day one.

Start with notify_only

For any new rule + any significant change: action = notify_only for 1-2 weeks. Validate matches are right. Then switch to real action.

The cost of staying in notify_only longer is "you do more manual work for 2 weeks." The cost of activating a wrong rule is "spend impact across multiple campaigns."

Conservative cooldowns

For destructive actions (pause, decrease_budget_pct): cooldown ≥ 360 min default. Lower only if you've validated the metric is stable + the noise pattern is understood.

Pair metrics with spend guards

Any rule on roas, cpa, cpl, ctr, conv_rate etc.: add a spend > N guard.

Low-volume ad sets have wild metrics. Without spend guards, a brand-new ad set with $5 spend and 0 purchases has CPA = infinity, ROAS = 0 — and your rule pauses it after 1 day. Almost never what you want.

Notify_on_execution on production rules

You want to know what your automation did. The cost of noise is low; the cost of silent surprise is high.

Use templates as reference patterns

Even if you don't use a template directly, reading its conditions teaches you patterns. See rul-110.

Audit weekly first month, monthly after

For each rule: check execution history weekly first month, then monthly. Look for:

  • Acting on wrong entities (refine scope)

  • Excessive skips (cooldown / cap too tight, or expected)

  • Errors (fix root cause + monitor)

  • Zero acts (rule too strict; loosen or remove)

Document rule intent

Use the description field. 6 months later, "Rule 1" tells you nothing. "Kill ClientA prospecting losers with stable CPA target $35 — owner Anna" tells you everything.

Disjoint scopes between rules

Two rules acting on the same entity → conflicts. Either narrow scopes (different name_contains) or coordinate (only one active at a time).

Anti-patterns

  • Aggressive increase_budget_pct (+50% or more): trips auctions, hurts efficiency

  • No budget_daily_cap: rule fires multiple times, compounding budget changes uncontrollably

  • Conditions on postback metrics with today time range: postback data lags 24-72h, rule acts on incomplete data

  • No spend guard on rate metrics: low-volume ad sets trigger on noise

  • One rule for all accounts: hard to audit, easy to misfire

  • Activating without preview: see above

  • notify_on_execution: false: silent automation = no learning loop

Tuning workflow

  1. Build with preview + notify_only

  2. Run 1-2 weeks

  3. Review execution history

  4. Adjust thresholds based on real distributions

  5. Switch action from notify_only to real

  6. Monitor weekly for first month

  7. Move to monthly review

Related