Before you start: you’ll need a
subscriptions or customers table with a renewal_date or current_period_end column, and an email service configured. See Send Emails.The Flow at a Glance
7 days out
Gentle heads-up
3 days out
Upgrade/downgrade options
1 day out
Last chance to change
Day of
Receipt or payment retry
Step 1: Create the Workflow
Open Workflows
In your project, go to Workflows > New Workflow. Name it
Subscription Renewal Reminders.Step 2: Query Upcoming Renewals
Each tier uses a separate query so you can send different messaging. Here’s the 7-day query as a template:Step 3: Send Tiered Reminder Emails
Different days, different tone:- 7 days out: “Your plan renews next week” — casual, reassuring. Include the plan name and renewal amount. One soft CTA: “Manage your subscription.”
- 3 days out: “Renewing in 3 days” — introduce upgrade/downgrade options. Highlight what they get on a higher tier.
- 1 day out: “Your subscription renews tomorrow” — last chance to change anything. Include a link to update payment method prominently.
- Day of: Either a “Thanks for renewing” receipt, or a “Renewal failed — update payment” notice depending on charge result.
Add a Send Email action per tier
After each query, add a Send Email action scoped to that query’s results.
Personalize per plan
Monthly customers get different messaging than annual. High-tier customers deserve a more personal touch. Use conditionals in your email template or split into multiple workflows.
Step 4: Handle Failed Renewals
Failed payments are recoverable — most are card expirations, not intentional cancellations. Build a second workflow for this:Add a Stripe webhook trigger
Listen for
invoice.payment_failed. See Webhook Patterns.Send a recovery email
Subject: “Your payment didn’t go through.” Body: plain and calm. Explain what happened, link to update payment method, mention what happens if they don’t.
Loyalty Incentives
Tenure is a retention lever. Pull it in your renewal emails:- “You’ve been with us 1 year — here’s 10% off next month”
- “Celebrating 6 months — unlocked: priority support”
- “Year 2 with Acme — we upgraded you to the new Pro features at no extra cost”
created_at in your subscription record and branch the email template based on thresholds.
Personalize by Plan
One-size-fits-all reminders get unsubscribes. Branch your messaging:- Monthly vs annual: annual customers need less hand-holding but bigger-deal framing (“your annual plan renews in 30 days”)
- Free trial converting to paid: emphasize what they’ll lose if they cancel vs what they’ve already set up
- High-tier: consider a personal email from a human, not a templated one
- At-risk (low usage): combine renewal reminder with a “need help getting started?” offer
Verify It Worked
Confirm the email arrives
Check the test email inbox. Verify the subject, tone, and CTAs render correctly. Confirm the
renewal_reminder_7d_sent flag was set.Troubleshooting
No reminder went out
No reminder went out
Check the workflow is Enabled (toggle in top right). Then check the
renewal_reminder_*_sent flag on the target row — if it’s already set, the query filters the row out. To re-test, clear the flag and re-run.Wrong tier fired (7-day instead of 3-day)
Wrong tier fired (7-day instead of 3-day)
Date math is tricky. Make sure your
BETWEEN ranges don’t overlap — the 7-day window should end exactly where the 3-day window begins. Also check your database timezone matches the workflow’s schedule timezone.Customer says 'my card was charged without warning'
Customer says 'my card was charged without warning'
The 7-day email is the most commonly overlooked — spam folder, busy week, address change. Always send a day-of confirmation email too, even for successful renewals. That way they have at least one touchpoint they can search their inbox for.
Renewals failing after email sends fine
Renewals failing after email sends fine
If the email workflow runs but Stripe payments aren’t going through, the issue is at the payment layer, not the email layer. Decouple email sending from payment retry — each should succeed or fail independently. Check your Stripe API logs and webhook configuration.
Duplicate emails on the same day
Duplicate emails on the same day
Usually a sent-flag race condition. Make sure the flag update happens before the next workflow tick — or use a uniqueness constraint like
UNIQUE(subscription_id, reminder_tier, date) on a reminders log table.What’s Next?
Add Stripe
Wire up subscriptions and payment processing
Webhook Patterns
Handle Stripe and other third-party webhooks reliably