Skip to main content
Users drift. This recipe catches them at 30, 60, and 90 days of inactivity with progressively more engaged messaging — one last chance to remind them why they signed up before you quietly remove them from your active list.
Before you start: your users table needs a last_login_at (or similar activity timestamp), and you need a configured email service.

The Flow at a Glance

Day 30

“What’s new since you left”

Day 60

“Do you need help?”

Day 90

Final offer or clean goodbye

Step 1: Create the Workflow

1

Open Workflows

Go to Workflows > New Workflow. Name it Re-engagement Campaign.
2

Add a Schedule trigger

Set to run daily at 10 AM UTC (or whatever time zone makes sense for your audience).
Daily is enough for re-engagement — hourly would be overkill. Pick a time when your audience typically opens email, not 3 AM.

Step 2: The 30-Day Cohort

1

Add a Database query action

Find users whose last activity was exactly 30 days ago (within a 1-hour window to match the schedule):
2

Loop and send

Add a For Each step over the results. Inside, add a Send Email action:
  • Subject: {{item.name}}, here's what you missed
  • Body: Focus on what’s new since they were last active. New features, popular content, customer wins. Make it about value, not guilt.
3

Mark as sent

Add a Database Update:

Step 3: The 60-Day Cohort

Clone the 30-day block. Change the query to target 60 days:
Shift the messaging to “do you need help?” — offer an onboarding call, a support chat link, or a link to the docs. The assumption is they hit a wall, not that they didn’t see the value.

Step 4: The 90-Day Cohort

At 90 days, it’s either a clean goodbye or a final offer. Pick one:
  • Final offer: discount, extended free trial, white-glove onboarding
  • Clean goodbye: “We’d love to have you back anytime — here’s a link to log in”
Either way, after 90 days with no response, flip marketing_opt_in = false to stop active marketing. Keep the record in your CRM for future relationships.

Messaging Tone by Cohort

Track email opens and clicks to separate “alive but quiet” from “truly gone.” If someone opens the 30-day email but doesn’t log in, they’re paying attention — nurture them longer. If they never open any of the three, they’re done.

Respecting Unsubscribes

Always include an unsubscribe link and honor your suppression list. Re-engagement campaigns hit users who are already half-checked-out; one wrong email and they unsubscribe or mark as spam. Add a Check Suppressions step before each Send Email, or use your provider’s built-in suppression handling. See Email Suppressions.
Sending re-engagement emails to users who already unsubscribed is the fastest way to blow up your sender reputation. Always check suppressions first.

A/B Testing Subject Lines

Low-engagement cohorts are a great place to test subject lines — you’re already reaching users unlikely to convert, so nothing to lose. Try:
  • Curiosity-based: “A question about your account”
  • Direct: “We miss you, {{item.name}}
  • Benefit-led: “Three new features since you’ve been gone”
  • Human: “From Abe at Acme — hope you’re well”
Look at open rates after a week and keep the winner.

Verify It Worked

  1. Pick a test user
  2. Manually set last_login_at to 30 days ago: UPDATE users SET last_login_at = now() - interval '30 days' WHERE email = 'test@example.com'
  3. Wait for the next scheduled run (or trigger manually from Workflows > Runs)
  4. Confirm the 30-day email arrives
  5. Confirm reengagement_30d_sent_at is now populated
  6. Re-run the workflow — the test user should not receive a duplicate

Troubleshooting

The reengagement_Xd_sent_at check isn’t in the query, or the UPDATE isn’t running. Look at Workflows > Runs and inspect the query output — if the same user appears in the results across two consecutive runs, the UPDATE silently failed. Check permissions on the users table.
Interval math is easy to get wrong. The BETWEEN now() - interval '30 days 1 hour' AND now() - interval '30 days' pattern catches a 1-hour window ending 30 days ago. If your schedule runs hourly, widen to '30 days 1 hour'; if daily, widen to '31 days' AND '30 days'. Always match the window to the schedule cadence.
Re-engagement is hard — a 5-10% open rate is typical, 1-2% click-through is normal. If you’re at 0%, the issue is subject lines (too generic), sender reputation (check deliverability), or the offer (too weak). A/B test subject lines first.
If you have 100k+ inactive users, looping inline will timeout. Batch it: send to 500 users per run, schedule more frequently, or push the batch to a queue with worker processing. See Workflows for long-running job patterns.
Low-engagement sends hurt sender reputation. Warm up carefully: start with the most-engaged dormant users (those who opened recently), skip anyone with prior bounces, and cap daily volume. Consider a dedicated IP if re-engagement is a large portion of your volume.

What’s Next?

Email Suppressions

Handle unsubscribes and bounces properly

Email Webhooks

Track opens and clicks for smarter segmentation