AWS Builder Center
When does a decision model pay for itself?

When does a decision model pay for itself?

Strands Decider 2B and Claude Haiku 4.5 compared on four questions per support message, measured on Amazon SageMaker AI and priced from 100 to 25,000 requests an hour. It includes the break-even point against one LLM call, an inline cost calculator, and why self-hosting rarely beats hosted decision APIs on price.

In Part 1  I ran Strands Decider 2B on five AWS hosts. On one routing question it lost to Claude Haiku 4.5, 72% against 93%. Letting Decider answer when it was confident and handing the rest to Haiku got 90%, at about 36% lower cost. Part 0  covered where decision models came from and how to choose one.
The question I keep getting since is simpler: is it actually cheaper than an LLM, and at what volume?
Real agents rarely ask one question. A support message needs routing, a scope check, a personal-data check and a "does a person need to see this?" check, often as four separate model calls. Decision models can answer several questions in one pass, so that's where I expected Decider to win. I wrote down three pass/fail bars before running anything, then measured.
Two things changed between Part 1 and this test:
  • Hosted decision APIs now have public prices. OpenAI's Decisions API went into public beta  on 6 October, and TypeSafe lists Jev's price  per input token.
  • Strands published a new checkpoint, hobson-v21, with the same accuracy as v19 and better calibration. I used v21, with v19 as a check.
Batching gets half an answer here: several questions in one request is measured below; batching separate requests on the GPU isn't possible yet, for reasons in the gotchas.

The results first

Bar, written before the testResult
A. Four questions cost Decider at most 1.3× the latency of oneFail: 196 ms against 71 ms, 2.8×
B. Decider first, Haiku when unsure: within 3 points of Haiku's accuracy and at least 40% cheaper than four separate Haiku calls, at 1 request a secondPass: 70% against 73% all-four-right, 58% cheaper ($1.69 against $4.06 per 1,000 requests)
C. The same, against one Haiku call answering all four questionsFail: only 4% cheaper ($1.69 against $1.77)
Cost per 1,000 four-question requests against volume
So, when does a decision model pay for itself?
  • Against four separate LLM calls: almost always, above about 500 requests an hour on one GPU.
  • Against one well-built LLM call: only at volume. Break-even is about 3,000 requests an hour on a SageMaker AI ml.g6.xlarge, or about 1,250 if only the routing question goes to the LLM.
  • Against a hosted decision API: not on price, at any volume one GPU can serve. Self-hosting buys you residency and control, not a lower bill.
The surprise was that Decider beat Haiku on one question outright, and that how you split the questions matters as much as which model answers them.

The test

200 synthetic support messages for a fictional invoicing SaaS: the 100 from Part 1 plus 100 new ones, 70 of them deliberately ambiguous (90 hard in total). Each message has four questions:
QuestionTypePositive labels
Which team should handle it (billing, technical, sales, account, unknown)?choice—
Is it about our product?yes/no171 of 200
Does it contain personal data?yes/no17
Should it skip the bot and go straight to a person?yes/no37
To keep the answer key independent of the Claude model I compare against, the final labels come from a different model family: OpenAI's GPT-5.6 labelled all 200 items blind against written rules. A Claude-drafted key agreed on 97–100% per question. For the 10 items where they differed, I used GPT-5.6's label. All the text is synthetic; names, emails and bank details are fictional.
The arms, on the same 200 items:
  • Decider v21, all four questions in one request (and v19 for comparison)
  • Decider v21, one question per request
  • Claude Haiku 4.5, one forced tool call answering all four. This is the fair baseline.
  • Claude Haiku 4.5, four separate calls. This is how guardrail, router and gate stacks are often built.
  • Decider first, Haiku below a confidence threshold, scored from the runs above
Decider ran on one SageMaker AI real-time endpoint on ml.g6.xlarge (NVIDIA L4) in eu-west-1. Haiku used the EU cross-Region inference profile at temperature 0. Both got the same wording for every question and team.
The SageMaker AI endpoint used for the test

Four questions for the price of one?

A four-question request to Decider looks like this:
1
2
3
4
5
6
7
8
9
10
11
body = {
"state": f"A customer sent this message to AnyCompany Invoicing support:\n\n{text}",
"questions": {
"route": {"type": "choice", "instructions": "Which team should handle this message?",
"criteria": TEAMS}, # five teams, one line each
"in_scope": {"type": "noul", "instructions": "Is this message about the AnyCompany Invoicing product?"},
"personal_data": {"type": "noul", "instructions": PERSONAL_DATA_RULES},
"needs_human": {"type": "noul", "instructions": NEEDS_HUMAN_RULES},
},
}
answers = decider(body)["answers"] # one choice with probabilities, three P(true) values
Decider's docs say asking many questions is "nearly free", because the state is encoded once and shared across questions. On my test, it wasn't:
Model time per request: one question against four
Model time, p501 question4 in one request4 separate requests
Decider v21 on ml.g6.xlarge71 ms196 ms273 ms
Claude Haiku 4.5 (as reported by Bedrock)519 ms768 ms2,149 ms
Why not nearly free? Our messages are short, and our questions aren't. Each yes/no question carries its own instructions plus about 65 tokens of template, so four questions took 572 input tokens against 236 for routing alone. With one-line wording for every question, four still took 2× as long as one (132 ms against 66 ms). The "nearly free" result holds when the state is long and the questions are short: a long document with a few quick checks, not a one-line message with detailed rules.
One request is still better than four. It's 28% faster, and it raised throughput on the L4 from 3.6 to 5.0 requests a second.

Accuracy per question

Accuracy per question
RouteIn scopePersonal dataNeeds a humanAll four right
Claude Haiku 4.5, one call94%99%99%78%73%
Claude Haiku 4.5, four calls92%95%100%71%64%
Decider v21, one request69%93%94%84%48%
Decider v19, one request69%94%94%89%52%
Decider first, Haiku below 0.694%94%95%84%70%
Three things stand out:
  1. Routing is still Decider's weak spot. Like in Part 1, it under-predicts "sales" (12 predicted against 35 labelled) and over-predicts "unknown". It's only slightly worse on the hard items (67%) than the easy ones (71%), which suggests the option descriptions are the problem, not ambiguity.
  2. On "needs a human", Decider scores higher than Haiku, but read the errors. Of the 37 messages that needed a person, Haiku flagged 35 and Decider 25. Haiku's lower score comes from over-flagging: 42 false alarms against Decider's 21. If missing an angry customer costs more than a wasted handoff, Haiku's errors are the better kind. Accuracy alone would have hidden that.
  3. Splitting questions makes the LLM worse, not just dearer. Asked one question per call, Haiku lost 9 points on all-four-right. With every question in one call, it can see the whole picture: a complaint about a charge is both "billing" and "needs a human".
Decider gave almost the same answers in one request and in four (48% all-four-right either way), and the L4 matched a run on my laptop on 199 of 200 routes. Where it runs changes speed and cost, not answers.

Escalation compounds

In Part 1, at a threshold of 0.6, 55% of requests went to Haiku. With four questions it's 76%, because a request escalates if any question is unsure:
At 0.6RouteIn scopePersonal dataNeeds a humanAny question
Share below threshold71%2%2%21%76%
Accuracy against the share of requests answered without Haiku
The yes/no questions rarely escalate; routing does. So I tried a variant I hadn't planned (treat it as exploratory): Decider answers everything, and only an unsure routing question goes to Haiku, as a route-only call that costs $1.07 per 1,000 instead of $1.77. At 0.6 that's 68.5% all-four-right, about 5 points under Haiku, at 37% lower cost than one Haiku call. It's the best cost-accuracy trade-off I found, but it still misses bar C.
1
2
3
4
5
6
answers = decider(body)["answers"]
route = answers["route"]
if route["confidence"] \< 0.6: # 71% of requests on this set
route = ask_haiku_route_only(text) # one short LLM call
decision = {"route": route["choice"],
**{q: answers[q]["noul"] \>= 0.5 for q in ("in_scope", "personal_data", "needs_human")}}

What it costs, and the calculator

Prices are eu-west-1 list prices on 7 October:
  • Claude Haiku 4.5: $1 per million input tokens, $5 per million output
  • SageMaker AI ml.g6.xlarge: $1.258 an hour
  • AgentCore Runtime Instances on g4dn.xlarge: $0.587 an hour plus the 7.8% management fee
Haiku used about 1,320 input and 90 output tokens for one four-question call.
Per 1,000 four-question requests, at 1 request a secondCost
Claude Haiku, four separate calls$4.06
Claude Haiku, one call$1.77
Decider first, Haiku when any question is unsure (76%)$1.69
Decider first, only an unsure route to Haiku (71%)$1.11
A fully used ml.g6.xlarge on its own (5 requests a second)$0.07
The whole model fits in two functions. Plug in your own volume, prices and escalation rate:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import math

def cost_per_1000(requests_per_hour, instance_per_hour, max_rps, escalation, llm_cost_per_request):
"""$ per 1,000 requests for 'decision model first, LLM when unsure' on always-on instances."""
instances = max(1, math.ceil(requests_per_hour / (max_rps * 3600)))
gpu = instances * instance_per_hour / requests_per_hour * 1000
return gpu + escalation * llm_cost_per_request * 1000

def break_even(instance_per_hour, escalation, llm_cost_per_request, escalated_cost=None):
"""Requests per hour above which the cascade beats sending everything to the LLM."""
escalated_cost = llm_cost_per_request if escalated_cost is None else escalated_cost
saving = llm_cost_per_request - escalation * escalated_cost
return math.inf if saving \<= 0 else instance_per_hour / saving

haiku_one_call = (1317 * 1.00 + 90 * 5.00) / 1e6 # $ per request
print(cost_per_1000(3600, 1.258, 5.0, 0.76, haiku_one_call)) # ≈ 1.69
print(break_even(1.258, 0.76, haiku_one_call)) # ≈ 2,970 requests/hour
print(break_even(1.258, 0.71, haiku_one_call, 0.00107)) # route-only ≈ 1,250
Break-even against one Haiku callDecider alone (48% all-four-right)Decider first, Haiku when unsure (76%)
SageMaker AI ml.g6.xlargeabout 710 requests/habout 2,970 requests/h
SageMaker AI ml.g4dn.xlargeabout 465 requests/habout 1,940 requests/h
AgentCore Instances g4dn.xlargeabout 360 requests/habout 1,490 requests/h
The T4 rows break even sooner because the instance is cheaper. They also top out sooner: Part 1 measured the T4 about 3.7× slower than the L4, so plan on roughly 1.3 four-question requests a second per T4. That's an estimate, not a measurement.
The escalation rate matters more than the GPU. Every point of escalation you remove saves about 1.8 cents per 1,000 requests at any volume; the GPU's share falls towards zero once it's busy. That's why fine-tuning on your own labels, which should make Decider confident more often, is the next test.

Against hosted decision APIs

At Decider's 570 input tokens per request (their tokenisers differ, so treat this as approximate), list prices are:
Hosted decision APIList pricePer 1,000 four-question requests
OpenAI Decisions API (public beta, 6 Oct)$0.10 per million input tokensabout $0.06
TypeSafe Jev$0.042 per million input tokensabout $0.02
I didn't measure their accuracy on this set; this is price only. At about $0.06 per 1,000, a self-hosted GPU only matches them above roughly 20,000 requests an hour, which is more than one instance can serve. If price is all you're optimising, a self-hosted decision model doesn't pay for itself against these APIs.
The reasons to run it in your own account are the ones from Part 1. For the regulated startups I work with, they're usually the deciding ones:
  • prompts and decisions stay in your AWS account and Region
  • access is controlled by IAM
  • there's no third-party processor to add to your data-protection paperwork
  • you can fine-tune on your own labels

Which should you pick?

If…Use
You make several decisions per request, under about 1,000 requests an hourOne structured Claude Haiku call. Not one call per question
You run more than about 1,500–3,000 requests an hour and data must stay in your accountDecider first, Haiku for unsure answers, on a GPU you keep busy
Routing is the hard question and the yes/no checks are easyDecider for the yes/no checks, Haiku for unsure routes only
Missing a case is expensive (a person must see it)Check recall, not accuracy. Keep the LLM on that question, or lower the threshold
Price is all that matters and a third-party API is acceptableA hosted decision API

Gotchas

  • Lock the engine. The released strands-decider (0.1.0) keeps per-request state on the engine (issue #17 ). Two overlapping requests can get each other's answers, with HTTP 200 and no error. Until a fix ships, serialise calls, and pin the commit you test:```python
    import threading
    LOCK = threading.Lock()@app.post("/invocations")
    def invocations(body: dict):
    with LOCK: # one request at a time; overlapping calls can mix up answers
    out = ENGINE.evaluate(SystemOneRequest(**body))
    return out.model_dump()
  • Set thresholds per question, not globally. One 0.6 threshold sent 71% of routes to Haiku but only 2% of the scope checks.
  • Count the LLM's tokens honestly. A structured call with four field descriptions used 1,320 input tokens, about 50% more than Part 1's two-question call.
  • AWS has an official starting point. If you're hosting Decider on SageMaker AI, there's now an aws-samples example . It serialises engine access too.

Cost and clean-up

This part cost under $5:
  • about 1.5 hours of ml.g6.xlarge
  • about 1,200 Haiku calls
  • one AWS CodeBuild image build
I created the endpoint with a small script rather than a stack and deleted it the same day, along with its IAM role.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article