Field Notes

Cost Model

Parent: Architecture · Companion: decisions/supabase-db-auth.md · Status: estimate, prices verified via public pricing pages on 2026-07-04. Ranges are deliberate — this is a planning tool, not an invoice. Re-verify LLM prices before launch; they churn quarterly.

As built (all 8 phases shipped): the operational budgets settled in doc 05 are $20/mo house-key cap · $10/mo per-user virtual key · $2/day chat · alert at 80% — this page is the planning model those caps were sized against. Two shipped choices make the current bill smaller than the steady-state modeled below: market data stayed on yfinance and news is Finnhub free tier (the Tiingo line is $0 until the paid upgrade), and dev runs the whole gateway on a free Gemini key. Backups are Supabase Pro's own daily backups (no self-run backup infra) and observability is OTel wiring with no hosted backend — neither adds a line item.

1. Assumptions (read first)

All volume assumptions come from design 01 unless noted:

  • News: ~150 articles/day embedded (title+snippet, ~100–200 tokens each); ~40 stories/day synthesized, avg ~1.5 synthesis calls/story (re-synthesis at count thresholds 1/3/8) → ~60 calls/day. Each call: ~10 title+snippet pairs + instructions ≈ 2–3k tokens in, structured output ≈ 300–500 tokens out.
  • Market recap (shared): 1 run/day, ~3–5k in / ~1k out; ~30 runs/mo.
  • Daily agent (per user): ~5–9k in / ~2–3k out per run — fact pack ~3–6k plus system prompt and tool round trips (aligned with design 02 §5.5) — ~22 trading days/mo.
  • Recap personalization (per user): ~1–2k in / ~500 out per briefing — incremental tokens of the daily agent's markets section (same run, same mid tier, user key per design 02 §5.5); shown as its own line for visibility.
  • Chat (per user): light/medium/heavy = ~10/50/150 messages/day, 30 days/mo. Per user message, including tool-call round trips that re-send context: ~6–12k tokens in (midpoint 9k), ~0.5–1k out (midpoint 0.75k). This is the single most important assumption in the whole model.
  • Action verification: deterministic transaction matching — zero LLM cost by design.
  • Month = 30 days; trading month = 22 days. No prompt caching or batch discounts assumed (both exist and only make these numbers smaller — see §8).
  • Prices are standard-tier list prices in USD per million tokens ("/M").

2. LLM price reference (verified 2026-07-04)

Chat/completion models

TierModelInput /MOutput /MNotes
CheapGPT-5 nano$0.05$0.40cheapest usable extraction class
CheapGPT-5 mini$0.25$2.00the workhorse cheap tier
CheapGemini 3.1 Flash-Lite$0.25$1.50comparable to mini
CheapClaude Haiku 4.5$1.00$5.00priciest "cheap"; strong quality
MidGPT-5 / 5.1$1.25$10.00
MidGemini 3.5 Flash$1.50$9.00near-frontier quality, mid price
MidGemini 3.1 Pro$2.00$12.00≤200k context pricing
MidClaude Sonnet 5$2.00→$3.00$10.00→$15.00intro pricing until 2026-08-31
BestGPT-5.5$3.00$20.00
BestClaude Opus 4.8$5.00$25.00modeled best-tier default
BestClaude Fable 5$10.00$50.00premium ceiling; not a default

Sources: Calcis OpenAI rate card, Anthropic pricing roundups + Sonnet 5 announcement, Gemini rate summaries. Batch APIs are ~50% off everywhere; Anthropic cache reads are ~90% off input.

Embeddings

text-embedding-3-small: $0.02/M ($0.01/M batch) — OpenAI model page. At our volumes embeddings are a rounding error, which is why the design keeps re-embedding cheap and swappable. As built (phase 6): the shipped model is gemini/gemini-embedding-001 @ 1536 dims on the free Gemini key — $0 today; the swappability paid off immediately.

3. Shared layer (house key) — monthly

JobVolume/moTokens/mo (in / out)Model tierCost/mo
Article embeddings~4,500 articles~0.7M / —text-embedding-3-small~$0.01–0.02
Story synthesis~1,800 calls~4–5M / ~0.6–0.9Mcheap (nano→mini span)~$0.50–3
Generic market recap~30 runs~0.12M / ~0.03Mcheap~$0.02–0.10
Shared total≈ $1–3/mo (≤$8 even on Haiku)

This validates the hypothesis: cheap-tier models are the right call for the entire shared layer, and the whole layer costs less than a coffee per month regardless of user count. It is consistent with design 01's envelope ($0.05–0.15/day for synthesis).

The one quality floor to watch: structured extraction accuracy on story synthesis — tickers[], event_type, importance drive story routing into daily briefings, so extraction errors propagate into user-facing insights. The eval set (story → expected tickers/event_type, design 01 §6) is the gate. Recommended tier per job:

JobRecommendation
Embeddingstext-embedding-3-small — no reason to pay 6.5× for -large at this corpus size
Story synthesismini-class (GPT-5 mini / Gemini 3.1 Flash-Lite) as default; downgrade to nano-class only if the extraction eval holds; upgrade to Haiku 4.5 if it doesn't. The spread is $0.5–8/mo — buy accuracy, it's cheap
Generic recapnano-class — freeform prose over pre-ranked stories, no structured extraction risk

4. Per-user layer — monthly

Defaults per job (each user can override per job; LiteLLM makes this config): daily agent = mid (GPT-5-class), recap personalization = mid (runs inside the daily agent call — design 02 §5.5), chat = best (Opus 4.8-class), verification = none.

JobMath at defaultsCost/user/mo
Daily agent22 × (7k in @ $1.25 + 2.5k out @ $10) ≈ 22 × $0.034~$0.60–0.90
Recap personalization22 × (1.5k @ $1.25 + 0.5k @ $10) ≈ 22 × $0.007~$0.10–0.20
Action verificationdeterministic — no LLM calls$0.00
Chat (the dominant variable)per message ≈ 9k @ $5 + 0.75k @ $25 ≈ $0.06light ~$19 · medium ~$96 · heavy ~$288

Per-user totals (chat model choice shown because best-tier pricing spans 2.5×):

VariantLight (10/day)Medium (50/day)Heavy (150/day)
Defaults (best chat = Opus 4.8)~$20~$95–100~$290
Defaults, best chat = Gemini 3.1 Pro ($2/$12)~$8–9~$38–40~$115
All-cheap (everything mini-class)~$1.5~$6~$18
All-premium (everything Opus 4.8-class)~$21–22~$98~$290+

Two readings of this table:

  • Chat is 90–99% of per-user spend at defaults. Everything else — the briefing, personalization, verification — rounds to about $1/user/mo. The architecture's "deterministic facts, generated words" principle is what keeps the non-chat lines this small: contexts are compact fact packs, not raw data dumps.
  • Under BYOK these per-user costs sit on the user's own provider key (with LiteLLM budget caps), not the house key. House-key exposure is then only the shared layer (§3) plus infra (§5) — the product's marginal LLM cost per user is ~$0.

5. Infrastructure — monthly

ItemChoiceCost/moNotes / source
App DB + authSupabase Free → Pro$0 → $25Pro when it's the daily driver; $10 credit covers Micro compute (decision doc, pricing)
Lake object storageCloudflare R2~$0Free tier: 10 GB + 1M writes + 10M reads/mo, zero egress. Our lake is tiny: 5y EOD prices for a few hundred tickers is tens of MB of Parquet; news raw+curated ≈ 25–50 MB/mo; per-user snapshots are KB/day. Years of runway ≈ single-digit GB; paid rate $0.015/GB-mo thereafter (R2 pricing)
Python brain + LiteLLMsmall VPS (Hetzner CPX22-class, 2 vCPU/4 GB) or Fly.io shared VMs~$6–15Hetzner ≈ €8/mo; Fly ≈ $2/machine + egress, realistically $8–15 for two small always-on services
Web appon the v1 box (Caddy serves Next.js, per doc 05 §9); Fly/Railway or Vercel Pro at scale-out$0 → ~$20v1 ships no separate web host — the VPS line above covers it. At multi-user scale-out move to Fly/Railway or Vercel Pro ($20/user/mo, $20 usage credit); if a serverless platform (Vercel) hosts the web tier, check function-duration limits on the /brain/* SSE chat proxy first (pricing)
Market data + newsTiingo Power$30 ($25/mo if annual $300)Verified current: individual $30/mo, News API included, EOD + corporate actions included; fundamentals is an add-on. Note: design 01 said "~$10/mo" — outdated, actual is $30 (Tiingo pricing). Internal-commercial tier $50/mo; redistribution licensing beyond that needs review before multi-user launch
News fallback (dev)Finnhub free tier$060 calls/min, company news, personal use only (Finnhub pricing) — fine for dev, not for a commercial product
Domainany registrar~$1 (~$10–15/yr)

Infra subtotal: dev/lean (all free tiers + yfinance) ≈ $7–16/mo; solo steady state ≈ $60–70/mo; multi-user adds a web host (Fly/Railway or Vercel Pro) and the Tiingo commercial tier.

As built (phase 8): the hosting target is AWS EC2 (t4g.small ARM, ≈$12–15/mo — the "small VPS" line above), runbook committed; news shipped on Finnhub free and prices stayed yfinance, so the $30 Tiingo line is deferred until the paid-data upgrade — the running system's infra bill is the dev/lean column plus Supabase Pro when it becomes the daily driver.

6. Scenario totals

Steady state, defaults, house key pays everything (no BYOK). Chat mix assumed all-light for the headline; the medium/heavy spread is in §4.

LineSolo (1 user)10 users100 users
Shared LLM (§3)~$2~$2–4~$3–6
Supabase$25$25$30–75 (Small→Medium compute)
R2~$0~$0~$0–1
VPS (brain + LiteLLM)~$10~$10~$15–30
Web hosting$0 (on the VPS)~$20 (Fly/Railway or Vercel Pro)~$20 (Fly/Railway or Vercel Pro)
Tiingo + domain~$31~$51 (commercial)~$51+ (license review)
Fixed subtotal~$70~$110~$120–185
Per-user LLM (light chat, defaults)~$20~$200~$2,000
Total (house key)~$85–95/mo$310/mo ($31/user)$2,100–2,200/mo ($21/user)
Total if BYOK (users pay own LLM)~$70$110 ($11/user)$120–185 ($1.2–1.9/user)

How to read it:

  • Fixed costs amortize hard: ~$70/user solo → ~$11/user at 10 → ~$1–2/user at 100. The shared layer (news, prices, recap) is genuinely flat — its LLM cost doesn't move from 1 to 100 users, exactly as designed (universe growth is sub-linear, stories are synthesized once).
  • The only line that scales linearly is per-user LLM, and chat is ~95% of it. BYOK converts that line to $0 house exposure, which is why the architecture treats BYOK as the multi-user unlock: at 100 users the house bill is roughly a Netflix-tier fixed cost, not a payroll-tier LLM bill.
  • Step functions to expect on the fixed side: Supabase compute (Micro→Small→Medium), VPS size, Tiingo license tier, web hosting (Fly/Railway or Vercel Pro). Each is a $5–50 step, not a cliff.
  • Solo today, being honest: ~$90/mo all-in at defaults with light chat — of which $30 is Tiingo, $25 Supabase, ~$20 chat. During the build phase (free tiers, yfinance, no chat yet) it's realistically ~$10–20/mo.

7. Where the money actually goes

At every scale the ranking is the same: (1) chat tokens, (2) fixed subscriptions (Tiingo + Supabase + hosting), (3) everything else. The deterministic analytics engine — the core product value — costs $0/run. The daily briefing costs about a dollar per user per month. Design effort spent on cost should go to chat context discipline and model routing, nowhere else.

8. Sensitivity and knobs

  • Chat volume dominates (~15× between light and heavy at the same model). A per-user LiteLLM budget cap is the safety net; usage-ledger visibility in Settings is the behavioral one. As built: the shipped caps are $2/day chat (user_settings, preflight-enforced) with the $10/mo virtual-key budget as the hard stop — at defaults that bounds chat to roughly the light-usage line.
  • Chat model choice is a 2.5–4× knob: Gemini 3.1 Pro ($2/$12) vs Opus 4.8 ($5/$25) vs Fable 5 ($10/$50) — per-job defaults with user override make this a config decision, per architecture.
  • Prompt caching: chat re-sends system prompt + fact pack + history every turn — the exact shape caching rewards (cache reads ~90% off input on Anthropic, ~90% on OpenAI cached input). Realistically cuts chat input cost 40–70% at medium/heavy usage; not assumed above, so treat §4 as conservative.
  • Tool-call round trips: each extra round trip re-bills the whole context. Tight tool outputs (compact fact JSON, not row dumps) keep the 9k-in/message assumption from drifting to 20k.
  • Polling cadence (3×/day → 30-min): raises API request counts against Tiingo limits, but embeddings/synthesis costs barely move — dedupe and thresholds mean the same articles cost the same once. A freshness knob, not a cost knob.
  • Synthesis thresholds (1/3/8): raising the first threshold to 2 cuts synthesis calls ~30–40% but delays first summaries of slow-building stories. At ~$1–3/mo total, not worth touching for cost.
  • Daily agent tier: mid → best is ~$0.75 → $1.6–2.1/user/mo. If briefing quality ever disappoints, upgrading is cheap; downgrading to mini ($0.15) is on the table for cost-floor mode.
  • Trading-day gating already saves ~27% on the daily agent vs running every calendar day — keep the gate.

9. Source list

Verified 2026-07-04: Supabase pricing · Supabase compute · Cloudflare R2 pricing · Vercel pricing + Hobby plan terms · Tiingo pricing · Finnhub pricing · OpenAI embeddings · OpenAI/Anthropic/Google model rate cards as linked in §2 · Hetzner cloud pricing review · Fly.io pricing teardown.