Cart recovery
A serverless system that wins back online shoppers who added items but didn’t check out. When a cart is left behind, it waits a sensible amount of time, then sends a friendly, well-timed reminder (and maybe a second) with what they left — and stops the instant they buy or unsubscribe. Never pushy: it respects quiet hours and sends one gentle nudge, not a barrage. Seven posts on the same system — one diagram at a time — with an engineering reference at the end.
-
01
A cart recovery system on AWS for a few dollars a month
The whole system on one page — a cart intake, a waiter, and a sending piece, plus the four moves they share for every abandoned cart.
-
02
How an abandoned cart gets spotted
Three sources feed the cart list — a webhook from your storefront that catches every add and checkout, a nightly Drive export a human can read, and a tag lane for carts started from a saved link.
-
03
How a cart reminder gets timed
A per-cart wake-up reads the cart, computes time-since-abandon, compares against per-size waits in the rules doc, and picks one of four moves: still shopping, first reminder, second reminder, give up. No model on the decision.
-
04
How a cart reminder reaches the shopper
Address resolution per cart, quiet hours, a do-not-disturb check, a polished friendly-to-warm reminder with the items and a return link, and the four guardrails between the chosen move and the actual email landing.
-
05
How a cart recovery stops on checkout
The chase stops the moment they buy. Plus three owner actions: suppress (stop reminders on one cart), unsubscribe (stop them for an email), and write off (close it out). Every action is logged.
-
06
What the cart recovery costs
A couple of dollars a month at SMB volume. The system wakes once per cart, calls no model on the decision, and only fires Bedrock to polish a line and on the monthly summary.
-
07
Engineering reference: the cart recovery architecture
Same system, drawn purely for engineers. Service names, resource identifiers, region, Bedrock model IDs, Lambda inventory, IAM scopes, the SQS and DLQ wiring, EventBridge Scheduler config, and the DynamoDB schemas.
Frequently asked questions
- What is a cart recovery system?
- A small serverless system that wins back online shoppers who added items to their cart but didn’t check out. When a cart is left behind, it waits a sensible amount of time, then sends one friendly, well-timed reminder (and maybe a second) showing what they left. It stops the instant they buy or unsubscribe. It’s never pushy — it respects quiet hours and sends one gentle nudge, not a barrage.
- How much does it cost to run?
- About $2.20/month at typical small-business volume (around 300 abandoned carts a month). The fixed cost is essentially zero. The variable cost is dominated by the small Lambda that wakes per cart to decide whether to send; Bedrock fires only to polish a reminder line and once a month for the summary, so it’s a small sliver. At 3,000 abandoned carts a month the bill lands around $14.
- Which AWS services does it use?
- Lambda (Python 3.14, arm64) with Function URLs for the cart-event webhook and the unsubscribe link, EventBridge Scheduler for the per-cart deferred wake-ups, DynamoDB on-demand, S3 (with versioning), SES outbound, SQS with a DLQ, Secrets Manager, CloudWatch Logs (7-day retention), AWS Budgets, and Bedrock (Claude Haiku 4.5 via Global cross-Region inference) for the reminder polish and monthly summary. No API Gateway, no NAT Gateway, no always-on compute, no Knowledge Base.
- Where do the carts come from?
- From your store. Your storefront posts a cart event to a small webhook the moment a shopper adds, updates, or checks out. The webhook writes one row per cart to DynamoDB with the shopper’s email, the items, the cart total, and a timestamp. A nightly export of the same data lands in a Google Sheet in a Drive folder you control, so a human can read the day’s carts without touching AWS.
- Does the system use AI?
- Sparingly. The decision to send a reminder uses no AI — it’s plain Python that reads a timestamp and a couple of flags. Bedrock Haiku 4.5 fires only to polish one reminder line into your store’s voice (with a deterministic fallback if it’s unavailable) and once a month for the recovery summary. Most of the system is deterministic by design.
- How does a reminder stay friendly and not annoying?
- Each cart size has its own wait in the rules doc — a small cart waits 4 hours then 24, a big cart waits 1 hour then 20. There are at most two reminders, ever. Sends respect quiet hours (default 9pm–8am local) and skip the send if the shopper already got a reminder in the last few days. One gentle nudge, not a barrage. Every reminder carries a one-click unsubscribe.
- What happens when the shopper checks out?
- The recovery stops on the next wake-up. The webhook watches for a checkout event on that cart; the moment it lands, the live chain is cleared so no reminder goes out. The shopper can also unsubscribe (stop all reminders for that email), or the owner can suppress a cart by hand or write it off. Every action is recorded in the
cr-auditDynamoDB table with timestamp, cart, action, and a before-and-after snapshot, so the trail is auditable.