Thnkrr: Swappable Suppliers
9 October 2026. Research and recommendations. Nothing in here is built yet.
What this document is for
Thnkrr runs on other companies' services: Amazon for the servers, database, files, email and the AI check; GitHub for the code; and a few more. This document answers three questions for every one of those suppliers:
- What do we use it for, and what would break for a student if it stopped?
- What else could do the same job, at the same price or better?
- How would we switch, without taking the site down, and how long would it take?
The goal is the one big companies work to: no supplier should be able to hold us hostage.
If a price doubles, a service is retired, a company changes its rules on children's data, or
an account is frozen, we switch, and students never notice. The companion file
PROVIDER-SWAP-PLAN-2026-10-09.md is the step-by-step build plan for an AI coding agent.
It waits for your approval.
This document was written alongside PRODUCTION-RESEARCH-2026-10-09.md and
PRODUCTION-PLAN-2026-10-09.md (the production deployment work). It does not replace them.
It adds the "and we can leave" layer on top of whatever shape that plan lands on.
The one-minute version
- Most of our suppliers are already easy to swap, because the code talks to them through open standards: files use the S3 language (many companies speak it), email uses SMTP (every email company speaks it), the database is plain Postgres (a dozen companies host it), and the AI check sits behind one small connector.
- Four things are not swappable today, and they are all about running and watching the app, not about the app itself: how code gets onto the server, how the website files are published, where the secrets live, and where logs and alarms go. Each is tied to one Amazon feature by hand.
- One thing the docs claim exists but does not: the connector for an automatic picture check. The decision to use Amazon's picture check has no slot in the code to plug into.
- The fix is small. About 3 to 4 weeks of agent work, spread over the production build, and about $5 to $15 a month in extra running cost (a second copy of every backup at a different company, and a free Cloudflare account kept ready).
- The biggest single safety step is cheap: keep a copy of every backup at a company other than Amazon. Without it, an account freeze at Amazon would be the end of the data.
- The honest limit: no setup makes a switch free. Our aim is that each switch is a settings change plus a data copy, never a rewrite, and that we have practised every switch on a test copy before we need it.
Words used in this document
| Word | What it means |
|---|---|
| Supplier / provider | A company whose service we rent: Amazon, GitHub, an email sender |
| Connector (adapter) | A small piece of our code that talks to one supplier. The rest of the app only talks to the connector. Swapping suppliers means writing or choosing one connector, not changing the app |
| Open standard / protocol | An agreed language many suppliers speak. S3 (files), SMTP (email), Postgres (database), OpenTelemetry (logs and measurements), OCI (packaged app images). If we speak the standard, we can change who listens |
| Settings | Values the app reads when it starts (addresses, names, keys). A swap that is "a settings change" needs no new code |
| Stand-in | A free, local copy of a supplier's service that runs on a developer's laptop and in automated tests. It proves daily that the connector works without that supplier |
| Dual-run | Running the old and new supplier side by side for a while, comparing results, before switching |
| Cutover | The moment traffic moves from old to new |
| Warm spare | A second supplier's account, set up and tested, costing nothing or almost nothing until used |
| Exit drill | Practising a switch on a test copy, with a timer, and writing down what happened |
| Lock-in | When leaving a supplier would be so expensive or slow that we can't |
| Egress fee | What a cloud charges to copy your data out |
| Region | A group of a supplier's data centres in one place. Ours is Amazon's US East (Virginia) |
How the big companies do it, and what we take from each
What follows is what these companies have said publicly. It is a mix of good examples and honest warnings.
LinkedIn. Announced in 2019 that it would move everything to Microsoft's cloud (Azure). Shelved the move in 2022 and 2023 and stayed in its own data centres. The lesson is not "don't move"; it is that even a company owned by the cloud provider found a wholesale move too hard. What LinkedIn does well is layers: its apps talk to in-house systems (Espresso for data, Kafka for messages, Ambry for files, Nuage as a self-service portal), never to a vendor directly. It also tests every release with a canary: a small copy gets real traffic first and is compared against the old version for 30 minutes before the rest follow, and "dark canaries" receive copied traffic whose answers are thrown away.
Netflix. Fully on Amazon since 2016, and open about it: it does not try to be cloud-neutral. Instead it runs in several Amazon regions at once so one region failing is survivable, and it runs its own delivery network (Open Connect) for video, the one part of the bill that would otherwise be ruinous. Its deploy tool, Spinnaker, can target any cloud. The lesson: pick the one or two costly or risky parts and make those swappable; accept the rest.
Spotify. Moved from its own data centres to Google's cloud in 2016 to 2018. It did the move service by service, user-facing parts first, with no redesign during the move, and ran data and services as two separate programmes. About two years of preparation.
Dropbox. Moved 90% of its file storage off Amazon S3 onto its own hardware (2015 to 2016), and later reported about $75 million saved over two years. Possible only because its file layer already sat behind its own interface.
37signals (Basecamp). Left the cloud between 2022 and 2025. The yearly bill fell from about $3.2 million to $1.3 million, then the remaining storage moved too. Amazon waived about $250,000 in egress fees for the final copy-out. They built a small, open deploy tool, Kamal, that puts a packaged app on any Linux server with zero downtime and a one-command rollback. It is the closest open tool to what our deploy script does today, and it works on any provider.
Figma and Pinterest, the counter-examples. Figma's 2025 stock-market filing says its platform is "designed specifically to run on AWS" and commits it to at least $545 million over five years. Pinterest has a $3.25 billion Amazon commitment through 2029. Both are fine businesses. Both have given up the option to leave.
What regulators now demand. Europe's rules for financial firms (DORA, in force since 17 January 2025) require a written and tested exit strategy for every important outside service. Europe's Data Act (12 September 2025) forces cloud providers to make switching possible and bans switching charges, including egress fees for leaving, from 12 January 2027. Amazon, Google and Microsoft already waive egress fees for customers who leave. These rules don't apply to us, but they define what "industry standard" means now: a written exit plan per supplier, tested on a schedule.
The patterns we adopt, in plain words:
| Pattern | What it means for us |
|---|---|
| Backing services are attachable (the "twelve-factor" rule) | The app must not be able to tell a local stand-in from the real supplier. Only the settings differ |
| Ports and adapters | One connector per supplier type, one interface the app uses. We already do this for files, email, AI, speech and the guardian check |
| Expand, migrate, contract | For data moves: set up the new place, copy and keep in sync, switch readers, switch writers, then retire the old. Never a big-bang |
| Dual-run and shadow traffic | Before trusting a new AI model or email sender, run it beside the old one on real items and compare |
| DNS as the switch | Our addresses (thnkrr.com, media.thnkrr.com) are ours. Lower the address's cache time a day before, point it at the new place, keep the old place alive for a day |
| Backups outside the provider | A copy of every backup at a second company, in a format anyone can read |
| Exit drills on a calendar | Each switch practised on a test copy at least twice a year, timed, written down |
| A supplier register | One page listing every supplier, what it holds, the fallback, the last drill date. The same list feeds the public supplier (subprocessor) page schools will see |
Everything we depend on today
"Swap today" is how long a switch would take right now, with the code as it is. "After the plan" is after the companion plan is built.
| What | Supplier today | Open standard? | Swap today | After the plan |
|---|---|---|---|---|
| The server the app runs on | Amazon EC2 (one machine) | Yes: plain Linux | 1 to 2 days by hand | About 1 hour |
| The database | Amazon RDS (Postgres 16) | Yes: Postgres | 1 day, with an outage | Under 1 hour of read-only time |
| Photo and video files | Amazon S3 | Yes: S3 language | Hours (copy) + a settings change | Same, practised |
| Delivery network and website hosting | Amazon CloudFront + S3 | Partly: the routing rule and the purge are Amazon-specific | 1 day | 1 hour (DNS switch) |
| Amazon SES | Yes: SMTP | 1 hour + a day for the new sender's domain setup | Minutes (spare pre-verified) | |
| AI writing check | Amazon Bedrock (gpt-oss-safeguard-20b) | Partly: Amazon's own API, but an open-standard API exists too | A model change is one setting; a provider change is a new connector | One setting, within our allowed list |
| Picture check | None yet (Rekognition decided) | No connector exists | Not applicable | One setting |
| Speech-to-text | Whisper on our own server | Yes: open model | Already ours | Unchanged; a cloud fallback adapter added |
| Video conversion | ffmpeg on our own server | Yes: open software | Already ours | Unchanged |
| Domain and DNS | Unknown registrar; DNS not yet decided | Yes: DNS | Hours | Minutes (zone kept in code) |
| HTTPS certificates | Let's Encrypt via Caddy | Yes: ACME | Automatic fallback already | Unchanged |
| Code hosting and tests (CI) | GitHub | Partly: Git yes, Actions no | Days | Hours (mirror ready, thin workflows) |
| Getting code onto the server | Bash script over Amazon Session Manager | No | Rewrite | Same packaged image on any host |
| Secrets (passwords, keys) | One locked file on the server | Portable, but by hand | Hours | Minutes (encrypted in the repo) |
| Logs, alarms, errors, uptime | Not built; Amazon CloudWatch planned | Planned as Amazon-only | Not applicable | Any backend (OpenTelemetry) |
| Backups | RDS automatic backups only | Amazon-only | Not possible outside Amazon | Nightly copy at a second company |
| Child-safety and identity vendors | Hive or Thorn (quote), WebPurify (quote), Checkr, DigiLocker (2027) | Each proprietary | Contract-level | Behind connectors where they touch code |
| Laptop and test stand-ins | MinIO (files), Mailpit (email), Docker Postgres | Yes | MinIO is now unmaintained (see below) | Replaced |
Part by part
Each section says: what we use, what a switch looks like for students, the realistic alternatives, what must be true in the code, and how long. Prices are list prices seen on 9 October 2026 unless marked "unverified". Our usage is tiny, so the differences are a few dollars; what matters more is the rules each company applies to children's data.
1. The server the app runs on
Today: one Amazon EC2 machine (2 processors, 4 GB memory, about $25 a month plus disk and a fixed address). The production plan proposes Amazon's container service (Fargate) instead. Either way the app is a plain Node program on Linux.
What a switch looks like: we package the app once as a standard container image (an "OCI image", the same format every cloud and every laptop runs). The same image runs on an Amazon container service, on a rented Linux machine at any company, or on a laptop. Moving host = run the image somewhere else, point the address at it.
Alternatives for one always-on machine of about this size:
| Company | About a month | Notes |
|---|---|---|
| Amazon EC2 t4g.medium (today) | $25 + disk + address | ARM chip, cheap; our credits pay it |
| DigitalOcean (2 processors, 4 GB) | $24 | Official price. Per-second billing since January 2026. New York and Bangalore |
| Linode / Akamai (2 processors, 4 GB) | $24 | Official price. Washington DC, Newark, Atlanta; Mumbai and Chennai |
| Vultr Regular (2 processors, 4 GB) | $20 (High Performance line: $24) | Third-party listing; Vultr's own page blocks readers. Has Mumbai |
| Hetzner (US, Ashburn) | CPX11 (2 processors, 2 GB) $20.49; CPX21 (3 processors, 4 GB) $37.49 | Official, after the 15 June 2026 rise (CPX11 was $6.99). The cheap CX and ARM lines are not sold in the US. No longer a bargain here |
| Google Compute e2-medium (2 processors, 4 GB) | $24.46 (South Carolina) to $27.55 (Virginia) | Third-party price tracker, 4 October 2026 |
| Microsoft Azure B2ls v2 (2 processors, 4 GB) | about $30 | Third-party calculator, July 2026 |
| Oracle Cloud "Always Free" ARM | $0 | Official: 2 processors and 12 GB in total, 200 GB disk, 20 GB file storage. Reclaimed if idle (under 20% use for 7 days); home region only; capacity often short |
| Fly.io, Render, Railway | $22 to $25 | Zero-upkeep hosts; Fly changed prices 1 October 2026; Render cut included bandwidth 20× in August 2026 |
Rule that stays: the app must keep running all the time, because the review queue runs inside it. Any host that "sleeps when idle" is out.
What must be true in code: a container image built in CI; a deploy tool that works on any Linux machine (Kamal 2 is the recommendation: free, open, zero-downtime, one-command rollback, automatic HTTPS, used by 37signals for their own exit); the existing single-server files kept as the fallback. Time to build: 2 days. Time to switch after: about 1 hour.
2. The database
Today: Amazon RDS running Postgres 16. Postgres itself is open software; only the hosting
is Amazon's. Our search needs two standard Postgres add-ons (pg_trgm, citext); every
host below supports them.
What a switch looks like: Postgres can copy itself to another Postgres live ("logical
replication"). We set up the new database, let it catch up, then make the old one read-only
for a few minutes, point the app at the new one, done. Tools: Postgres's own replication, or
pgcopydb, which a company used in March 2026 to move 1 TB from Amazon to Microsoft with a
cutover of minutes. Things that don't copy automatically and must be scripted: sequence
counters, and the schema itself (we have it in our migration files already).
Alternatives (about 1 to 2 GB memory, backups to any minute):
| Company | About a month | Notes |
|---|---|---|
| Amazon RDS db.t4g.micro (today) | $12 + $2 disk | Our credits pay it |
| DigitalOcean Managed Postgres 1 GB | $15 | Per-minute billing since 2026; HA doubles it |
| Microsoft Azure Flexible B1ms | $12 | 1 processor, 2 GB; Central India available |
| Google Cloud SQL db-f1-micro / g1-small | $8 / $26 | Mumbai available |
| Crunchy Bridge (Postgres specialists) | from $10 | Runs inside AWS, Azure or Google regions |
| Neon | about $19 always-on + storage | Pay-per-hour; must turn off auto-sleep, or our queue stalls |
| Supabase Pro | $25, includes the smallest ("Micro") database | Official. The free plan pauses after a week idle, so only Pro fits us |
| Aiven | Free (1 GB, no choice of cloud); $12 Hobbyist on DigitalOcean, Google or OVH; $75 if it must run inside AWS | Official |
| Tiger Data (Timescale) | $30 + $0.177 per GB | Official. Time-series specialist; fine as plain Postgres |
| Postgres on our own server | $0 extra | We'd own backups and upgrades; not recommended for minors' data |
What must be true in code: nothing new in the app (it already takes a database address).
What's missing is a backup we own: a nightly export in the standard pg_dump format,
encrypted, copied to a second company's storage, plus a restore drill. Time to build:
1 day. Time to switch after: under an hour of read-only time, or hours from a backup.
3. Photo and video files
Today: two private Amazon S3 buckets. The code speaks the S3 language, not "Amazon". Database rows store file names, never full addresses, so the storage company can change without touching data.
What a switch looks like: copy the buckets with rclone (free, open), then change one
setting. During the copy, new uploads go to both (dual-write) or the new place pulls files
on demand (Cloudflare's "Sippy" does this). Students see nothing.
Alternatives that speak S3:
| Company | Storage per GB-month | Download fee | Legal-hold lock | US East / India | Notes |
|---|---|---|---|---|---|
| Amazon S3 (today) | $0.023 | $0.09 after 100 GB | Yes (Object Lock) | Yes / Yes | |
| Cloudflare R2 | $0.015 | $0 | Bucket-level locks only, no per-file hold | No regions; "US" hint only, no India | Free delivery pairs with free CDN |
| Backblaze B2 | $0.00695 (rose 1 May 2026) | Free up to 3× stored | Yes, per file | Virginia / no India | Cheapest with real lock; best for backups |
| Wasabi | $0.008 (rose July 2026) | $0, fair use | Yes | Virginia / unverified | 1 TB minimum bill, 90-day deletion charge |
| Google Cloud Storage | $0.020 | $0.12 | Yes | Yes / Mumbai | S3 mode exists |
| DigitalOcean Spaces | $5 for 250 GB | 1 TB included | No | New York / Bangalore | |
| Microsoft Azure Blob | $0.018 | $0.087 | Yes | Yes / Central India | Does not speak S3: needs a translation layer or code change |
| Hetzner, Scaleway | about $5 base | low | Yes | EU only | Not for US students |
Two things to know. First, the law-related holds: anything linked to a child-safety case must be kept a year and never deleted by a reviewer. Today that hold lives in our database, not in the storage company's lock, so R2's weaker lock is fine for live media. The future "archive" plan wants a true lock, so backups and archives should go to B2, Wasabi or S3, not R2. Second, no copy tool preserves a lock; after any copy, the lock must be re-applied.
MinIO, our laptop stand-in, is dead. The free MinIO stopped shipping in October 2025 and its code was archived in April 2026; the images we pull are a third party's frozen build with no security fixes. Replacements for laptops and tests: Garage (small, S3-speaking, no versioning or lock, fine for dev), SeaweedFS (has lock), or simply R2's free 10 GB for CI.
What must be true in code: already true. Add a conformance test that runs our storage connector against any S3 address and reports pass or fail, so a new company is proven in minutes. Time to build: half a day. Time to switch after: copy time plus minutes.
4. Delivery network and the website files
Today: Amazon CloudFront in front of the files and the website. Three Amazon-specific
pieces: the rule that sends app pages to index.html (a "CloudFront Function"), the purge
call when a photo is taken down (needed for the 2-hour legal clock), and a secret header
CloudFront adds so the API believes the visitor's address.
What a switch looks like: a delivery network is a layer in front of our own addresses. Switching is a DNS change plus warming the new cache. The three Amazon-specific pieces each need an equivalent on the new network.
| Company | Price | Purge | Private-bucket access | App-page routing |
|---|---|---|---|---|
| Amazon CloudFront (today) | First 1 TB a month free | API, free to 1,000 paths a month, minutes | Yes (OAC) | CloudFront Function |
| Cloudflare (free plan) | $0 | API, 1,000 URLs a minute, seconds | Yes, when paired with R2 | Pages or a Worker |
| Bunny.net | $0.01 per GB, $1 minimum | API, tag or URL | Yes (Storage Zone or S3 origin) | Edge rules |
| Fastly, Akamai | Enterprise | Fast | Yes | Yes |
| Google Cloud CDN, Azure Front Door | Usage | Slower purge | Yes | Yes |
What must be true in code: the purge connector gets a Cloudflare and a Bunny adapter beside the CloudFront one; the "which header carries the visitor's address" rule becomes a setting; the website publish step becomes a script with one adapter per host. Time to build: 1 to 2 days. Time to switch after: about an hour, plus DNS cache time.
5. Email
Today: Amazon SES, through plain SMTP. Switching the sender is literally one setting. The
catch is not the code: a new sender must prove it owns thnkrr.com (DNS records) and
build a reputation, which takes a day to set up and should be done before it is needed.
The guardian consent email is a legal instrument, so deliverability is the whole game.
| Company | At our volume (about 5,000 a month) | Keeps message text? | Where | Notes |
|---|---|---|---|---|
| Amazon SES (today) | about $0.50; new accounts from July 2026 start on a $0.16-per-1,000 plan | No body kept by default; archiving is a separate opt-in feature | Choose region (US East, Mumbai) | |
| Postmark | $15 for 10,000 | 45 days, cannot be shortened below 7 | US only (Chicago area and AWS); Postmark says it has no plans for EU servers | Best deliverability reputation |
| Resend | Free to 3,000; $20 for 50,000 | 30 days unless a $50-a-month add-on | US only | |
| Mailgun | $15 for 10,000 | 1 to 5 days on cheap plans | US or EU | |
| Brevo, Mailjet, Scaleway | Free to $15 | Not stated | EU only | Fine for EU, not our first pick |
| SendGrid | $20 for 50,000 | 3 days of logs | US | Killed its free plan in 2025 |
| Zoho ZeptoMail | $2.50 per credit of 10,000 (price from third-party listings; Zoho's page confirms the credit size, a free first credit, and a 6-month expiry) | Not found | "Available across all regions" (Zoho runs US, EU, India data centres) | Cheapest; credits expire |
| Self-hosted (Postal) | Server cost | We control | Anywhere | We'd own the sending reputation; not recommended |
Recommendation for the warm spare: Postmark or Zoho ZeptoMail, domain verified in advance, chosen on retention terms (ask Postmark for the 7-day setting).
What must be true in code: nothing. Add a mail:check script that confirms the DNS
records (SPF, DKIM, DMARC) for the active and spare sender. Time to build: half a day.
Time to switch after: minutes.
6. The AI writing check
Today: Amazon Bedrock running an open model (gpt-oss-safeguard-20b), with Amazon set to keep nothing. The code has one interface and three connectors (Bedrock, a laptop-only Anthropic one that production refuses, and "none"). The model name is stamped on every verdict, and a daily check keeps the backup models reachable. This is already the best-designed seam in the codebase.
Our rule stands: student writing goes only to a model running inside a cloud account we already hold, with zero retention and a written no-training promise. Never to a model company's own API. So the realistic fallbacks are other big clouds' model services and our own server, not Groq or Together, however cheap.
| Where the same model can run | Has gpt-oss-safeguard? | Price per million words-ish (in / out) | Retention terms | Fits our rule? |
|---|---|---|---|---|
| Amazon Bedrock (today) | Yes | $0.07 / $0.20 | None, by setting | Yes |
| Microsoft Azure AI Foundry | Yes (catalog) | 120b: $0.15 / $0.60 | Abuse monitoring may store flagged prompts for human review unless Microsoft grants an exemption | Yes, only with the exemption |
| Google Vertex AI | No (plain gpt-oss yes) | $0.15 / $0.60 | Zero retention needs an abuse-monitoring exception via account team | Yes, with exception; different model |
| Oracle OCI | No (plain gpt-oss yes) | Per token | Standard no-training | Yes; different model; has Hyderabad |
| Our own GPU server (vLLM) | Yes (open weights) | about $0.50 to $0.80 an hour, 24/7 ≈ $350 to $600 a month | Ours | Yes; expensive while idle |
| Groq, Fireworks, DeepInfra, Together | Some | $0.03 to $0.30 | Good zero-retention options | No: a new company would see children's writing |
The one portability trick worth doing: Bedrock now also answers in the industry-standard "OpenAI-compatible" API that every other host above speaks. Our Bedrock connector today uses Amazon's own API (Converse). Adding a second, generic connector that speaks the standard API to any allowed address means a provider switch becomes a settings change. Production keeps an allow-list of addresses so no setting can send writing to an unapproved company.
What must be true in code: the generic connector; the allow-list; the daily keep-alive generalised to any connector; the model-comparison script (already exists) run before any switch. Time to build: 1 to 2 days. Time to switch after: a setting, after the comparison passes.
7. The picture check (not built)
Today: people check every photo and video. Amazon Rekognition was chosen for later. The
architecture docs describe an imageScreen connector; the code has none.
| Service | Per 1,000 images | Free tier | Notes |
|---|---|---|---|
| Amazon Rekognition | $1.00 (+$1.00 for text in image) | 5,000 a month, first year | Default keeps images to improve Amazon's AI; must opt out account-wide first |
| Google Vision SafeSearch | $1.50 | 1,000 a month | Good terms, official: images are processed in memory and not written to disk; Google does not use them to train Vision |
| Microsoft Azure Content Safety | about $0.75 per 1,000 images (third-party; Microsoft's page hides the figure) | 5,000 a month, official | Best data terms (nothing stored, nothing trained); narrower categories, no text-in-image |
| Hive | $3.00 (+$2.00 text) | Trial credit | Most detailed categories. Its public privacy policy says nothing about retention or training and allows storage "in the United States or other countries"; terms would have to be negotiated |
| Sightengine | $29 for 10,000 operations | 2,000 a month | EU company. Offers an "delete immediately" setting and a data agreement; region choice only on enterprise plans; no explicit no-training promise found |
| WebPurify | $2.60 automatic; $20 human | Founder has asked for a quote | |
| Open-source on our server (NudeNet and similar) | $0 | Nudity only; misses much; keep humans |
What must be true in code: build the connector with a "send to a person" default and one real adapter; a provider setting. Time: 1 day for the seam, 1 day per adapter.
8. Speech-to-text and video conversion
Both run as open software on our own server (Whisper, ffmpeg). Nothing to swap away from. The production plan proposes moving speech to Amazon Transcribe for speed; that is fine as long as it goes behind the existing speech connector so Whisper stays the fallback. Cloud options, if we ever need them: Amazon Transcribe (official: $0.006 a minute for batch, $0.01 for live, 60 free minutes a month in the first year; the account-wide opt-out of data use is required first), Google (from $0.003 a minute, no logging by default), Microsoft Azure Speech. For video conversion, the only services that read from any S3 storage are Coconut, Qencode and Transloadit (about $0.0075 to $0.015 a minute). Mux, Bunny Stream and Cloudflare Stream keep the output on their side, which is lock-in; Amazon MediaConvert and Google only read their own storage.
9. Domain, DNS and certificates
Today: the domain's registrar and DNS host are not yet confirmed (an open item in docs/27). Certificates come from Let's Encrypt through Caddy, which already falls back to a second free authority (ZeroSSL) on its own.
The standard practice: keep the DNS zone as a text file in the repository and push it to whichever DNS company is active (open tools: DNSControl or OctoDNS). Then a DNS company switch is a one-line change, and the zone can never be lost with an account.
| Cost | API | Notes | |
|---|---|---|---|
| Amazon Route 53 | $0.50 a zone + $0.40 per million lookups | Yes | Natural if the site stays on Amazon |
| Cloudflare DNS | $0 | Yes | Fastest, free, DNSSEC included |
| DNSimple, NS1, deSEC | $0 to $6 | Yes | deSEC is a non-profit |
| Registrar: Cloudflare, Porkbun, Namecheap, Gandi | at cost to $15 a year | Keep the registrar separate from the hosting company |
10. Code hosting, tests and the packaged image
Today: GitHub holds the code and runs the tests (Actions). GitHub cut its hosted-runner prices in January 2026 and postponed a planned charge for self-hosted runners. Fine to stay. The risk is concentration, not price.
Standard practice: a nightly mirror of both repositories to a second host (GitLab,
Codeberg, or a plain Git server), and workflows that only call our own scripts (pnpm ci:local already mirrors CI), so they port in hours. Container images pushed to two
registries (GitHub's free one and Amazon's). Alternatives for CI: GitLab (400 free minutes),
Woodpecker (free, self-hosted), Forgejo Actions (reads GitHub workflow files with small
differences). Earthly, often suggested, shut down in 2025.
11. Secrets
Today: one locked file on the server, typed by hand. Portable in theory, but it lives in one place, and the production plan's move to Amazon Secrets Manager would tie it to Amazon.
Standard practice for a small team: secrets encrypted inside the repository with SOPS and age (free, open), decrypted at deploy time on whatever host. Alternatives: systemd's own encrypted credentials; 1Password or Bitwarden Secrets Manager (Kamal reads both directly); OpenBao (the open fork of Vault) if we ever need rotation and audit. Avoid a cloud's own secret store unless it sits behind a one-line loader we can replace.
12. Logs, alarms, errors, uptime and status
Today: nothing beyond the server's own log. The production plan proposes Amazon CloudWatch with Amazon's log format for metrics. That works, but it is the single most common lock-in in small companies.
Standard practice: the app emits logs, measurements and traces in OpenTelemetry (the open standard; traces and metrics are stable in the Node library, logs are still maturing), through a small collector that forwards to whichever backend we choose. Change the backend, change one line in the collector. Errors go through the Sentry format, which the open GlitchTip and Bugsink also accept.
| Need | Options | Cost |
|---|---|---|
| Logs, metrics, traces backend | Amazon CloudWatch; Grafana Cloud (free: 50 GB logs, 10,000 series); Honeycomb (free 20 million events); Axiom (free 500 GB); SigNoz (free self-hosted) | $0 to $25 |
| Errors | Sentry (free 5,000 errors; $26 team); GlitchTip (free self-hosted, $15 hosted); Bugsink (one container) | $0 to $26 |
| Uptime check from outside Amazon | UptimeRobot (free 50 checks); Better Stack (free 10); Checkly; Gatus or Uptime Kuma self-hosted | $0 |
| Status page | Instatus (free); Better Stack (free 1); Upptime (free on GitHub) | $0 |
| Paging | PagerDuty (free 5 users); incident.io (free basic); Grafana IRM (free 3 users). Opsgenie ends April 2027 | $0 |
The uptime check and status page must live outside Amazon, or they go dark with it.
13. Backups
Today: Amazon's automatic database backups, 7 days. Nothing outside Amazon. If the Amazon account were frozen or deleted, every photo, post and consent record would be gone.
Standard practice (3-2-1): three copies, two kinds of storage, one at a different
company. For us: Amazon's own backups, plus a nightly encrypted pg_dump and a nightly
file sync to Backblaze B2, plus a restore drill every quarter that times a full restore
onto a test host at a different company. Tools: pg_dump and rclone, or pgBackRest for
continuous backup (archived by its maintainer in April 2026 and revived in May 2026 under a
coalition including AWS and Supabase). Cost at our size: about $1 to $5 a month.
14. Child-safety and identity vendors
These are contracts more than code. What we can do in code is keep each behind a connector with a "people do it" default, which already exists for the guardian adult check.
| Need | Vendors | Swappable? |
|---|---|---|
| Child-abuse image matching | Microsoft PhotoDNA (free, vetted), Google CSAI Match (free, vetted), IWF list (£5,000+ a year), NCMEC hash sharing (free), Cloudflare's scanning tool (free with Cloudflare) | Several free sources; one connector |
| Grooming and new-content detection | Thorn Safer (list $30,720 a year), Hive | Contract; keep the human queue as the default |
| Human review vendor | WebPurify ($0.02 an image) | Contract; results arrive through one interface |
| Staff background checks | Checkr ($29.99), Certn ($49.99), GoodHire ($29.99), Sterling (quote) | Any; no code |
| Guardian adult check (India, from 13 May 2027) | DigiLocker (named in the law), plus IDfy, Signzy, HyperVerge (India), Veriff ($0.80), Persona ($250 a month minimum) | Connector exists; one adapter per vendor |
| Reporting to NCMEC | NCMEC only | Not swappable: the law names it |
Things we accept are not swappable
- Postgres as the database engine. Changing hosts is easy; changing engines is a rewrite. We chose Postgres for that reason.
- NCMEC for child-safety reports, and DigiLocker for India's guardian check: the law names them.
- GitHub as the daily workplace. We mirror it; we don't plan to leave it.
- Amazon's credits. Leaving Amazon early means paying cash. The point of this work is the option, not the move.
- Infrastructure code is always cloud-shaped. The production plan writes Amazon's setup in Amazon's CDK; that code cannot run on Google. That is normal. What stays portable is the app and the data. The reasonable hedge is OpenTofu (the open fork of Terraform) if the CTO prefers one tool that knows every cloud; it is a preference, not a requirement.
What the plan would build, in order
- Backups outside Amazon and a restore drill. The one step that removes the catastrophe. 1 day.
- The missing seams: the picture-check connector, the generic AI connector with an allow-list, Cloudflare and Bunny purge adapters, a configurable visitor-address header. 3 to 4 days.
- The packaged app (container image) and Kamal as the any-host deploy path, beside the existing files. 2 days.
- Website publish script with an adapter per host. 1 day.
- Secrets in the repository, encrypted. Half a day.
- OpenTelemetry for logs, measurements and traces, with Sentry-format errors. 2 days.
- DNS zone in the repository; registrar confirmed. Half a day.
- Repository mirrors, two image registries, thin CI workflows. Half a day.
- Supplier register (internal page plus the public supplier list),
providerscommand that prints what is live and whether each is reachable, and a drill calendar. 1 day. - The first exit drills on a test copy, timed and written down: storage to R2, email to the spare, AI to the backup model, delivery network to Cloudflare, host to a rented machine, database restore from the off-site copy. 3 days.
About 3 to 4 weeks of agent work, interleaved with the production plan's phases.
What it costs
| Item | A month |
|---|---|
| Off-site backups (Backblaze B2, about 100 GB first year) | about $1, rising to $5 |
| Cloudflare account (DNS, CDN, R2 free tier) | $0 |
| Spare email sender, verified, idle | $0 (Postmark free developer tier) or $0 (ZeptoMail first 10,000 free) |
| Uptime check and status page outside Amazon | $0 |
| Logs and errors backend, free tiers | $0, up to $25 if we outgrow them |
| Total | about $1 to $15 |
Against that: a switch that today would take days of hand work and an outage becomes an hour; a frozen account becomes a bad day instead of the end of the data; and every school asking "what happens to our students' data if your provider fails?" gets a written, practised answer.
Decisions for the founder and CTO
Product and money decisions. Everything else follows from them.
| # | Decision | Recommended | Alternative |
|---|---|---|---|
| P1 | Approve the companion plan as the next build after the production plan's Phase 1 | Yes, interleaved | Later, after the first school |
| P2 | Second company for backups | Backblaze B2 (US, cheap, real lock) | Wasabi (1 TB minimum) or Google |
| P3 | Allowed AI fallback cloud, if Amazon's model were ever unusable | Microsoft Azure AI Foundry, with the abuse-monitoring exemption in writing | Our own GPU server (about $400 to $600 a month) |
| P4 | Spare email sender | Postmark (ask for 7-day retention) | Zoho ZeptoMail (has India) |
| P5 | Laptop and test file stand-in, replacing the dead MinIO | Garage | SeaweedFS, or R2's free tier in CI |
| P6 | Infrastructure code tool | Keep the production plan's CDK; app and data stay portable | OpenTofu for one tool across clouds |
| P7 | Measurements format | OpenTelemetry to CloudWatch via a collector (swappable) | Amazon's own log format (not swappable) |
| P8 | Secrets | Encrypted in the repository (SOPS and age) | Amazon Secrets Manager behind a loader |
| P9 | Drill cadence | Every quarter, one drill; all six at least once a year | Twice a year |
| P10 | Domain registrar and DNS | Registrar separate from hosting; zone in the repository | Everything at Route 53 |
What we could not verify
Checked again on 9 October 2026. Resolved against the supplier's own pages: DigitalOcean, Linode, Hetzner (US table), Oracle's free tier, Amazon Transcribe, Google Vision's data terms, Postmark's US-only hosting, ZeptoMail's credit terms, Supabase, Aiven, Tiger Data, Bedrock's model prices, and SES's no-storage default. Still resting on third-party figures or silent pages:
- Vultr's prices (its site blocks automated readers), Google and Azure compute prices (from trackers, not the official pages, which load their tables with scripts), and ZeptoMail's per-credit dollar price.
- Azure Content Safety's paid image price (Microsoft's page shows a blank).
- Hive's and Sightengine's retention and training terms: neither company states them publicly. Both would need a signed agreement before any student image went to them.
- Which specialist inference hosts list gpt-oss-safeguard. Moot: our rule excludes them.
Sources
Seen 9 October 2026 unless noted. Grouped by the section they support.
How the big companies do it
- CNBC, 14 Dec 2023, "LinkedIn shelved plan to migrate to Microsoft Azure cloud"; The Register and Data Center Dynamics, same date.
- LinkedIn Engineering: "Nuage: making data systems management scalable" (2018); "Kafka ecosystem at LinkedIn" (2016); "Monitoring the pulse of LinkedIn" (EKG, 2015); "Production testing with dark canaries" (2020).
- Netflix: "Completing the Netflix cloud migration" (2016); Spinnaker blog, "Running Spinnaker in multiple regions at Netflix"; QCon London 2014, Netflix active-active case study; TechCrunch on Open Connect (2012).
- Spotify Engineering, "Views from the cloud: a history of Spotify's journey to the cloud, part 1" (2019).
- The Register, 14 Mar 2016, Dropbox moves data from AWS; Data Center Dynamics, "How Dropbox pulled off its hybrid cloud transition".
- David Heinemeier Hansson, "We stand to save $7m over five years from our cloud exit"; Data Center Dynamics on 37signals leaving S3 and on its 2024 savings; The Stack on the AWS egress waiver; dev.37signals.com, "Kamal 2".
- Figma S-1 (SEC, 2025); InfoQ, "Figma's $300K daily AWS bill" (July 2025). Pinterest 10-K FY2025 (SEC).
- 12factor.net, "Backing services". Martin Fowler, "Parallel change". Google SRE Workbook, chapter 16, "Canarying releases"; Google, "The calculus of service availability".
- Cloudflare DNS best practices, "Phase 2: lower TTLs". AWS whitepaper "Unpicking vendor lock-in" (marked historical); AWS Prescriptive Guidance, multicloud for FSI, "Vendor lock-in".
- DORA Article 28(8) exit strategies (Panorays summary; presencis.com text). EU Data Act switching framework (Travers Smith; Maples); 2026 Digital Omnibus proposal (Greenberg Traurig). Bank of England PRA SS2/21 and Rulebook chapter 10.
- Flexera 2026 State of the Cloud; Gartner press releases 13 May 2025 and 19 Nov 2024.
Servers and hosts
- DigitalOcean Droplet pricing page (official). Akamai Cloud (Linode) North America pricing page and regions page (official). Vultr prices via learnwithhasan.com and costbench.com (third-party; vultr.com returned 403). Hetzner Docs, "Price adjustment 15 June 2026" (official US and EU tables); Hetzner cloud page (Cost-Optimized line marked "currently not available"); coverage at findstack.com, privatedevops.com, wz-it.com, northflank.com, bex.co. gcloud-compute.com e2-medium page (third-party tracker, updated 4 Oct 2026). azurespeed.com and holori.com Azure VM calculators (third-party, July 2026). Oracle Cloud docs, "Always Free resources" (official).
- Fly.io, "2026 pricing update" (effective 1 Oct 2026) and resource pricing docs; Render pricing coverage (pricingsaas.com; costbench.com; jwatte.com on the August 2026 bandwidth change).
- Kamal releases (GitHub, v2.12.0); Dokku zero-downtime docs; k3s requirements and resource profiling; Nomad 2.0 release notes; Watchtower archive notice (linuxiac.com).
Database
- Supabase pricing page (official). Aiven for PostgreSQL pricing page (official). Tiger Data pricing page and docs (official). DigitalOcean Managed Postgres pricing (infratally.com, April 2026; kuberns.com). Neon pricing page; Prisma, "Prisma Postgres vs Neon pricing 2026"; jetadmin.io Neon review (Sept 2026). Crunchy Data, "Making Postgres more affordable" and pricing page. Bytebase dbcost snapshots for Cloud SQL (July 2026) and Azure Flexible B1ms.
- PostgreSQL docs, logical replication restrictions (PG 19). Meltwater engineering, 19 Mar 2026, "Migrating a 1 TB PostgreSQL from AWS to Azure with pgcopydb". PlanetScale pgcopydb import guide. AWS DMS pricing (nops.io); Google Database Migration Service pricing. pgBackRest news (archived 27 Apr 2026, revived 18 May 2026); Percona community post, 28 Apr 2026. AWS RDS Postgres extensions page; Neon pg_trgm docs; Supabase extensions page.
File storage
- Cloudflare R2 pricing, S3 API compatibility, bucket locks (Mar 2025), data location, Super Slurper, Sippy (Azure added July 2026). Backblaze B2 pricing (rise effective 1 May 2026), Object Lock docs, data regions, Cloud Replication. Wasabi pricing and FAQ (minimum, 90-day deletion charge), object-lock docs. Google Cloud Storage pricing, interoperability (S3 XML API), object lock. Azure Blob pricing; Flexify.IO marketplace listing; MinIO gateway deprecation (2022). DigitalOcean Spaces pricing and features; DigitalOcean HIPAA products post. Hetzner Object Storage overview and FAQ. Scaleway storage pricing and concepts. Tigris blog and features. Storj pricing and forum pricing notice (July 2026).
- MinIO end of development (linuxiac.com); Docker Hub and Quay pull problems (byteiota.com). Garage (garagehq.deuxfleurs.fr). rclone forum, object-lock feature request. AWS DataSync, other-cloud object locations.
Delivery network and DNS
- Bunny.net purge-cache docs and core API; Bunny pricing coverage (bitdoze.com; costbench.com). Cloudflare docs: purge by single file (rate limits), cache rules, R2 public buckets and custom domains, caching R2 content; Cloudflare blog, "Instant purge for all". Cloudflare DNS product page and feature matrix (DNSSEC on Free). Route 53 pricing (AWS docs; cloudcostkit.com; classmethod.jp on July 2026 TLD price changes).
- AWS SES pricing (Essentials plan default from 21 July 2026); AWS re:Post, "Searching and retrieving email content sent via Amazon SES" (content not stored by default; archiving opt-in). Postmark retention article; Postmark, "EU privacy" page (US hosting, no EU plans). Zoho ZeptoMail pricing page (credit size, expiry, regions) and GetApp listing ($2.50 a credit). Resend docs on disabling content storage; Resend GDPR page; SOC 2 period. SendGrid, Mailgun, Mailtrap, Mailjet, Brevo, Zoho ZeptoMail, Scaleway TEM pricing pages and third-party summaries. Postal (GitHub, release June 2026); Haraka. Google, Yahoo and Microsoft bulk-sender requirement summaries (2025 to 2026).
AI writing check
- AWS Bedrock pricing page (official, US East: safeguard-20b $0.07 in / $0.20 out per million tokens; safeguard-120b $0.15 / $0.60). AWS Bedrock model cards for gpt-oss-safeguard-20b and 120b (launched 29 Oct 2025; EOL no sooner than 29 Oct 2026); Bedrock OpenAI-compatible Chat Completions docs. Azure AI Foundry model catalog; Microsoft abuse-monitoring docs. Google Vertex AI data governance and gpt-oss forum post. Oracle OCI Generative AI release notes (18 Nov 2025) and regions. Groq models and "your data" docs. Fireworks data handling docs. DeepInfra data privacy policy (15 Aug 2026). Together, Cerebras, SambaNova, Nebius pricing pages. Baseten, Modal, Hugging Face endpoint pricing (third-party). RunPod pricing (27 Sept 2026); AWS g6/g5 pricing; Hetzner GEX44; OVH GPU. OpenRouter ZDR docs; Portkey; Cloudflare AI Gateway logging docs; LiteLLM; Kong AI Gateway.
Picture check, speech, video
- Amazon Rekognition pricing (Group 2 API) and quotas (50 TPS us-east-1, 5 TPS ap-south-1); AWS Organizations AI services opt-out policy. Google Vision pricing; Google Cloud Vision docs, "Data usage" (in-memory processing, no training). Azure AI Content Safety pricing page (F0 allowance; paid figure blank) and turbo360.com cost playbook ($0.75 per 1,000 images, third-party). Hive pricing; Hive privacy policy (silent on retention and training). Sightengine security page and FAQ (delete-immediately option, enterprise region choice). Sightengine, WebPurify, Clarifai, Imagga pricing pages (third-party where noted). NudeNet, Falconsai, OpenNSFW2 repositories. Microsoft PhotoDNA terms; Google protectingchildren.google; Thorn Safer partnership criteria and AWS Marketplace listing ($30,720 a year); IWF membership fees; NCMEC 2023 hash-sharing report; Cloudflare blog on the CSAM scanning tool.
- Amazon Transcribe pricing page (official: $0.006 batch, $0.01 streaming, 60 free minutes a month for 12 months) and opt-out docs. Deepgram model improvement partnership docs. AssemblyAI EU endpoint and pricing. Google Speech-to-Text v2 data logging docs and pricing. Groq Whisper pricing. Speechmatics, Gladia pricing. faster-whisper and WhisperX.
- AWS MediaConvert pricing; Google Transcoder pricing; Azure Media Services retirement (30 June 2024). Mux, Bunny Stream, Cloudflare Stream, api.video, Coconut, Transloadit, Qencode pricing pages.
Code hosting, CI, secrets, observability
- GitHub changelog, 16 Dec 2025, Actions pricing; samexpert.com on the postponed self-hosted charge. GitLab, Bitbucket, Buildkite, CircleCI pricing (cicdcalculator.com; Atlassian). Woodpecker CI releases (3.19.0, 7 Oct 2026). Forgejo Actions overview. Dagger licence. Earthly shutdown post. Docker Hub pull limits docs; GitHub Container Registry announcement; ECR pricing.
- SOPS and age on a VPS with systemd (dchost.com); systemd credentials (iconik help). AWS Secrets Manager and Parameter Store pricing. OpenBao releases (1 Oct 2026); Vault BSL. Infisical, Doppler pricing (envmanager.com). 1Password Connect docs. Bitwarden Secrets Manager FAQ.
- OpenTelemetry language status table;
@opentelemetry/sdk-node;@opentelemetry/instrumentation-pino. Grafana Cloud, Honeycomb, Axiom, Better Stack, SigNoz, Datadog, New Relic pricing summaries. Highlight.io shutdown (Feb 2026). Sentry pricing (costbench.com); GlitchTip; Bugsink. UptimeRobot, Checkly, Gatus, Uptime Kuma 2.0, Healthchecks.io. Instatus, Atlassian Statuspage, Upptime. Opsgenie end of support 5 Apr 2027 (hyperping.com); PagerDuty, Grafana IRM (OnCall OSS archived 24 Mar 2026), incident.io, Rootly pricing. - OpenFeature (CNCF incubating); Unleash, Flagsmith, GrowthBook, LaunchDarkly pricing. AWS WAF and Shield pricing; Cloudflare plans; Bunny Shield pricing; Fastly NGWAF coverage.
Identity and background checks
- Checkr pricing article; Certn US pricing; GoodHire (third-party); University of Washington HR (Sterling example). Veriff self-serve plans; Persona help centre pricing; Stripe Identity pricing; Yoti, Onfido, Jumio (third-party estimates); IDfy, Signzy, HyperVerge (third-party). DPDP Rules 2025 notification (13 Nov 2025) and Rule 10 commentary (privacyglobal.org; legal500.com).