Cost to Serve¶
This document estimates what it costs PackyTrace to host one user. It covers infrastructure cost only (cost to serve), not customer acquisition, support, or salaries. The figures are grounded in the real deployment: one AWS EC2 instance running all eight services, Postgres, Redpanda, and Keycloak under Docker Compose, with documentation on free Cloudflare Pages.
The key point: cost is fixed, not per user¶
PackyTrace runs no per-user infrastructure. All eight microservices, Postgres, the Kafka broker (Redpanda), and Keycloak share one EC2 instance. The marginal cost of one more user is effectively zero until the box saturates. The real cost is a single monthly bill divided by the number of users it serves.
This means cost per user is not a constant: it falls as we grow. The story for the business model is near-zero marginal cost and high operating leverage.
Monthly infrastructure cost¶
On-demand pricing, AWS eu-central-1 (Frankfurt), the region the deployment targets:
| Item | Spec | ~EUR / month |
|---|---|---|
| EC2 instance | t3.large (2 vCPU, 8 GB), holds Keycloak, Redpanda, Postgres, and 8 services |
~52 |
| EBS storage | ~50 GB gp3 (root plus the separate /data volume) |
~4 |
| Data transfer out | Passport pages are small JSON, first 100 GB/month is free | ~0 to 2 |
| Domain | Amortized (~12 EUR/year) | ~1 |
| Docs (Cloudflare Pages), images (GHCR), SSM, Elastic IP | Free tiers | 0 |
| Total | ~57 |
A one-year reserved instance or savings plan lowers this to ~38 EUR/month. On the AWS Free Plan or startup credits the MVP effectively runs at ~0 EUR. This is why the project budget of under 500 EUR over six months holds: ~57 EUR x 6 is ~342 EUR, inside budget even unsubsidized.
Cost per user at scale¶
The same box serves more users as we grow. A user scans a few products per week. Each scan is a couple of internal REST calls, one database read and write, one Kafka event, and one verdict computation: all cheap and internal.
| Users | Infrastructure | EUR / month | Cost per user / month |
|---|---|---|---|
| 50 (MVP target) | 1x t3.large | ~57 | ~1.14 |
| 500 | same box | ~57 | ~0.11 |
| 5,000 | t3.xlarge (16 GB) | ~115 | ~0.023 |
| 50,000 | larger box plus managed Postgres (RDS) | ~500 | ~0.010 |
In short: about 1 EUR per user at MVP scale, falling to 1 to 2 cents per user as we grow. At 50 users the per-user figure looks high only because a whole box sits mostly idle. That is a starting-cost artifact, not the unit economics.
Why it is this cheap¶
- Single-box architecture avoids per-service managed infrastructure (RDS, MSK, Fargate, load balancers, EKS) that would each carry its own monthly fee. One instance amortizes across all services and all users.
- No per-user compute or storage allocation: users share the same containers and one Postgres. A user adds only kilobytes of scan history, fridge items, and account rows.
- The only cost that scales with usage is external recipe lookups. The default provider (TheMealDB) is keyless and free, Edamam is optional and quota-limited. Verdicts and GS1 resolution are computed in-house, so there is no per-scan API fee.
- The only cost that grows steadily is database storage, but it is tiny text data. Even 50,000 users with full scan history is a few gigabytes, cents on EBS.
What to keep in mind¶
- This is cost to serve (infrastructure) only. It excludes customer acquisition, support, and salaries, which dominate real unit economics for a consumer app.
- The MVP box is a single point of failure with no high availability and no automated backups. Production-grade reliability (managed Postgres, backups, a second availability zone) roughly triples infrastructure cost but still stays at cents per user at any real scale.
- Revenue is B2B: brands pay for aggregate analytics. The relevant framing is not "charge each consumer X", it is "each consumer costs about 1 to 2 cents per month to host and generates insight value a brand pays for". That gap is the margin story.