Dry-run mode
Why this matters for your business
Automation rules that spend money are the highest-stakes rules in any shop. A misconfigured "auto-bid up by 50%" rule on Meta ads can torch a quarter's budget overnight. A miswired "50% off for at-risk customers" rule can give away thousands in margin in an afternoon. A typo in an SMS-blast condition can fire 50,000 unintended sends and trigger a spam complaint.
Dry-run mode is the safety belt. The rule fires normally — trigger matches, conditions evaluate, action chain queues — but the side effects (the actual money-spending part) don't execute. Instead, the system logs what would have happened. You read the log, verify it matches intent, then flip dry-run off. Mistakes that would cost real money in production become free observations.
What this typically unlocks
| Outcome | Result |
|---|---|
| First-fire surprises on new rules | near 0 |
| Costly automation accidents per year | 0 when dry-run policy enforced |
| Confidence in shipping new rules | high |
| Time spent reviewing rule logic before launch | shorter — see actual fires, not hypothetical |
What you actually get
Three modes per rule:
| Mode | Behaviour |
|---|---|
| Live | Trigger fires, conditions evaluate, actions execute |
| Dry-run | Trigger fires, conditions evaluate, actions are logged but not executed |
| Disabled | Trigger doesn't even attempt to match |
Plus the dry-run log:
- Every fire shown with full payload, condition results, and what each action would have done
- Side-by-side comparison: "actual rule output if live"
- One-click promote-to-live when you're confident
When dry-run is mandatory
For these action types, the system forces a 7-day dry-run period before allowing live execution:
| Action type | Why mandatory |
|---|---|
| Paid ad spend (Meta / Google / TikTok bid changes) | Money out the door per fire |
| SMS sends (any volume) | Per-send cost; spam-complaint risk |
| Mass-tagging (> 10% of customer base in one fire) | Hard to reverse |
| Price changes (catalog) | Customer-facing, complaint-attracting |
| Inventory changes (downward) | Hides products from sale |
You can shorten the dry-run window with explicit override (Pro+), but the system requires confirming "I understand this is a paid- spend / mass-impact rule" — a deliberate friction step.
How it works
What's in a preview log entry
Rule: VIP_email_offer
Fired: 2026-05-10T14:23:00Z
Trigger: customer_tagged (vip)
Customer: cus_abc123
Conditions:
- lifecycleStage = 'loyal' → true
- country = 'US' → true
- lastEmailAt < 7 days ago → true (5 days)
Actions (would have executed):
1. send_transactional_email
Template: vip_welcome
Recipient: jane@example.com
Subject: "Thanks for being VIP — here's a special offer"
2. enroll_journey
Journey: vip-onboarding
Step: 1
Outcome: dry_run_preview (no side effects)
Cost (live): $0 (transactional email, no extra cost)
For paid-spend actions, the cost line shows what would have been charged: "Would have spent $4.20 on 3 SMS sends." A quarter of dry-run logs at $5/fire compounds into "this rule, if live, would have cost $4,200 in 90 days" — useful sanity check.
Real merchant scenarios
Scenario A — New SMS rule caught in dry-run
Brand built a rule: "send SMS when cart abandoned > $500." Tested in dry-run for 7 days.
Preview log showed: 240 fires/week → ~$120/week SMS cost. But
~30% of fires were the same customer — Shopify was firing
multiple cart_abandoned events per cart due to a session-
timeout pattern. Without dry-run, the customer would have
gotten 4 SMSes per cart — and the brand would have paid for
each one + faced spam complaints.
Fix: Added condition last cart-recovery SMS > 24h ago.
Re-ran dry-run for 3 days; clean. Promoted to live.
Scenario B — Auto-bid rule preview saves the budget
Brand wanted: "increase Meta bid by 20% on top-LTV decile." Built it; ran in dry-run.
Preview showed: bids would have increased on 3,400 customers, total spend impact +$1,200/day. However, the rule was firing every time a customer's predicted LTV updated (weekly). With weekly fires, each customer would get +20% × 4 weeks = +82% bid over a month — runaway.
Fix: Added "fire only on first crossing into top decile" guard. Re-tested in dry-run; saw 200 first-time fires/week — stable. Promoted to live.
Scenario C — Mass-tag dry-run avoids a meta-data mess
"Tag every customer with archive if no order in 18 months"
seemed safe. Dry-run preview:
Would tag 28,000 customers (52% of base). The brand realized: that would unintentionally exclude all of them from win-back campaigns. They'd been planning to include archived customers in win-back.
Fix: Changed action to "add dormant_18mo tag" + updated
win-back campaign to include dormant_18mo. Re-ran dry-run;
intent matched. Promoted.
Best practices
✅ Always run dry-run for the full 7 days on paid-spend rules. Captures weekly cycles you wouldn't see in 24 hours.
✅ Read the cost-projection line. "Would have spent $X" tells you the rule's real cost before you commit.
✅ Look at fire-frequency, not just per-fire correctness. A correct rule firing 100× per day is still a problem.
❌ Don't override the dry-run requirement on paid-spend rules. The friction is intentional.
❌ Don't promote based on a 24-hour dry-run. Most patterns emerge over a week.
Plan tiers
| Capability | Free | Starter | Pro | Agency | Enterprise |
|---|---|---|---|---|---|
| Dry-run mode (any rule) | — | ✓ | ✓ | ✓ | ✓ |
| Mandatory 7-day for paid-spend | — | — | ✓ | ✓ | ✓ |
| Cost projection in preview log | — | — | ✓ | ✓ | ✓ |
| Override 7-day requirement | — | — | — | ✓ | ✓ |
| Replay preview log against live data | — | — | — | ✓ | ✓ |