Skip to main content
E-commerce sites typically recover 10-30% of abandoned carts with a well-timed reminder. This recipe sends a gentle nudge an hour after someone walks away — and optionally a discount follow-up the next day.
Before you start: your site needs a carts (or orders) table with a status column and a user email, plus a configured email service.

The Flow at a Glance

1 hour

Gentle reminder

24 hours

Add a small discount

3 days

Final last-chance

Step 1: Create the Workflow

1

Open Workflows

Go to Workflows > New Workflow. Name it Abandoned Cart Recovery.
2

Add a Schedule trigger

Click Add Trigger > Schedule. Set it to run every hour (rate(1 hour)).
Hourly works well for most stores. Busy stores with thousands of carts per day can drop to every 30 minutes; quieter stores can schedule less often.

Step 2: Find Abandoned Carts

1

Add a Database query action

Click + Add Action > Database Query. Paste this SQL:
SELECT c.id, c.user_email, c.items, c.total, c.updated_at
FROM carts c
WHERE c.status = 'abandoned'
  AND c.updated_at < now() - interval '1 hour'
  AND c.updated_at > now() - interval '24 hours'
  AND c.reminder_sent_at IS NULL
This returns carts that were abandoned between 1 and 24 hours ago and haven’t received an email yet.
2

Loop over results

Add a For Each step over the query result. Each iteration represents one cart to recover.

Step 3: Send the First Email

1

Add a Send Email action inside the loop

  • To: {{item.user_email}}
  • Subject: You left something behind!
  • Body: Show the cart contents, total, and a big button back to checkout. Keep it short and warm.
2

Personalize the body

Pull fields from the cart row:
Hey {{item.customer_name || 'there'}},

Your cart is still waiting — {{item.items[0].name}} and more. 
Total: ${{item.total}}.

Pick up where you left off: https://yoursite.com/checkout?cart={{item.id}}
3

Mark the reminder as sent

Add a Database Update action:
UPDATE carts SET reminder_sent_at = now() WHERE id = '{{item.id}}'
This prevents the same cart from receiving the email every hour.

Step 4: Day 2 Follow-up with Discount

Clone the first action set, but change the query to target carts that were reminded 24 hours ago and still haven’t converted:
SELECT c.id, c.user_email, c.items, c.total
FROM carts c
WHERE c.status = 'abandoned'
  AND c.reminder_sent_at < now() - interval '24 hours'
  AND c.discount_sent_at IS NULL
Send a follow-up with a small incentive (e.g., 10% off code COMEBACK10) and update discount_sent_at.

Step 5: Day 3 Last-Chance

A final message 3 days after abandon, with last-chance language. Skip anyone who already converted by filtering status != 'completed'.

Stop Sending When They Purchase

Every email action should check the current cart status first. Add a Condition step before each Send Email:
{{item.status}} == 'abandoned'
If the customer completed checkout between the schedule runs, the condition fails and the email is skipped.
Don’t be pushy. Three emails is the cap. More than that hurts your sender reputation, drives unsubscribes, and flags you as spam — which lowers deliverability for every other email you send.

Personalization Ideas

  • Include product images pulled from {{item.items[0].image_url}}
  • Reference the customer’s location or last purchase if you have the data
  • Tailor subject line to cart value — “Your $200 cart is waiting” converts better than generic copy
  • Use the customer’s first name, not “Dear Customer”

Tracking Effectiveness

Email opens and clicks tell you what’s working.
  • Open rate on Email 1 — subject line quality
  • Click-through on Email 2 — did the discount move them?
  • Conversion rate from email → checkout — the only metric that really matters
Wire up Email Webhooks to log open/click events per cart so you can A/B test subject lines and offers.

Verify It Worked

  1. Add a test item to a cart while signed in as a test user
  2. Leave the session idle for just over an hour
  3. Wait for the next workflow run (or trigger manually from the Workflows > Runs tab)
  4. Confirm the email arrives at the test address
  5. Click the checkout link — it should return you to the exact cart

Troubleshooting

Check your cart status filter. Many sites store abandoned carts as active or pending rather than abandoned — run the SELECT manually in the database explorer and confirm it returns rows. Also check the time range: if nothing is between 1 and 24 hours old, the query is correct but there’s nothing to send.
The reminder_sent_at update isn’t being written. Open Workflows > Runs, click a recent run, and check the UPDATE action output. Common cause: a syntax error in the UPDATE that silently fails. Wrap it in a try/catch step and log errors.
Your messaging is too pushy, or frequency is too high. Reduce to two emails max, soften the language (“Your cart is still here” instead of “Don’t miss out!”), and always include an unsubscribe link. Check your sender reputation in your ESP dashboard.
Add a final status check right before the Send Email action. The schedule fires every hour — between the query and the send, a customer might have completed checkout. The Condition step on status == 'abandoned' guards against this.
The query didn’t return the field, or the loop item path is wrong. In Runs, inspect the query output — if customer_name is null, add a fallback like {{item.customer_name || 'there'}}. Confirm you’re referencing {{item.x}} inside the loop, not {{trigger.x}}.

What’s Next?

Workflows Basics

How triggers, actions, and runs fit together

Email Webhooks

Track opens, clicks, and unsubscribes