A solo-dev growth cockpit that runs its marketing on a solar-powered AI farm

Most AI marketing tools are a meter with a UI on top. You write a blog draft, something bills you. You regenerate it, something bills you again. The pricing page talks about credits because credits are what the vendor is buying wholesale and reselling.
IndieBob's free tier is built the other way round. The models that serve it run on a machine I own, in a room I can walk into. That one architectural decision changes what a free account can honestly be — so it is worth writing down what actually runs, rather than the marketing version.
What is on the rig
Two local text models sit behind an OpenAI-compatible endpoint, registered as two tiers:
- Fast (tier 1) —
qwen3.5:9b. Slugs, keyword clusters, social posts, meta descriptions, image prompts, SEO fix suggestions, email copy, claim checks. - Smart (tier 2) —
gemma4:12b. Blog drafts and outlines, content briefs, content opportunities, keyword analysis.
The smart model used to be a 30B mixture-of-experts. It was replaced because it could not physically load: the rig is a 12 GB card, that model wants 18 GB, and it only ever appeared to work when another model happened to already be resident in VRAM. gemma4:12b was A/B'd on this exact card — better instruction-following, 7.6 GB — and won on the hardware that exists rather than on a benchmark table.
Images are the same story. The default image model is local FLUX, and it is the default for every plan, not just the free one, because it is both free and good enough that reaching for a metered provider is usually a downgrade in economics and a sideways move in quality. The paid alternatives are still there behind a plan gate, honestly priced in the code at roughly $0.003 to $0.055 an image depending on which one you pick.
Both text providers are registered with an input and output cost of zero. That is not a rounding convenience — it is the number the usage meter records, and it is why a free account's month of writing shows up in the ledger as compute minutes on hardware we own rather than as a bill.
The rule that makes it a guarantee
Anyone can put local models behind a free tier and then quietly fall through to a cloud API when the machine is busy. That fallback is where "free" turns into a bill you did not plan for, and it is invisible from the outside.
So the policy is one function, in one file, and it returns a pair of flags rather than a single boolean:
- Plus and admin — the cloud cascade is allowed. Their generations still debit their monthly allowances.
- Free — local-only, always.
The pair matters, and it matters because of a real bug. The router only blocks the cascade when noCloudFallback is set; passing only the permissive half of the pair does nothing at all. For a while, callers passed only that half, and free accounts silently fell through to Gemini or Claude every time the local rig was down. It never showed up as an error, because it was not one — it was a working feature doing the wrong thing quietly. The fix was to make the two flags one object that callers spread whole, so they cannot be separated by accident.
Two more holes in the same wall got closed at the same time. Tier 3 tasks — strategic analysis, pricing advice — used to route straight to a frontier model before the guard ran, and an explicit "force cloud" option bypassed it too. Now, when cloud is blocked for the caller, a tier 3 task is served by the local smart model instead, or it fails honestly.
That is what the honest failure looks like, verbatim, when the rig is off and you are on the free tier:
Image generation is briefly offline. Please try again in a few minutes.
Briefly offline is a real state of a real machine. It is a worse experience than a silent fallback would be, for about four minutes. It is a much better one than a bill.
Caps live at the endpoint, not in the button
Every AI action a free account can take is capped per month, and the check runs on the server, inside the generation endpoint, before any model is touched. The blog-draft endpoint asks for a blog_drafts credit before it drafts; the image endpoint asks for an ai_images credit before it renders, and clamps the size of the batch to what is actually left, so a four-image request cannot oversell a two-image remainder.
Underneath the per-user caps there is a global circuit breaker: a daily aggregate cost and request budget across all free accounts, cached for sixty seconds so it does not cost a database query per request. If free usage as a whole blows through it, free AI pauses for the day rather than the rig being pinned by whoever wrote the fastest loop.
Two AI calls sell nothing on the pricing page and are deliberately not metered against any monthly category — the claim check and the Command Center's "Do Next" refresh. Charging for the safety check teaches people to skip it, which defeats the point of having one. They get per-user, per-day breakers instead, counted in the database so they hold across instances.
Why grounding matters more when the model is small
Here is the part that people who have only used frontier models tend to get wrong.
A 9B or 12B model is perfectly capable of writing a clean paragraph about your product. What it cannot do is know your product. Neither can a frontier model, but a frontier model's guesses are fluent enough that you have to read carefully to catch them, and it has absorbed enough of the internet that its average guess about "a tab manager" is often accidentally close. A small local model's guesses are worse and easier to spot — which sounds like a disadvantage and is actually the design constraint that makes the whole thing work.
The answer is not to make the model bigger. It is to make the gap where facts belong impossible to fill with invention:
- A per-project facts corpus is pasted into every content prompt — blog drafts, briefs, social posts, email copy, meta descriptions — through the one project-context seam every content prompt already used. A prompt template cannot forget to include it, because it does not have the option.
- Each source is sliced to 4,000 characters before it reaches a prompt, and to 1,200 for compact tasks like social posts and meta descriptions. The corpus is a paragraph the model is allowed to know about you, not a knowledge base.
- Audience and tone are separate rows, capped at 600 characters each, emitted as their own lines. They never spend corpus budget, so describing your reader never costs you a feature.
- The grounding rules override style, and they give the model somewhere to put a gap:
[VERIFY: what needs checking]on its own line, instead of a confident guess.
The size caps are the unglamorous half of that list and they are load-bearing. A 7,000-character facts sheet is half-invisible to a full-length prompt, and entirely invisible past the first 1,200 characters to a social post. Under a tight budget, what you put first is what the model knows.
I am not going to claim the local models write better copy than a frontier model. We have not run that comparison and I would not trust our own scoring of it if we had. What I will claim is narrower and testable: a small model with your actual product facts in front of it produces fewer false statements about your product than a large model without them.
What this costs you
Nothing, on the free tier, and not in the sense that a trial is free. There is no card, no per-token meter running behind the UI, and no path by which a free account triggers a metered call — that last one is the rule the code holds absolutely, and it is the reason the rest of it can be stated plainly.
The way in is the connect guide: open a project, go to its connect page, and it walks you through pointing IndieBob at what your product actually is before you ask it to write a word about it. That is fifteen minutes that decides whether everything downstream is grounded or invented.
Some months the rig will be busy and you will see "briefly offline". I would rather ship that sentence than a bill neither of us agreed to.
Share this article
Stay up to date
Get the latest insights on indie software growth, marketing tactics, and building profitable projects.
No spam. Unsubscribe anytime.