What to settle before an LLM feature carries real traffic

The demo works. Someone has asked when it ships. This is the point at which a list is more useful than an opinion, because every item below is cheap to decide now and expensive to retrofit once traffic is on it.

Twelve things, grouped by the conversation each one belongs to. If an item makes you say "we should check that", that is the item.

Money

1. A ceiling that stops spending, not one that emails you. Budget alerts tell you after the money is gone. What you want is a limit that refuses requests (per key, per team, or per feature) and you want to have seen it trigger at least once in staging. Which means deliberately blowing a small budget before launch rather than hoping.

2. Attribution decided before, not reconstructed after. If you cannot answer "what did this feature cost last month" without a spreadsheet, the boundary was not in the credential. Issue a separate key per boundary you will be asked about, the reasoning is here, because retrofitting attribution means reconstructing it from logs and arguing about the result.

3. Know what a retry costs. Every retry is a second full-price request. A retry policy set without a budget can multiply spend during exactly the incident when nobody is watching the bill.

Failure

4. A timeout chain, written on one line. Four numbers (connect, first byte, inter-token, total) that decrease as you move inward from the user. Ordered the other way, your outer layer gives up while the inner one is still generating and you pay for output nobody received.

5. A failover target and a retry budget. Not "retry three times": a cap on what share of your traffic may be retries, so a provider's bad hour cannot become a self-inflicted load spike. The failure taxonomy is here.

6. A decision about streaming failure. If you stream, work out now what happens when a stream dies at token 200. Restart? Show partial? Fail? Whatever it is, decide it before it happens: the edge cases are worse than they look.

7. A degraded mode that is not an error page. A smaller model, a cached answer, a form. Something that keeps the feature usable when the ideal path is unavailable.

Change

8. The model id out of your application code. Providers retire model versions on their own schedule — two months' notice is normal — so the id will change on a date you did not choose. If it lives in configuration, that is a config change; if it lives in a binary, it is a release under time pressure.

9. Baselines recorded before you need them. Parse rate on structured routes, output length distribution, refusal rate. Without a before, you cannot tell whether a model change hurt — and you cannot collect a before retroactively.

10. A rollback you have actually run. Not a documented one. Flip back, confirm traffic serves, flip forward. A rollback nobody has exercised is a hypothesis.

Evidence

11. Logs that answer the question you will be asked. The question is always "what happened to this request", so you need a request id you can quote, the model that served it, the token counts, and the outcome. What not to log matters as much: prompts and completions are the highest-risk data in the system and the least often the field you needed.

12. A written answer to the data question. Someone will ask what happens to the content users send — internally before launch if you are lucky, by a customer's security team if you are not. The questions worth being ready for are known in advance.

What this list deliberately leaves out

Evaluation quality, prompt engineering and model choice are not here. Not because they do not matter — they are most of the product — but because they are the part teams already spend their time on. The twelve above are the ones that get discovered in production, and every one of them is a decision rather than an implementation.

A useful test: pick any three and ask who would make the change and how long it would take. If the answer involves a deploy, that item is not settled yet.

Several of these land in the same place, which is the argument for a gateway rather than a library: the spend ceiling, the retry budget, the timeout chain, the model pin and the request log are one decision each, and either they live in one place or they live in every service that calls a model. Runix Router is where ours live. The list is worth running whatever you decide.