cd /news/artificial-intelligence/my-saas-was-silently-broken-for-4-da… · home topics artificial-intelligence article
[ARTICLE · art-56457] src=dev.to ↗ pub= topic=artificial-intelligence verified=true sentiment=· neutral

My SaaS was silently broken for 4 days because an AI My app was broken for four weeks and I didn't notice. So I got rid of the API.

A solo developer running brevio.news discovered that a hosted LLM API silently broke the product's weekly brief feature for four weeks after the provider retired a model ID. The developer fixed the issue by switching the weekly brief to run entirely on a local Mac Studio M4 Max using Qwen via MLX, eliminating API dependencies and adding a healthcheck that fails loudly if the brief is missing. The local model generates the brief in about 35 seconds with zero API cost and produces comparable or better results.

read4 min views1 publishedJul 12, 2026

On June 14th, the weekly brief feature of my product died. No crash, no alert, nothing in my inbox. It just quietly stopped producing anything new, and the dashboard kept showing the last good brief like everything was fine.

I found out four weeks later.

Some context

I run brevio.news alone. It started as a personal itch: I had hundreds of YouTube videos saved for "later", newsletters I never opened, articles piling up. I wanted something that reads all of it and gives me back a short editorial brief every morning, like a tiny Economist built from my own watchlist. No sponsored content, no recommendation feed.

Today it watches 475+ sources (YouTube, RSS, academic feeds, newsletters) across 7 themes, and publishes a brief every morning at 9:00 in 5 languages. It went through the classic solo builder phases: a CrewAI prototype, then n8n, then a real codebase.

The setup is simple. A Mac Studio M4 Max (64 GB) in my office does all the AI work: Whisper for transcription, Qwen for classification and writing. I started with Ollama and later moved the pipeline to MLX. The Mac pushes results to a small VPS (FastAPI, Postgres, nginx) that serves the dashboard. The Mac generates, the VPS serves.

Everything ran locally except one feature. The weekly brief, a Sunday synthesis of the week for paying users, still called a hosted LLM API.

What actually happened

The weekly job calls a model by its ID. That ID got retired by the provider, and the API started returning 404. The job itself kept "succeeding" every Sunday: the timer fired, the code ran, the error got swallowed somewhere, and no new brief was written. A frozen feature looks exactly like a working feature unless you check the dates.

I'd love to say I caught it through some clever alert. I didn't. I noticed while working on something else.

Two things I had to admit to myself:

A hosted model ID is a dependency with someone else's lifecycle. It can be retired like an old npm package, except there's no lockfile and nothing warns you at build time.

And my monitoring only watched for errors. The failure here wasn't an error, it was an absence. Nothing happened, and "nothing" doesn't trigger alerts unless you design for it.

The fix took one Sunday

The daily editorial already ran on a local model, Qwen3.6-35B-A3B in 4-bit, about 19 GB on disk. So the weekly brief had a proven path to copy. Now it works like this:

Sunday 09:15, on the Mac:
  pull the week's items from the local DB (~700 items, 7 themes)
  generate the brief with Qwen via mlx_lm
  pick the featured video per theme in code (the model never writes URLs)
  convert markdown to HTML in code (the model never writes HTML)
  POST to the VPS, idempotent upsert
  ping a healthcheck that expects a brief to exist by 10:00

The numbers on the M4 Max: model loads in about 6 seconds from cache, generation takes about 28 seconds for ~1,800 tokens from an 8,700 token prompt. Call it 35 seconds for the whole brief. API cost: zero. New dependencies: zero, the model was already on disk for the daily pipeline.

I'm currently the only paying user of this feature (the product has 29 users total), which made the migration comfortable. I could iterate on the prompt against real data and judge the result myself. The local brief turned out as good as the hosted one on the part I care about, connecting trends across themes. Its "what to watch next week" section is actually better, because it sticks to signals from the week instead of speculating.

A few choices I'd defend: the model writes prose, code writes structure. Links are picked by a ranked query and injected afterwards, so a hallucinated URL is impossible, not just unlikely. The sync keeps the last good brief if anything fails, so the dashboard never shows a hole. And there's now a check that fails loudly if the expected brief doesn't exist on Sunday morning. That one would have saved me a month.

Why local, honestly

The zero API bill is nice, but it's not the real reason. The real reason is that a model on my own disk can't be retired, rate-limited or repriced by someone else. For a one-person product, removing a whole class of external failures, the exact class that just bit me, is worth more than being able to switch to the newest hosted model.

The Mac was already paid for and already reads 475+ sources every morning. The weekly brief costs it 35 seconds a week.

If people are interested I'll write up how the daily pipeline works end to end, from Whisper to the 9:00 brief. Brevio is at brevio.news.

The whole thing exists because I believe staying informed shouldn't cost you your mornings.

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @brevio.news 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/my-saas-was-silently…] indexed:0 read:4min 2026-07-12 ·