I've audited a lot of GoHighLevel workflows, and there's one pattern I see over and over: the "Send Email" action and the "Send SMS" action stacked back-to-back on the same step, no wait, no branch. The contact enters the workflow, and within a second they get both messages. The builder thinks they're being thorough. What they're actually doing is inflating their unsubscribe rate and burning through their most expensive channel on people who would have converted from the free one.

Full disclosure: I work for Ready, and we build SMS tooling that plugs into GHL. So I have a bias toward SMS being used well — which is exactly why I don't want you spraying it at everyone who just got an email.

Why simultaneous send doubles your unsub rate

Think about what the contact experiences. They get an email. A beat later, their phone buzzes with a text saying roughly the same thing. To them, that reads as aggressive — not helpful. SMS is a permission channel that lives in the same inbox as messages from their mom. When you use it as a carbon copy of an email they already have, the reaction is "why is this brand texting me the thing they just emailed me?"

That reaction produces two costs:

  1. Higher SMS opt-outs. People reply STOP not because they hate the offer, but because the redundancy feels like overreach. Every STOP is a contact you can never text again — Ready honors the opt-out automatically and propagates it across every campaign, so a STOP triggered by a redundant blast costs you that contact permanently.
  2. You paid for a message that did no work. On Ready Standard, a single-segment SMS is $0.02 plus the $0.0045 carrier pass-through — $0.0245. If half your list would've opened the email anyway, half of your SMS spend on that step was pure waste, and it also earned you unsubscribes. You paid to shrink your own list.

The fix isn't "send less." It's "send SMS conditionally, after email has had a chance to do its cheaper job."

The core idea: SMS as the fallback, not the twin

Email is nearly free. SMS costs real money per segment and carries opt-out risk. So the sane sequence is:

  • Send the email first.
  • Wait long enough to see whether it landed and got engagement.
  • Only fire the SMS if the email didn't land or didn't get opened/clicked.

That way SMS goes to the subset that actually needs a second touch — the stalled or unreachable ones — instead of the whole list. Your SMS volume drops, your relevance per text goes up, and your unsub rate falls because every text now feels like a genuine nudge rather than a duplicate.

Building the branch in a GHL workflow

Here's the structure I use. Assume this is a lifecycle step — an offer, a booking reminder, a re-engagement, whatever.

  1. Send Email action.
  2. Wait step — this is the whole game. Give the email room to breathe. For a promo, 4–24 hours. For a time-sensitive reminder, maybe 1–2 hours. The wait is what lets engagement data accumulate.
  3. If/Else branch on email engagement. GHL exposes email events (opened, clicked, bounced). Branch on: did the contact open or click the email?
  • Yes (engaged) → do nothing, or route to the next lifecycle step. No SMS. You already reached them cheaply.
  • No (stalled) OR email bounced/failed → fall through to the SMS action.
  1. Send SMS — only the stalled/unreachable branch gets here.

The bounce case matters more than people realize. A hard-bounced email means you have no working email for that contact. That's the single best-justified reason to spend an SMS segment — it's your only remaining owned channel to them.

A cleaner condition than "opened"

Open tracking is noisy now — Apple Mail Privacy Protection fires opens whether or not a human looked. If your list skews Apple, "opened = yes" will suppress SMS to people who never actually read the email. Two ways to tighten it:

  • Branch on clicked, not opened, when the email has a real CTA. A click is a human.
  • Branch on bounced/failed OR no-click after wait for anything transactional where you want maximum reach.

Pick based on how much you trust the open signal for your audience.

Worked example: what the branch saves you

Say you've got 10,000 contacts and a two-segment SMS (a 175-character message with a link splits into two segments on GSM-7). Both-at-once versus branched:

ApproachContacts textedSegmentsSMS cost (Standard, $0.0245/seg)
SMS + email fired together10,00020,000$490.00
SMS only to non-engagers (~55%)5,50011,000$269.50

You save $220.50 on a single send — and you did it while removing the texts most likely to trigger STOP, because the people who engaged with the email were the ones most annoyed to also get a duplicate text. Run that across a lifecycle with a dozen touchpoints a month and the branch pays for itself many times over. If your monthly volume is high enough to cross 50,000 segments, Ready drops you to the Growth rate automatically — but the branch logic is what keeps you from paying for volume that does nothing. (We break down what that blended rate actually looks like in the Growth-tier math post.)

Where Ready's GHL integration fits

The branch above works with any SMS action in GHL. The reason I run it through Ready specifically:

  • Native two-way sync per location. When the stalled-branch SMS fires and the contact replies, the reply lands in Ready's unified inbox and back in the GHL conversation, mapped to the right sub-account. For agencies running many clients, that per-location isolation keeps replies from crossing wires. (If you're weighing one 10DLC registration per sub-account versus consolidating, we covered that tradeoff here.)
  • Automatic STOP handling. The opt-out from a fallback text propagates everywhere, so a contact who unsubscribes from one workflow won't get texted by another. That's what makes conditional sending safe to scale.
  • Quiet-hours enforcement. Your wait step might push an SMS into 11pm local. Ready holds sends outside permitted local hours based on the recipient's area, so the branch doesn't accidentally fire a text at a TCPA-risky time.

Don't over-engineer it — email-first isn't always right

A branch isn't free complexity you should sprinkle everywhere. Some cases genuinely warrant SMS-first or SMS-only:

  • Time-critical alerts. A failed payment or a same-day appointment change shouldn't wait 4 hours for an email to be ignored. SMS-first is correct there — the SaaS critical-alert piece makes that case.
  • SMS-native audiences. If someone opted into SMS specifically and never gave you a good email, branch on email is moot.
  • Confirmations and short replies. A "reply Y to confirm" flow is inherently a text thing, not an email thing.

The email-first branch is for marketing and lifecycle touches where email can plausibly do the job alone. That's most of them, but not all.

One more honest caveat: if your email deliverability is genuinely bad — you're landing in spam — then "email first" means "reach almost nobody first." Fix the email problem before you architect around it. A branch that waits on an email that never inboxed just delays every SMS by your wait duration for no benefit.

The practical takeaway

Stop stacking the SMS action directly under the Send Email action. Insert a wait, branch on real engagement (or a bounce), and route only the stalled and unreachable contacts to SMS. You'll spend less on your expensive channel, and — more importantly — you'll shed the redundant texts that were quietly manufacturing unsubscribes.

If you're building these flows in GHL and want the SMS side to sync two-way, honor STOPs automatically, and hold quiet hours without you babysitting it, that's what Ready's GHL integration is built for. You can start with 2,500 free credits, wire up one workflow branch, and watch the unsub rate on that flow before you change anything else.