The arithmetic of a $10 app

By Lior Rabanian · · 6 min read
  • Builder's log
  • Pricing
  • One-time purchase

Apple charges $99 a year for the right to sign software that opens without a warning on someone else's Mac. That bill arrives whether I sell nothing or sell ten thousand copies, and it arrived before Cyanote had a name.

At $10 a copy, with the payment processor's cut taken out, that is eleven sales a year to stand still.

I want to lay out the rest of the numbers, because "one-time purchase" gets discussed almost entirely from the buyer's side — as a nicer line on a bank statement — and almost never as the constraint it puts on the person on the other end. The constraint is the interesting part. It shapes what the app is allowed to be.

Where the ten dollars goes

Take one sale. Lemon Squeezy is the merchant of record, which means they handle sales tax in every jurisdiction that wants some, and they charge 5% plus 50¢ for the service. On a $10 sale that is a dollar, near enough, so about $9 lands.

Against that, the recurring costs:

Apple Developer Program, $99/year. Not optional. Without it there is no Developer ID certificate, which means no notarisation, which means every buyer meets the warning that macOS cannot verify the app and a meaningful share of them stop right there.

A domain, about $12/year. Boring, unavoidable.

Hosting, near zero. The site is static and sits on GitHub Pages. The update payload goes to a Cloudflare R2 bucket, which is free until a level of traffic I would be delighted to reach.

So the floor is roughly $111 a year, or about thirteen copies. That is the whole cash side. It is small enough that I could pay it out of pocket forever and never notice, which tells you immediately that money is not the real cost here.

The obligation the buyer never sees

The moment someone pays $10, they get free updates for life. That is on the pricing page, and I meant it when I wrote it.

Now count what "life" contains. macOS ships a major version every autumn. Each one has, historically, been able to break something: a permission prompt that used to appear once and now appears every launch, a window behaviour that changes, a system API that gets deprecated with two years' notice. None of that generates a single new sale. All of it has to be fixed, for people who paid once, three years ago, and are entirely right to expect the app to keep opening.

The surface that has to survive those autumns is about 36,000 lines of TypeScript and 3,500 lines of Rust, sitting on a webview that Apple ships and I do not control.

This is the honest asymmetry of buy-once software, and the reason so many good apps drifted to subscriptions: revenue is a spike at launch and a long tail after, while the maintenance is flat forever. Anyone who tells you the model is simply better for everyone is selling you something. It is better for the buyer, plainly. For the developer it is a bet that enough new people keep arriving to fund work that existing customers have already paid for.

One $10 sale against the fixed yearly costs: about $9 net, $111 a year in floor costs, and the maintenance that the price does not scale with
The cash side is small. The obligation is the part with no ceiling.

What the price makes impossible

Here is where the arithmetic stops being accounting and starts being product design.

$10 once cannot fund a server. Not a sync server, not an account system, not a licence server that phones home on every launch. Run the numbers on any of those and you get a per-user, per-month cost against a one-time payment that was already spent — the classic way a buy-once app becomes insolvent about eighteen months in, quietly degrades, and then announces a subscription.

So the architecture had to make servers unnecessary rather than cheap. Everything lives in one SQLite file on your own disk. There is no account because there is nothing for an account to sign into. The licence key is checked once, on first launch, and never again — which creates its own support problems, and I would rather have those than the alternative.

I did not arrive at local-first from an ideology about data ownership, though I have since acquired one. I arrived at it because it is the only shape that a $10 payment can actually sustain. What local-first means for your notes is the buyer-facing version of that argument; this is the ledger underneath it.

$10 also cannot fund a support team, which is why the app tries hard to explain itself in place — a paste that cannot happen says what permission is missing rather than failing silently and generating an email.

The refund line

14 days, no reason required, no proof of uninstall.

The received wisdom is that a no-questions refund policy on a cheap product invites abuse. Maybe. What it definitely does is remove the reason a person hesitates at a checkout for a $10 app from a developer they have never heard of, with no free trial, that they cannot try before buying. That hesitation costs far more than the refunds will.

There is also a version of this that is just self-interest: a refund tells me something. A stream of them clustered around one feature is the most direct signal I will ever get, given that there is no telemetry in the app and I have deliberately given up every other way of knowing what people do inside it.

What I would tell someone pricing their own

Three things, learned mostly by doing them in the wrong order.

Price the maintenance, not the build. The build is finite and mostly already spent by the time you have a price. The maintenance runs until you stop, and the price is the only thing funding it. $10 is defensible for Cyanote because the app has no per-user running cost. If yours does, $10 is a slow way to lose money and no amount of goodwill fixes that.

Make the promise you can keep, and write it down narrowly. "Free updates for life" is a promise about updates to this app on this platform. It is not a promise that every future thing I build is free, and the pricing page says so in plain words. Vague generosity at the point of sale becomes a bitter argument in year three.

Do not pretend the model has no downside. The thing a one-time price genuinely buys is real and worth having — no renewal date, nothing taken away for lapsing, an app that still opens if I disappear. The thing it cannot promise is an infinite runway. Anyone who has watched a beloved buy-once app go quiet knows the failure mode, and pretending otherwise on a pricing page insults the reader.

The arithmetic is not comfortable and it is not a secret. Eleven sales a year covers Apple. Everything after that funds the autumn when macOS changes something and a few thousand people who paid once, years ago, expect their notes to open exactly as they did the day before.