Part 6 of 7 · Supplier bill matcher series ~3 min read

What the bill matcher costs

The matcher is one of the cheaper systems in this series, and the part that does the actual work — the three-way match — is essentially free, because it’s plain Python doing arithmetic. The cost is almost entirely in reading the bill: Textract reads each PDF, and one small Bedrock call per bill turns that read into clean lines. At typical SMB volume the bill is a few dollars a month, fixed cost essentially zero.

Key takeaways

  • Around $3.20/month at typical SMB volume (around 200 bills a month).
  • Fixed AWS cost is essentially zero. No always-on compute, no NAT Gateway, no API Gateway.
  • The three-way match costs almost nothing — it’s plain Python.
  • The cost is Textract reading each bill and one Bedrock call per bill to clean the lines.
  • At 500 bills the bill is around $7. At 1,000 bills it’s around $14.

Cost at three volumes

Monthly cost at three bill volumes, broken out by component A vertical stacked-bar chart showing monthly cost in US dollars at three bill volumes. The leftmost bar represents 200 bills a month and shows a total around $3.20, dominated by the Textract slice (reading each bill PDF) with a moderate Bedrock slice (one cleanup call per bill), a small fixed slice, and a small everything-else slice. The middle bar represents 500 bills and shows a total around $7, with the same shape — Textract and Bedrock grow roughly linearly with bill count because each bill is read and cleaned once. The rightmost bar represents 1,000 bills and shows a total around $14, with Textract still the largest slice; the match itself adds almost nothing because it is plain Python. Below the chart is a legend explaining the four sections of each bar: Textract (reading every bill PDF), Bedrock (one cleanup call per bill), AWS Budgets and Secrets Manager (small fixed amounts), and an everything-else bucket for Lambda runtime, DynamoDB on-demand, S3, EventBridge Scheduler, SES, SQS, and CloudWatch. A note at the bottom: reading the bill is the dominant cost — the three-way match is essentially free. $0 $5 $10 $15 $20 200 bills ~$3.20 500 bills ~$7 1,000 bills ~$14 Textract (reading every bill PDF) Bedrock (one cleanup call per bill) AWS Budgets + Secrets Manager (fixed) Everything else (Lambda, DDB, S3, Scheduler, SES, SQS, CloudWatch) Reading the bill is the dominant cost — the three-way match itself is essentially free.
Fig 6. Monthly cost at three bill volumes. Textract and Bedrock dominate because each bill is read and cleaned once. The match itself adds almost nothing: it’s plain Python comparing numbers against tolerances.

Where the dollars actually go

Textract (the bulk). Every bill is read once. Textract is priced per page, and a typical supplier bill is one to three pages. At 200 bills a month, that’s a few hundred pages, which lands around a couple of dollars. Textract is the single biggest line because reading is the unavoidable first step — you can’t check a bill you can’t read. It grows roughly linearly with bill count.

Bedrock (one call per bill). After Textract reads the page, one Bedrock Haiku 4.5 call turns the raw text into clean lines: a few thousand input tokens (the Textract output) and a few hundred output tokens (the structured JSON), so a fraction of a cent per bill. Across 200 bills it’s well under a dollar. The monthly summary adds one larger call — a board narrative of what matched, what was caught, and the top suppliers by mismatch — for a couple of cents.

Lambda runtime. The reader, the matcher, the approval desk, the ack-handler, the portal poll, the daily sweep, and the drive-sync all run as small short functions. The matcher itself is the cheapest of all — it reads a few rows, does arithmetic, writes an outcome. The Lambda total lands well under a dollar at all three volumes.

DynamoDB on-demand. A handful of small tables: bm-bills, bm-results, bm-queue, bm-audit. One write per bill read, one per match, one per approval action, plus the audit rows. Pennies a month at any of these volumes.

S3 + storage. The mirrored PO and goods-received CSVs, the raw inbound email, and the bill PDFs. A few hundred MB at SMB volume. Effectively free.

SES and SQS. Inbound for the emailed-bill lane and outbound for approver emails and supplier queries: $0.10 per thousand messages each way, so cents a month. SQS buffers the read-and-match work with a dead-letter queue for anything that fails twice; negligible at this scale.

What doesn’t cost money

  • API Gateway. Replaced by Lambda Function URLs for the approve/query/reject endpoints.
  • NAT Gateway. Nothing is in a VPC. No NAT, no $32/month minimum.
  • Always-on compute. No EC2, no Fargate. Everything is event- or schedule-driven.
  • A Knowledge Base. POs and goods-received notes are structured rows — deterministic lookup beats vector search here. No embeddings, no Knowledge Base, no S3 Vectors needed.
  • Models on the match. The three-way match is plain Python. Bedrock fires only to clean up the read and write the monthly summary.

How the cost scales

Textract and Bedrock grow linearly with bill count, because each bill is read and cleaned once. Lambda and DynamoDB grow linearly too, but from a much smaller base. So the bill at 2,500 bills a month is around $35; at 5,000 it’s around $70. Past those volumes you’d look at Textract’s bulk pricing and at caching repeat-layout reads from the same supplier — but those are optimizations for high-volume accounts payable, not redesigns. The match itself never becomes the cost.

Set an AWS Budgets alarm at $25/month so anything unusual pages you before the bill matters. The matcher’s normal-volume bill stays well under that ceiling — and a single caught overcharge usually pays for a year of running 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