Part 6 of 7 · Loyalty tracker series ~3 min read

What the loyalty tracker costs

The loyalty tracker is one of the cheapest systems in this whole series. Each sale runs a tiny function that reads a few numbers, does some arithmetic, updates a balance, and writes a ledger row. Redeems are just as small. The only emails are the reward-earned note, a short nightly balance email, and the odd win-back nudge. It calls no models on the busy paths. Bedrock fires only once a month for the owner summary. At typical small-shop volume, the bill is a couple of dollars a month, fixed cost essentially zero.

Key takeaways

  • Around $2.40/month at typical small-shop volume (about 200 members, ~1,500 sales a month).
  • Fixed AWS cost is essentially zero. No always-on compute, no NAT Gateway, no API Gateway.
  • The earn and redeem paths cost pennies — no model calls.
  • Bedrock fires only on the monthly owner summary, so it’s a small sliver.
  • At 500 members the bill is around $5. At 1,000 members and 8,000 sales it’s around $11.

Cost at three volumes

Monthly cost at three shop volumes, broken out by component A horizontal stacked-bar chart showing monthly cost in US dollars at three shop volumes. The leftmost bar represents about 200 members and 1,500 sales a month and shows a total around $2.40, dominated by the everything-else slice (Lambda, DynamoDB, S3, EventBridge Scheduler, CloudWatch) with a tiny sliver for SES email and a tiny sliver for Bedrock. The middle bar represents about 500 members and 4,000 sales and shows a total around $5, with the same shape — the everything-else slice grows roughly with sales count because the earn function runs per sale. The rightmost bar represents about 1,000 members and 8,000 sales and shows a total around $11, with everything-else still dominant; Bedrock stays small in absolute terms because it only fires once a month for the owner summary, and SES grows gently with the number of emails sent. Below the chart is a legend explaining the four sections of each bar: Bedrock (only the monthly owner summary), SES email (balance, reward, and nudge emails), AWS Budgets and Secrets Manager (small fixed amounts), and an everything-else bucket for Lambda runtime, DynamoDB on-demand, S3, EventBridge Scheduler, and CloudWatch. A note at the bottom: the per-sale earn function is the dominant cost, and even that is fractions of a cent per sale. $0 $5 $10 $15 $20 200 members ~$2.40 500 members ~$5 1,000 members ~$11 Bedrock (monthly owner summary only) SES email (balance, reward, nudge) AWS Budgets + Secrets Manager (fixed) Everything else (Lambda, DDB, S3, Scheduler, CloudWatch) The per-sale earn function is the dominant cost — and even that is fractions of a cent per sale.
Fig 6. Monthly cost at three shop volumes. Bedrock is a small sliver because it only fires once a month for the owner summary. The dominant cost is the everything-else bucket: the earn function running on every sale.

Where the dollars actually go

Lambda runtime (the bulk). The earn function runs once per sale. Each run reads the rules from S3 (cached on a warm function), finds the member, does a little arithmetic, updates the balance, and writes a ledger row — a few dozen milliseconds. At 1,500 sales a month that’s pennies; at 8,000 it’s still well under a dollar. Add the redeem function for each reward claimed, the sign-up function, the nightly balance-email job, the weekly lapsing sweep, and the drive-sync Lambda every fifteen minutes — the Lambda total lands under a dollar at all three volumes.

DynamoDB on-demand. Three small tables: the member store, loy-ledger, and loy-audit. Each sale is one read and a couple of writes; each redeem the same. Pennies a month at any of these volumes.

S3 + storage. The mirrored rules and voice docs, plus a daily backup of the member store. A few hundred KB total at small-shop volume. Effectively free.

EventBridge Scheduler. The nightly balance-email rule, the weekly lapsing sweep, the monthly summary, and the fifteen-minute drive-sync. A handful of invocations a day. Pennies.

SES email. Outbound for the reward-earned notes, the nightly balance emails, and the win-back nudges: $0.10 per thousand sent. At a few thousand emails a month that’s a few cents to a couple of dollars. The nightly email only goes to members whose balance changed that day, which keeps the count down.

Bedrock (only the monthly summary). The earn and redeem paths use no Bedrock. Once a month, the summary function calls Haiku 4.5 to write the owner a short plain-English read on the program: a few thousand input tokens (the month’s counts) and a few hundred output tokens (the paragraph). A couple of cents a month, every month, regardless of volume.

What doesn’t cost money

  • API Gateway. Replaced by Lambda Function URLs for the POS webhook, the sign-up form, and the redeem desk.
  • NAT Gateway. Nothing is in a VPC. No NAT, no $32/month minimum.
  • Always-on compute. No EC2, no Fargate. The functions only run when a sale, a redeem, or a scheduled job fires.
  • A Knowledge Base. Balances are structured numbers, not free text — an exact lookup beats vector search here. No embeddings, no Knowledge Base, no S3 Vectors needed.
  • Models on the busy paths. The earn math and the redeem check are plain Python. Bedrock fires only on the monthly summary.

How the cost scales

Lambda runtime and DynamoDB grow roughly with the number of sales, because the earn function runs once per sale. SES grows gently with the number of emails sent. Bedrock is flat — one call a month no matter how big the shop is. So the bill at 3,000 members and 25,000 sales a month is around $28; at 6,000 members and 50,000 sales it’s around $55. Past those volumes you’re a chain, not a small shop, and you’d batch the nightly emails and add a read cache — but those are tweaks, not redesigns.

Set an AWS Budgets alarm at $15/month so anything unusual pages you before the bill matters. The normal small-shop bill stays well under that ceiling.

Last post in the series: the engineering reference. Same system, drawn for engineers — service names, Lambda inventory, IAM scopes, DynamoDB schemas, SES config, and EventBridge Scheduler config.

All posts