What the upsell recommender costs
A recommender that costs more than the add-ons it sells is a toy. This post is the cost breakdown: every AWS service this design touches, what each adds up to at around 150 orders a month, and why the total lands near $2.60 — with the one model call per order the standout line — plus what happens to the bill when the volume goes up tenfold.
Key takeaways
- About $2.60/month at roughly 150 orders, and the fixed cost is almost nothing — nothing runs when no orders are coming in.
- The biggest usage line here is Bedrock: one propose-and-phrase call per order, which reads the basket and a candidate list every time.
- The next line is the outbound nudge; everything else — Lambda, queue, tables, schedules — is cents at this scale.
- The only real fixed cost is Secrets Manager: two secrets at $0.40 each, billed whether or not an order comes in.
- At ten times the volume (around 1,500 orders) the bill lands near $17 — it scales with use, not with idle time.
Where the money goes
The system is serverless end to end, so there’s no instance ticking over between orders and no idle bill. You pay for an order only when one happens — and, for the two lines that reach the customer, only when an order actually earns an offer. At a typical small-shop volume — call it 150 orders a month, most of which produce an offer, with a handful filtered out as no-fit — here’s the whole bill, line by line.
| AWS service | What it does here | Monthly |
|---|---|---|
| Secrets Manager | Two secrets — webhook signing key, store API key ($0.40 each) | $0.80 |
| Bedrock (Claude Haiku 4.5) | One propose-and-phrase call per order (~150), reading basket + candidates | $0.70 |
| SNS (SMS) | One nudge per order that gets an offer (~120) | $0.50 |
| DynamoDB (on-demand) | Orders, offers, catalogue mirror, customers, opt-out — small reads and writes | $0.25 |
| CloudWatch Logs | Function logs, 7-day retention | $0.15 |
| Lambda (Python 3.14, arm64) | Order, picker, sender, add-link, sweep, catalogue-sync | $0.10 |
| SES | Internal take-up report to the shop owner | $0.05 |
| SQS + DLQ | Buffering between the webhook and the slower model and send calls | $0.05 |
| EventBridge Scheduler | The send, the take-up sweep, and the catalogue sync | $0.00 |
| AWS Budgets | Cost alarm (first two budgets are free) | $0.00 |
| Total | ~150 orders/month | $2.60 |
The shape of that bill is the point, and it’s a little different from the other systems in this family. The only line that costs money while the system sleeps is Secrets Manager — two secrets at $0.40 each, $0.80 a month no matter what. But the biggest line that moves is Bedrock, and that’s deliberate: this is the most model-heavy design of the lot, because a full recommendation runs on every eligible order, and each call reads the basket and a slice of the catalogue rather than just writing one short sentence. The nudge itself is the next line down. Everything else — the six Lambdas, the queue, the five tables, the three schedules — together costs less than the Bedrock line alone.
The line that isn’t purely AWS
The SMS line deserves a caveat. AWS prices outbound SMS per message, and the exact rate depends on the destination country and the mobile carrier — a UK mobile is a few pence, other countries differ, and some routes add carrier surcharges. The $0.50 here is a UK-leaning estimate for around 120 outbound nudges; your real number will track your country and your provider. If you send the offer by email through SES instead of SMS — a perfectly good choice for many shops — this line all but vanishes and the total drops below $2.20. Either way, it’s one of only two lines that scale with volume, which is why the AWS Budgets alarm sits on top of the whole thing.
What ten times the volume costs
Push this to a busy shop — 1,500 orders a month, ten times the volume — and the bill lands near $17, not $26. It’s sub-linear because the fixed lines don’t move: Secrets Manager stays at $0.80, the schedules stay at a cent, and AWS Budgets stays free. What scales is the genuinely usage-priced work, and here the model call leads it: roughly $7 of Bedrock for ten times the picks, about $5 of SMS, around $2 of DynamoDB, and a couple of dollars more across logs, SES, Lambda and the queue. Even then, the propose-and-phrase call and the nudge dominate, and all the machinery in between stays close to free.
The honest way to read this: the AWS bill is rounding error against what an add-on sale is worth. A single lights-and-lock bundle, a burr grinder, a matching blanket — each is worth far more than $2.60, and this design catches them by the dozen without ever pestering the customer who doesn’t want one. Even at $17 a month for a busy shop, the system pays for itself the first few times it turns a bare order into a one-tap add — and the customers it has nothing good to say to simply hear nothing at all.
Design rules that shaped the cost
- Pay per order, not per hour. No always-on compute means no idle bill.
- The model is the big line — spend it once. One propose-and-phrase call per order, and only to rank and word — never to decide.
- Only offer when it fits. No-fit orders and capped customers skip the model and the nudge entirely, so the two big lines stay lean.
- Cheap work stays cheap. Catching, filtering, sending and sweeping are plain Lambda and DynamoDB, cents at this scale.
- Watch the two lines that scale. Bedrock and SMS are the parts that grow, so the Budgets alarm sits right on top of them.