Part 6 of 7 · Appointment reminder series ~3 min read

What the appointment reminder costs

The reminder is one of the cheapest systems in this whole series — with one twist. The hourly tick reads a CSV from S3, does some time arithmetic, writes a few rows to DynamoDB, and sends a handful of messages. It calls no models on the tick. The one line that actually moves the bill is the text messages themselves: each SMS carries a small per-message fee. At typical SMB volume the total is a few dollars a month, and most of that few dollars is texts.

Key takeaways

  • Around $3/month at typical SMB volume (about 200 appointments a month).
  • Fixed AWS cost is essentially zero. No always-on compute, no NAT Gateway, no API Gateway.
  • The dominant cost is text messages — a small per-message fee, a few per appointment.
  • Bedrock fires only on inbound email parsing (a few times a month) and the weekly summary.
  • At 500 appointments the bill is around $7. At 1,000 it’s around $12 — mostly texts.

Cost at three volumes

Monthly cost at three appointment volumes, broken out by component A horizontal stacked-bar chart showing monthly cost in US dollars at three appointment volumes. The leftmost bar represents 200 appointments a month and shows a total around $3, dominated by the SMS slice (the text messages sent through SNS) with a small everything-else slice, a tiny sliver for Bedrock and a tiny sliver for Textract. The middle bar represents 500 appointments and shows a total around $7, with the same shape — the SMS slice grows roughly linearly because more appointments mean more reminder texts. The rightmost bar represents 1,000 appointments and shows a total around $12, with SMS still dominant; Bedrock and Textract stay small in absolute terms because they only fire on the inbound parsing lane (a handful of forwarded booking emails per month) and the weekly summary. Below the chart is a legend explaining the four sections of each bar: SMS via SNS (the text reminders), Bedrock (only on inbound parsing and the weekly summary), Textract (only on attachments in forwarded booking emails), and an everything-else bucket for Lambda runtime, DynamoDB on-demand, S3, EventBridge Scheduler, SES, and CloudWatch. A note at the bottom: the text messages are the dominant cost — everything else is fractions of a cent per appointment. $0 $5 $10 $15 $20 200 appts ~$3 500 appts ~$7 1,000 appts ~$12 SMS via SNS (the text reminders — the main cost) Bedrock (inbound parsing + weekly summary) Textract (attachments in forwarded emails) Everything else (Lambda, DDB, S3, Scheduler, SES, CloudWatch) The text messages are the dominant cost — everything else is fractions of a cent per appointment.
Fig 6. Monthly cost at three appointment volumes. SMS is the dominant slice because every reminder is a paid text. Bedrock and Textract are small because they only fire on the inbound parsing lane and the weekly summary. The everything-else bucket — Lambda, DynamoDB, S3, Scheduler — stays tiny.

Where the dollars actually go

SMS via SNS (the bulk). This is the line that matters. Every reminder sent as a text carries a small per-message fee, and the fee varies by country. A typical appointment gets one or two reminders, plus the odd reschedule confirmation. At 200 appointments a month that’s a few hundred messages — a couple of dollars. At 1,000 appointments it’s a few thousand messages and the SMS line is most of the bill. Customers who only have email on file cost nothing extra to remind, because email is effectively free; that’s one reason the email fallback is worth keeping.

Lambda runtime. The reminder runs once an hour. Each tick reads the list CSV from S3, iterates the rows, computes hours_to_appt for each, and decides on a move. At 200 appointments that’s a few hundred milliseconds; at 1,000 it’s under a second. Add the dispatch Lambda firing per send, the Function URL Lambda for replies, the calendar-sync Lambda hourly, and the drive-sync Lambda every few minutes — the Lambda total still lands under a dollar at all three volumes.

DynamoDB on-demand. Three small tables: ar-sends, ar-replies, ar-audit. Reads are dominant during the hourly tick (one read per appointment per tick). Writes are sends, replies, and audit rows. Pennies a month at any of these volumes.

S3 + Storage. The mirrored list CSV plus the archived MIME from any forwarded booking emails. A few hundred KB total at SMB volume. Effectively free.

EventBridge Scheduler. The hourly tick rule plus deferred-send rules from quiet-hours and holiday gates. A handful of invocations a day. Pennies.

SES. Inbound for the forwarding lane: $0.10 per thousand received messages (a few cents a year for an SMB). Outbound for email-fallback reminders: $0.10 per thousand sent. Both are negligible at this scale — which is exactly why email-only customers are so cheap to remind.

Bedrock (only when something fires it). The hourly tick uses no Bedrock. The inbound parsing lane fires Haiku 4.5 once per forwarded booking email: a few thousand input tokens (the parsed text) and a few hundred output tokens (the proposed row JSON), so a fraction of a cent per parse. The weekly staff summary is one larger call: write a short paragraph on the week’s confirms, no-shows prevented, and slots freed; a fraction of a cent. Bedrock costs cents a month.

Textract (only on forwarded attachments). Many booking emails are plain text and skip Textract entirely. When a confirmation comes as a PDF or image, Textract runs per-page; a booking confirmation is usually one page. A few cents a month at most.

What doesn’t cost money

  • API Gateway. Replaced by Lambda Function URLs for the reply links.
  • NAT Gateway. Nothing is in a VPC. No NAT, no $32/month minimum.
  • Always-on compute. No EC2, no Fargate. The reminder sleeps almost the whole hour.
  • A Knowledge Base. The list is structured rows, not free text — deterministic lookup beats vector search here. No embeddings, no Knowledge Base, no S3 Vectors needed.
  • Models on the tick. The hourly decision is plain Python. Bedrock fires only on the inbound parsing lane and the weekly summary.

How the cost scales

SMS grows roughly linearly with appointment count, because each appointment gets a fixed number of reminder texts. Lambda and DynamoDB grow linearly too, but from a much smaller base. Bedrock and Textract are uncorrelated with appointment count — they only fire when somebody forwards a booking email or it’s the weekly summary. So the bill at 3,000 appointments is around $35, at 5,000 around $55 — almost all of it text messages. If the SMS line ever gets uncomfortable, you can lean harder on the free email channel for customers who’ll read it, or drop a tight third reminder for low-value services.

Set an AWS Budgets alarm at $30/month so anything unusual — a runaway loop sending duplicate texts — pages you before the bill matters. The reminder’s normal-volume bill stays well under that ceiling, and the one no-show it prevents each week more than pays for it.

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

All posts