Thnkrr — Why These AWS Services, and What We'd Switch To

Companion to 18-aws-services-and-costs.md. One section per service: why it's the right pick for this pilot, and the pre-planned exit if we ever want to change it.

The standing rule (docs/04 §11): AWS is certain for the pilot, but nothing may depend on AWS to exist. Every AWS touchpoint sits behind a small adapter interface in our code (storage, mailer, imageScreen), and the non-AWS side of each adapter runs every day in development. Switching vendors is a config change plus a data copy — never a rewrite. That rule is why the alternatives below are real options, not wishful thinking.


S3 — file storage

Why it's the best fit here:

Alternatives (in order we'd consider them):

AlternativeTrade-off
Cloudflare R2Same S3 protocol (config-change switch). Free egress — becomes attractive only if delivery traffic ever outgrows CloudFront's free tier.
Backblaze B2Same S3 protocol, cheapest storage per GB. Slightly less ecosystem polish.
Google Cloud StorageS3-compatible mode exists; only sensible if we moved everything to GCP.

Proof the exit works: development runs on MinIO (an S3-compatible server in Docker) every day. The database stores file keys, never URLs, and images are served from our own domain — so the bucket vendor can change without touching data or links.


CloudFront — image delivery (CDN)

Why it's the best fit here:

Alternatives:

AlternativeTrade-off
Cloudflare CDNAlso effectively free; the natural pair if storage moved to R2.
Fastly / bunny.netFine products; another vendor for no benefit at this scale.

Exit cost: near zero. A CDN is a DNS-level layer; media URLs are on our own domain, so swapping CDNs is a DNS change and a cache warm-up, invisible to users and to the database.


SES — transactional email

Why it's the best fit here:

Alternatives:

AlternativeTrade-off
PostmarkBest-in-class transactional deliverability; ~$15/month minimum. The first switch we'd make if consent emails ever showed spam-folder problems — the guardian email is the legal consent instrument (docs/14 §3: the link expires in 7 days, resends are capped, and a never-arriving email pushes the school to the paper form), so its deliverability is worth paying for.
ResendModern, generous free tier (3,000 emails/month), developer-friendly.
Any SMTP providerThe adapter is literally an SMTP URL in an environment variable.

Proof the exit works: development and tests run against Mailpit (a local SMTP inbox). Switching providers is changing one environment variable.


Rekognition — automated image screening (deferred)

Why it's the (future) pick:

Alternatives:

AlternativeTrade-off
Google Cloud Vision SafeSearchEquivalent capability and price shape; a second cloud account.
Hive ModerationModeration specialist, finer-grained categories; separate vendor and contract.
Claude (vision)We already have the Anthropic relationship and the moderation prompt/taxonomy; one vendor for all moderation. Likely the actual choice when this turns on.

Proof the exit works: the imageScreen adapter seam exists in the pipeline today; the pilot's implementation of it is "send to human queue," which is also the permanent fallback for any vendor's uncertain verdicts.


Text moderation and AWS — evaluated, not used

Text moderation runs on Anthropic's Claude API (not AWS), and the moderation research (docs/15 §2.4) compared the field before the §3a bake-off. Two Amazon options were on the table, for the record:

Amazon optionVerdict
Amazon Comprehend (toxicity detection)Rejected: English only, 7 fixed classes, and none of the categories that matter most here — grooming, contact-details exchange, spam. No known platform uses it for member content.
Amazon Bedrock (hosting gpt-oss-safeguard, an open policy-following model, at $0.07/$0.20 per MTok, no retention for open models)Possible future touchpoint: one of the shortlisted zero-retention hosts if the docs/15 §3a golden-set bake-off picks that model over the incumbent Claude connector. Not a commitment — Groq offers the same model on the same terms.

If Bedrock is ever chosen, it enters through the same rule as everything else: behind the existing moderation connector seam, swappable, with the human queue as the fail-closed default.


Backend hosting & the database — why Render today, and the AWS path later

The API and Postgres deliberately do not run on AWS today (docs/04 §11). Since "should we?" keeps coming up, here is the full reasoning. Costs for every path are in docs/18's last section.

The constraint that decides everything: the backend is one always-on Node process with the job workers (pg-boss) running inside it, polling Postgres every few seconds. That shape is a safety feature — moderation jobs enqueue in the same database transaction as the content they screen. It rules out, on architecture alone:

Why Render wins the pilot on merit, not inertia:

The AWS paths, ranked for when we do move:

PathWhen it's rightWhy not now
ECS Fargate (ARM) + ALB + RDS PostgresThe designated landing zone: real deploy pipeline, Multi-AZ database, room to split the worker into its own service later.~$60–77/month and a genuine ops surface (IAM, task definitions, security groups, alarms) — paying more to babysit more, at 10k users.
Lightsail VPS + Lightsail PostgresIf the only goal were "everything on one AWS bill" at minimum cost (~$27/month).It's a VM: we become the deploy pipeline, the TLS renewal, and the 3am restart. Violates the foolproof rule.
EC2 + RDSSame as Lightsail with more knobs.Same babysitting, more console.
App Runner / Lambda / Aurora ServerlessNever for this architecture (see above).—

Non-AWS alternatives to Render (same managed-PaaS shape, if Render itself disappoints): Railway (usage-based, ~$5 base), Fly.io (containers near users), Heroku (the original, pricier). For the database alone: Neon and Supabase are excellent managed Postgres, but their serverless/auto-suspend economics are wasted on a database our job queue never lets sleep — a plain always-on Postgres is the honest fit.

The exit, proven: everything runs in Docker locally every day; the database is vanilla Postgres 16 with plain SQL migrations. Moving Render → AWS (or anywhere) is: build the container, restore a pg_dump, repoint DNS. Days, not months — by design.


What we deliberately do NOT use AWS for

Not usedWhy
Cognito (auth)Auth is fully internal — for a minors' platform, no third party should hold children's credentials, and a ban must not depend on someone else's API (docs/04 §6).
RDS / DynamoDB (database)Postgres lives with the app on Render — one dashboard, backups included (full comparison in the hosting section above; RDS is the later landing zone). DynamoDB is proprietary lock-in with no benefit at 10k users.
Lambda / ECS / EC2 (compute)One boring Node process on a PaaS is the foolproof shape (see the hosting section above; Fargate is the later landing zone). Serverless is architecturally incompatible with our in-process job workers.
SQS / EventBridge (queues)pg-boss rides the existing Postgres and makes job enqueue transactional with the data change — a safety property SQS can't give us.

The pattern: AWS is used where it's a commodity behind a standard protocol (files, email, CDN), and avoided everywhere it would become architecture. That's what keeps the exit cheap and the pilot bill at a few dollars.

●  Have your own?

Paste your markdown, get a link like this.

Write your own
Thnkrr — Why These AWS Services, and What We'd Switch To · DocHouse