Layers

Reading Optimizer Decisions

Where to see what the optimizer did, why, and what to do about it.

View as Markdown

Every optimizer action is logged and visible. This page shows where to find decisions and how to interpret them.

Where decisions show up

SurfaceWhat it shows
Ad detail panel → Optimizer tabEvery action on this ad.
Ad set / campaign → Optimizer activity widgetRecent actions in this scope.
Notifications inboxMaterial decisions (pauses, scale-ups).
Audit log (Org-level)All actions across all layers.

Anatomy of a decision

2026-04-19 06:00 UTC
Action: PAUSE
Subject: Ad "Hook variant 3"
Inputs:
  - 7d spend:        $32.00
  - 7d conversions:  1
  - CPA:             $32.00 (target: $12.00)
  - Frequency:       4.2
  - Age:             12 days
State: FATIGUED
Reason: CPA exceeds target by 167% over a 7d window with high frequency.
Guardrails passed: age >= 3d, spend >= $5, not TOP_PERFORMER, not last in adset.
Replacement: Pinned "Hook variant 7" from creative pool (organic_score 6.4).

Every field is meaningful. Read all of them before pushing back.

Common decisions and how to read them

Pause + replace

The most common action. The optimizer paused an ad and brought a new one in from the eligible pool. Usually correct. Look at the new ad's performance over the next 3 days.

Pause without replace

The optimizer paused but couldn't find a replacement (eligible pool empty, last in ad set, etc.). The ad set runs short. Investigate:

  • Is your eligible pool too small? Generate more, approve more, lower the score threshold via override = 'include'.
  • Is the ad set's audience too narrow? Re-target.

Scale up

The optimizer raised an ad set's budget. Budget adjustments are capped at 50% of the current value and $100 absolute in a single step. Watch for spend efficiency over the next 3 days.

Hold (no action)

The optimizer evaluated but did nothing. Often you'll see "Hold — within performance tolerance" or "Hold — guardrail (only 2 days old)". Holds are healthy. Frequent holds = stable system.

Refresh ad set creative pool

Triggered nightly. Disables underperformers, brings in new from pool. Same as pause+replace at scale.

Disagreeing with the optimizer

Two ways to push back:

  1. Manual override — pause / activate ads directly. The optimizer respects user decisions and won't immediately undo them.
  2. override column — set 'include' to keep an ad eligible regardless of score, 'exclude' to keep it out.

If you find yourself overriding repeatedly, file feedback with support — either the optimizer logic needs tuning, or your config (CPA target, fatigue thresholds) needs adjustment.

Pause the optimizer

Layer settings → Pause optimizer. The optimizer continues collecting metrics but takes no actions until re-enabled.

On this page