Skip to content
Glassjaw
Lifecycle & retention 7 min read

Basket recovery that doesn't train people to wait

Discount-led basket recovery buys revenue you already had and teaches customers to abandon on purpose. How we rebuild the series around obstacles, timing and a holdout.

Abstract cover art: paths branching between waypoints on a dark blue field

Almost every programme we inherit has the same basket series. Message one an hour after abandonment, message two the next day with ten per cent off, message three two days later warning that the code expires. It reports the highest revenue per send of anything the team runs, so nobody questions it.

Then you look at who is receiving it. A meaningful share are repeat customers who abandon most weeks, collect the code, and buy the thing they were going to buy anyway. The series did not recover them. It sat in front of a purchase and took credit, at the cost of a margin point every time.

The deeper problem is that the pattern is learnable. Customers work out that leaving items in a basket produces a code within twenty-four hours, and the smart ones do it deliberately. You have built a discount request form with extra steps.

Read the basket data before you write anything

A basket is abandoned for a reason, and the reasons are not interchangeable. Before rewriting copy, pull ninety days of abandoned baskets and split them by what actually happened.

The cuts that tend to matter:

  • Stage reached. A basket that never reached checkout is a different problem from one that reached the payment step and failed.
  • Delivery threshold. Baskets sitting just under a free-delivery threshold abandon at a noticeably different rate from those above it.
  • Payment outcome. Some of what your platform records as abandonment is a declined card or a failed authentication, and no amount of persuasion fixes that.
  • Customer state. First-time visitor, known but never purchased, existing customer.
  • Device. Mobile baskets abandon more often, and a proportion of those are people who intended to finish on a laptop.

Do this by hand for a sample of a hundred before you do it in SQL. Reading real baskets teaches you things the aggregate hides, such as the repeated single-item baskets that are actually a stock check.

Then split basket abandonment from browse abandonment in your own head, because they need different tone entirely. Someone who viewed a product has shown interest. Someone who added it, entered a delivery address and stopped has hit an obstacle.

Make the first message remove the obstacle

The first message should read as help, not as a sales prompt. It needs three things and nothing else: what was in the basket, a direct route back to it, and the answer to the objection most likely to have stopped this particular person.

That last element is where the reason codes earn their keep. A basket under the delivery threshold gets the threshold stated plainly and the gap named. A basket that failed at payment gets the alternative payment methods. A high-value basket from a first-time customer gets the returns policy and the guarantee, because the obstacle is usually trust rather than price.

Keep the mechanics tight:

  • One primary link that restores the basket without a fresh login where your platform allows it.
  • No cross-sells in the first message. A distraction here costs more than the extra impression is worth.
  • Plain subject line naming the item, not a countdown or a manufactured urgency claim.
  • A send window that respects local time rather than firing at three in the morning.

If a programme only ever sent this one message, it would capture most of what the three-message version captures, at a fraction of the fatigue cost.

Set timing from behaviour, not from a habit

The standard one-hour delay comes from nowhere in particular. Find your own number by looking at how long unaided returns actually take: plot the time between abandonment and unassisted purchase, and look for the point where the curve flattens.

Sending before that point mostly means paying to interrupt people who were coming back anyway. Sending long after it means arriving when the basket is stale and the need has been met elsewhere.

Then set the suppression rules, which matter more than the timing. Exclude anyone who has purchased since abandoning, checked at send time rather than at entry. Exclude anyone with an open service ticket about that order. Exclude anyone already in a high-intent trigger campaign that day.

A basket series also has to live within the programme's overall pressure limits rather than outside them. Triggered messages are the usual exception people carve out, and it is the wrong exception. The rules in how we set frequency caps apply here too. Give basket recovery priority over broadcast, rather than immunity from the cap.

If you discount, make it earn its place

There are cases where a discount is the right tool. A first-time customer with a high-value basket and no purchase history is a genuine acquisition decision, and a margin trade may be worth making once.

The rules we apply when a code goes into the series:

  1. Never in the first message, and never on a fixed schedule a customer could learn.
  2. Never to customers who have received one from this series in the last few months.
  3. Never to segments whose repeat rate is already high, where the code is almost pure margin loss.
  4. Always with an expiry short enough that it cannot be stacked with a campaign offer.
  5. Always logged against the customer record, so the next series can see it.

The alternative levers are usually stronger and always cheaper. Stock scarcity, when it is true. Delivery upgrade rather than price cut. Extended returns window. A reminder that the basket is saved. A payment method the customer has not noticed.

If the argument inside the team is "but the discount version converts better", that argument is about conversion rate among openers, which is not the question. The question is what the programme adds over doing nothing.

Measure against a holdout, not against itself

Basket recovery is the single easiest programme to over-credit, because it fires at people already close to buying. Revenue per email tells you the audience was well chosen, not that the message worked.

Hold back a randomly selected share of eligible abandoners and send them nothing. Ten per cent is enough at most volumes, and it should be a standing holdout group rather than a one-off test, because the effect drifts with season and with offer pressure elsewhere.

Compare purchase rate and revenue per abandoner between treated and held-out groups over a window long enough to catch delayed returns — typically two to four weeks, matched to your repeat cycle. The difference is the incrementality of the programme, and it is always smaller than the platform dashboard suggests.

Run the same comparison separately for the discount arm. In several programmes we have measured, the discounted message added very little over the plain reminder among existing customers, while costing margin on every order it touched. That is the finding that changes the series, and it is the reason the holdout is worth the revenue it appears to cost.

What to change first

  • Pull a hundred real abandoned baskets and classify them by obstacle, before touching any copy.
  • Remove the code from message two for existing customers, keep it for first-time high-value baskets only, and log every issue.
  • Put a standing ten per cent holdout on the programme this week, and set a date four weeks out to read it.
Earlier on this topic · 2

Ready to transform your marketing?

Let's build something great.

By sending this form you agree to our privacy policy.