
The other evening I wanted to answer a question that sounds simple: how much should I charge for this? I couldn't. Not because the maths is hard, but because I didn't have the cost price yet. And to get it, you first have to know who does the work behind each button.
Every Krizaka product has its own trade. One makes video, another reads documents, another shows matches, another syncs a shop's listings. Each trade has its own providers, with their prices per unit, their licences, their minimums and their approval forms. This post is about how I choose, how I go from a cost to a price, and the tool that keeps me from guessing.
One trade, several providers
For the maths, the GPU taught me the most. When I wanted to generate clips, the GPU quota at DigitalOcean was at zero, while a ticket was waiting. I still tested a 20 GB RTX 4000 Ada from them: a 1280 by 704 clip fits in memory, but it takes 18 minutes. On an H100 rented by the hour from RunPod at $3.99, the same kind of clip with Wan 2.2 TI2V 5B takes between 170 and 280 seconds and costs $0.19 to $0.31. So I rented from RunPod. Not because it is "the best", but because it is what I measured on my own work.
For media, the idea is not to glue the code to one provider. Short five-second loops go to Bunny Storage, long videos to Bunny Stream, and I wrote down the decision to put a door in front of it, so I can change. This month Bunny weighs about $1 on my bill: that is not where I should look for savings. For e-mail it is Mailgun, with a key that can only send. For maps I have a house rule: MapLibre and a Protomaps base drawn from OpenStreetMap, never Mapbox or Google Maps.
Sports data taught me something else. Kachizaka shows fixtures and results. For two football leagues, openfootball is under a CC0 licence: we can use it freely. For the NHL there is only the league's public web API, and it has no published licence. So we call it from the server, with a ten-minute cache, in development only, never in production, behind an adapter we can replace. For the NBA, MLS and the Champions League, I found no source whose terms allow our use, so those competitions are not offered. There is a rule written in the repository: if a provider's terms forbid the use, we don't show the competition.
For the identity and creditworthiness checks of Yomizaka, I have chosen nothing yet. I wrote down the options and one rule: personal data stays in a single place, with consent and Québec's Law 25 first, and the price second. For payments in high-risk industries, I wrote a separate post.
Then there are providers you don't choose with a credit card. To sync a shop's Google listing and Meta pages, Akinaza needs approved API access. Google asks for a business profile verified for more than 60 days and a website, then an access form. Meta asks for business verification and an app review, with a screen recording of the flow. It is free, but it costs time, and time goes into the calendar before it goes into the price.
How I choose
My criteria are always the same, in this order. First the licence, and what the provider may do with our data. Then where the data lives, because a customer in Québec does not always want it to leave. Then the price per unit and the minimums. Then the approvals to obtain. Then lock-in: how much it would cost me to leave. Last, quality, which I measure on my own work instead of taking it on trust.
| Trade | Chosen | Set aside | Because | What it costs |
|---|---|---|---|---|
| Hourly GPU | RunPod, H100 at $3.99/h | RTX 4000 Ada at DigitalOcean | 18 min per clip against 3 to 5 | A forgotten GPU: nearly $96 a day |
| Video and media | Bunny, with a door in front | Nothing ruled out, a backup planned | Stream for long, Storage for loops | One more provider to depend on |
| Mailgun, send-only key | A key with broad rights | A leak can only send | The subscriber list lives in our database | |
| Maps | MapLibre and Protomaps | Mapbox, Google Maps | Open, our tiles on our CDN | Styling the map ourselves |
| Sports data | openfootball (CC0) | NBA, MLS: not offered | Terms missing or unclear | Competitions we don't show |
| Identity, credit | Nothing chosen | Everything, for now | Consent and the law first | We wait |
The table is honest on one point: the right-hand column is never empty. Every choice costs something, and the question is to know what before signing.
From a unit cost to a price
Once the provider is chosen, you need a number per user action. Not per run, per action: a clip kept, a lease read, a gigabyte delivered. Each trade has its own unit, which is why pricing looks so different from one product to the next.
I start from the post on the real cost of an image. A run costs a certain price, but what the person wants is an accepted result. If only one output in three is right, the good one costs three times as much.
cost per accepted result = (cost of one run + checking) ÷ p
full cost = cost per accepted result + overhead
price = full cost ÷ (1 − margin)An example, with a single measured figure. A hosted clip of Wan 2.2 A14B costs $0.60 a run. Suppose two clips out of three are right: the accepted result costs $0.90. I add 10% overhead for storage, payment and support: about $1. With a 50% margin, the price is $2. The two assumptions (p and the overhead) are not measured, and the margin is not a calculation, it is a decision.
What remains is the fixed costs, which depend on no action: the apps, the database, the message broker. For us that is about a hundred dollars a month, not counting the hourly GPU. While there are almost no users, that is an expense, not a unit cost. It enters the price once there is volume: fixed costs divided by the month's actions.
The report that keeps me from guessing
So these numbers don't stay in my head, I wrote a small command, ./couts. It is read-only. It queries the official billing of DigitalOcean, Bunny and RunPod, adds my subscriptions and domain names, and writes a dated report. In it: spend by provider and by product, the ten biggest lines, the trend over four months, a ceiling per provider with the month's projection, and a "where to save" section.
Keys are read at run time and never written. Before saving a report, the command reads it back and refuses to write it if anything looks like a key. This post shows a rounded excerpt, with no identifier, no resource name and no balance.
| Line, mid-October | Spent so far | Share |
|---|---|---|
| Hourly GPU (RunPod) | ≈ $83 | 78% |
| Apps and databases (DigitalOcean, estimated) | ≈ $14 | 13% |
| Subscriptions and fixed fees | ≈ $8 | 8% |
| Media (Bunny) | ≈ $1 | 1% |
| Total, 17 days out of 31 | ≈ $107 | 100% |
What jumps out: the GPU is close to 80% of the spend, and about 85% of the total goes to the AI engine, the rest being shared between the common infrastructure and the other products. The biggest line of the month is an H100 pod billed for five hours, about twenty dollars, left on without working. The day I ran the report, it also flagged in red a pod still on at 0% activity, with the cost of a day if you forget it. In "where to save" it also suggests merging two small admin apps, for $10 a month. That is the kind of thing I would never notice looking at one bill at a time.
What it doesn't cover yet: Claude and Gemini. For Claude, an admin key for the API is missing. For Gemini, the billing export to BigQuery has to be switched on. And the DigitalOcean line is an estimate, made from the inventory and the price list, because my token can't read billing. The report says so: a source that is unavailable is marked "not available", never guessed.
What you can take from this
Choose the provider on your own work, not on its website: measure a dozen real cases. Write down the licence and the cost of each choice next to the name, before signing. Work out the cost per action, not per run, and say which assumptions you added. Put a door in front of the providers you might leave. And automate reading your bills: a forgotten pod costs more than an afternoon spent writing the script. To go further on the numbers, there is what image and video generation costs, and my accounts and keys.