Day 10 of 100·Project Deep-Dive Day·518 words

Cost-aware architecture — the $30/month design constraint

How a hard budget shaped every infrastructure decision in zoth (and how to tell that story).

Know your own system

Most students' projects silently assume infinite cloud credits. Yours documents a budget and derives the architecture from it — DEVOPS.md §16 in zoth literally prices the deployment. This is a differentiator in interviews: engineering under constraints is the job.

The ledger (know these numbers)

ItemChoiceCost driver
AKS cluster1 × Standard_B2s, autoscaling off~$30/mo — node VM is the entire cost
ACRBasic SKU, admin user disabled~$5/mo (within credits)
RabbitMQin-cluster StatefulSet, 1 replica, 1 Gi PVC (Azure managed disk)~$0.05/mo
Postgresin-cluster (pgvector/pgvector:pg16 in dev)free (compute shared)
Ingressremoved — kubectl port-forward accessavoided ~18/moLB+ 18/mo LB + ~3/mo public IP
Idleaz aks stop~$0.05/mo

The ingress decision is the best story: the default kubectl apply of an nginx ingress on AKS spins up a **Standard Load Balancer + public IP ≈ 21/month∗∗—7021/month** — 70% of the entire budget to expose a demo. The documented alternative: `ssl-redirect: false`, no TLS/cert-manager, access via port-forward. The prod overlay ingress yaml even omits a `host:` (accepts raw IP). *Honest framing:* "I traded public reachability for budget; the 'right' fix is a 0 Cloudflare Tunnel in front, which I chose not to add before I needed it."

Decisions the budget forced (the pattern to articulate)

  1. Single node → no HA story, but K8s still buys self-healing processes (probes restart crashed pods) and declarative config.
  2. RabbitMQ in-cluster instead of CloudAMQP → ops burden accepted (StatefulSet + PVC + diagnostics probes) in exchange for $0 marginal.
  3. Postgres in-cluster in dev; Aiven managed for prod (per .env.prod / DEVOPS.md) → dev database on a volume, prod on managed storage with backups.
  4. OTel → Better Stack (free-ish tier) instead of self-hosting the ELK stack — observability as a SaaS line item.
  5. Bicep, not Terraform — DEVOPS.md justification: native Azure integration, no state file to store/lock/pay for.

Traverse's version of the same discipline: one VPS (~$6/mo class), Postgres as a container (postgres:17-alpine) with WAL archived to S3 (storage is cents/GB) and Aiven as the offsite backup rather than the primary — because a managed primary costs more than the whole box. Redis runs --maxmemory 512mb --maxmemory-policy noeviction — memory-bound cost control where eviction would mean losing jobs (Day 46).

How to talk about it

Never "I was too broke for Kafka." Instead: "The constraint was $30/month, so I designed the smallest system that met the functional requirements and bounded the non-functional ones: availability from process self-healing rather than replicas, durability from the outbox pattern rather than broker replication, and cost from running the broker and cache in-cluster. Each has a documented upgrade path: quorum queues, a second node, a managed PG." Constraints → decisions → upgrade paths. That's the language of staff-engineer design docs.

One more interview gem from your own CI: GitHub OIDC federation instead of storing Azure secrets in GitHub (Day 86) — app registration zoth-github-actions with federated credentials. Cost: zero. Value: no rotatable secret to leak. Cost-aware and security-aware at once.

Bulletproof your resume

Say these answers aloud before moving on

These are the follow-ups an interviewer will actually ask about your projects.

01

Your cluster has no ingress. How do you demo it, and what's the production-grade fix?

Dev/demo access via kubectl port-forward (free). The graded fix, in order of cost: (1) a 0CloudflareTunnelorngrok(IalreadykeptanNGROKDOMAINin.envforwebhookdev);(2)actuallypayingthe 0 Cloudflare Tunnel or ngrok (I already kept an NGROK_DOMAIN in .env for webhook dev); (2) actually paying the ~21/mo for a Standard LB + public IP with cert-manager TLS; (3) fronting with Azure Front Door. The reason it wasn't done: 70% of budget for a non-requirement at demo scale.

02

What did the budget teach you that an unlimited account wouldn't have?

To price every architectural component before adding it: a message broker, a load balancer, a managed database each have monthly costs that must be justified by an NFR. It also forced right-sizing — 1-node AKS with resource requests (100m/128Mi per service) means I actually read the utilization data instead of guessing. Most 'we need Kafka' decisions in industry are made by people who never saw the invoice.

03

How does traverse achieve durability on a $6 VPS?

Postgres runs with wal_level=replica, archive_mode=on, archiving WAL to an S3 bucket (us-east-1, cents per GB), plus a 3-day host-cron sync to Aiven as the offsite copy. That gives point-in-time recovery from a single box — restore drills exist as admin endpoints (/pitr/status|backups|snapshot|restore). The tradeoff accepted: the box itself is a single point of availability, but not of durability.