Guide

Why LLMs Are Bad at Big Data

Language models produce plausible text, not correct numbers. Why bigger context windows do not fix it, and the architecture that does.

Updated Aug 8, 2026 · 11 min read

I’ve spent my career in data — retail analytics, PPC, betting systems, trading algorithms. Domains where a number is not a talking point. It’s a decision, and being wrong costs something you can count.

So when people started connecting language models to warehouses, I paid attention. And what I’ve watched since is a category error playing out at scale: teams treating a system that produces plausible text as though it produces correct numbers.

Those are not the same capability. They aren’t even close. This guide is about why, and about the architecture that actually works.

The mismatch nobody names

Language models are extraordinary at a specific thing: given some context, produce the most plausible continuation. That’s the whole machine. Everything they’re good at — summarising, drafting, translating, writing code — is a variation on it.

Now look at what analytical work actually requires:

  • Exhaustiveness. A sum over four million rows must touch all four million. Not the salient ones. All of them.
  • Exactness. $4,182,993.41. Not “approximately $4.2 million,” unless you asked for that.
  • Reproducibility. The same question on Tuesday returns the same number it returned on Monday, or the number is worthless.

A plausibility engine offers none of these as guarantees. It can produce output that satisfies all three, and often does, which is precisely what makes it dangerous. It looks like it computed. It didn’t. It produced the most likely-looking answer given the shape of the question.

Most of the time the most likely-looking answer is right. That’s the trap.

Why “just use a bigger context window” fails

The instinctive fix is to feed the data in. Context windows keep growing; why not paste in the table?

Three reasons, and none of them go away with a larger window.

The economics are absurd

A modest warehouse table is hundreds of millions of rows. Even a single day’s slice of a mid-size retailer’s transactions won’t fit in any context window on offer, and if it did you’d be paying per token to re-read data that already lives in a system built to scan it for a fraction of a cent.

You’re renting the most expensive computation available to do the job a database does better, faster, and deterministically.

Retrieval is not aggregation

Long-context benchmarks mostly measure needle-in-a-haystack: hide a fact in a large document, ask the model to find it. Models are now genuinely good at this.

Analytical questions are the opposite shape. “What was our average order value by region last quarter?” has no needle. The answer depends on every row equally. Finding one fact among many and computing a statistic over all of them are different tasks, and being excellent at the first tells you nothing about the second.

This is why long-context evals can look great while your dashboard quietly returns garbage.

Attention dilutes

Even inside the window, information in the middle of a long context gets weighted less reliably than information at the edges. For prose, that’s a minor degradation. For a sum, a row that gets less attention is a row that didn’t get counted — and nothing in the output will tell you which one.

The failure mode: plausible numbers

In The Agent Reliability Handbook I argued that the thing that gets you isn’t wrong text, it’s wrong action, because wrong action is quieter. The data equivalent is worse.

A wrong number is indistinguishable from a right one. It arrives with the same formatting, the same confident tone, the same decimal places. There’s no visual tell, no jagged edge, no obviously-broken chart. It looks exactly like the truth, and it will be pasted into a board deck by someone who had no reason to doubt it.

Compare that to a broken SQL query, which throws an error, or a broken dashboard, which renders obviously wrong. Those failures announce themselves. A hallucinated aggregate does not.

And the error tends to be small, which is the cruelest part. A model that invents a wildly wrong figure gets caught immediately. A model that returns $4.1M when the answer is $4.3M passes every smell test and quietly moves a decision.

Here’s the version I keep in my head from retail: a bad data contract is asking every store for nightly sales and getting a different definition of “sale” from each one. Decisions computed on that data are brittle in ways nobody can see. Wire a model into that same ambiguity and you haven’t added intelligence — you’ve added a very fluent narrator for numbers that were already wrong.

The architecture that works

The fix is a single structural decision, and everything else follows from it:

The model writes the query. The engine computes the answer.

The language model never touches the data. It translates a question into a precise, inspectable specification — SQL, a metric call, an API request — and a deterministic system executes it. What comes back is a small, typed result the model may then describe in words.

Reasoning and computation stay separate. The model does what it’s excellent at: understanding an ambiguous question and mapping it to a formal one. The warehouse does what it’s excellent at: scanning billions of rows exactly, the same way every time.

This is the same principle as separating the plan from the permission. The model proposes; a system that cannot hallucinate disposes. When the model is wrong here, it produces a wrong query — which is reviewable, testable, and loudly wrong in a way a wrong number never is.

That shift alone eliminates most of the problem. Everything below is about making it hold up.

The semantic layer is the guardrail

Give a model raw schema access and you’ve handed it every ambiguity in your business at once.

Does revenue include tax? Are cancelled orders excluded, and from which date — order or fulfilment? Is a “customer” an account, an email, or a household? Does last quarter mean fiscal or calendar?

A human analyst learns these answers over months, mostly by getting them wrong in meetings. A model will pick the most plausible interpretation, every time, silently, and it will pick a slightly different one next Tuesday.

The answer is not a longer prompt. Definitions written into a prompt are suggestions competing with everything else in the context. They belong in a semantic layer: a governed set of metric definitions the model selects from but cannot redefine.

Give it net_revenue as a defined, tested, version-controlled metric — not permission to compose its own revenue calculation from columns. Then “what was net revenue last quarter” resolves to one query, owned by your data team, that returns the same number for the model as it does for the finance dashboard.

This is the data expression of the argument in Agents Need Contracts, Not More Brains. The contract here is the metric definition, and it does the same job: it removes the ambiguity the model would otherwise resolve by guessing.

Most teams discover they don’t have a semantic layer at the exact moment they try to point a model at their warehouse. That discovery is the real value of the exercise, and it was a problem before the model arrived.

Aggregate, don’t enumerate

Push computation down. Always.

The pattern that fails: query returns 200,000 rows, agent loads them, agent “analyses” them. You’re back to asking a plausibility engine to do arithmetic, just with extra steps and a larger bill.

The pattern that works: the query returns the answer. Twelve rows, one per month. The engine did the aggregation; the model narrates the result.

Enforce this structurally rather than hoping:

  • Row limits on every result set returned to the model, low enough to make enumeration impossible.
  • Query budgets — bytes scanned, execution time, cost per run — so an unbounded scan fails loudly instead of arriving as a surprise invoice.
  • Read-only credentials against a replica, so the worst outcome of a bad query is a slow query.
  • Required aggregation for large tables: reject a plan that selects raw rows past a threshold and make the model reformulate.

The row limit is the load-bearing one. It converts “please aggregate properly” from a request into a constraint.

Make it show its work

Every number an agent produces should arrive with the query that produced it.

Not in a debug log. Attached to the answer, visible to whoever reads it.

This changes the trust model completely. An unsourced number has to be believed or rejected on vibes. A number with its query attached can be checked — by an analyst, in seconds, at exactly the moment it matters. You’ve moved from “trust the model” to “verify the query,” and verifying a query is a thing your team already knows how to do.

It also makes the system honest about its own ambiguity. When the query shows WHERE status != 'cancelled' and the reader knows cancellations are backfilled two days late, they catch a subtlety no evaluation suite would have flagged.

Keep a run record for every question: the question asked, the metrics selected, the generated query, the row count, the execution time, and the result. Same discipline as agent run records, same payoff — you can replay any answer and get the same number, and any disputed figure becomes a five-minute investigation instead of an argument.

How you actually know it’s right

Testing a system like this is not testing a model. It’s testing a translation layer, which is far more tractable.

Golden questions

Build a suite of questions with known-correct answers, verified independently by your data team. Run it on every prompt change, model upgrade, and schema migration. This is a regression suite, and it should gate deploys like any other.

Include the awkward ones — questions with genuine ambiguity, questions spanning a fiscal boundary, questions about entities that were renamed. Those are where translation breaks.

Invariants that must reconcile

Some things are true regardless of the question. Regional revenue sums to total revenue. Segment counts sum to the customer count. Month-to-date is never greater than quarter-to-date.

Encode those as automatic checks on generated results. An answer that violates an invariant gets blocked, not returned with a caveat.

Permission to refuse

The most valuable behaviour is declining to answer.

If a question can’t be mapped onto defined metrics, the correct output is “I can’t answer that with the metrics available” — not a creative interpretation. Build that path deliberately and reward it, because the default gradient runs hard the other way. Every incentive in the model pushes toward producing something.

In betting, the discipline that separates winning from losing isn’t picking well. It’s passing on the races where you have no edge. Same discipline, same reason: the cost of a confident wrong answer is much higher than the cost of no answer.

Earning trust incrementally

Nobody should trust this system on day one, including you.

  1. Ask questions you already know the answer to. Run it beside your existing reporting and compare. Every mismatch is either a bug or an undocumented definition — both worth finding.
  2. Open it to analysts, not executives. People who can read the generated SQL and spot a wrong join. They’ll find the failure modes safely.
  3. Widen to defined metrics only. Broader audience, but restricted to the governed semantic layer.
  4. Allow exploration, still read-only, still bounded. Free-form questions against non-critical data.

Most teams start at step four because it demos beautifully. Then a number reaches a board deck, turns out to be wrong, and the project is finished — not because the technology failed, but because trust was spent before it was earned.

The checklist

  • The model generates queries; it never receives raw data to aggregate itself.
  • Metrics are defined in a governed semantic layer, not composed ad hoc from columns.
  • Every result set returned to the model is row-limited.
  • Every query runs under a byte and time budget against a read-only replica.
  • Every answer displays the query that produced it.
  • A run record is kept for every question and can be replayed to the same number.
  • A golden-question suite runs on every prompt, model, and schema change.
  • Invariant checks block results that fail to reconcile.
  • “I can’t answer that” is an implemented, tested path.
  • Rollout is staged by audience, starting with people who can read SQL.

What to do this week

Take the ten questions your team actually asks most often. Not interesting questions — the boring recurring ones that drive decisions.

For each, write down the exact definition of every term in it. What counts as a sale. Which date. Which exclusions. If your team can’t agree on all ten in one sitting, you’ve found the real project, and it isn’t an AI project. It’s the semantic layer you were always going to need.

Then point a model at those ten questions with those definitions locked, and check its SQL — not its answers. The SQL tells you whether it understood. The answers only tell you whether it was lucky.

That’s the whole discipline: make the model responsible for understanding the question, and make a deterministic system responsible for the number. Get that boundary right and these systems are genuinely useful. Get it wrong and you’ve built a very expensive, very fluent way to be confidently mistaken.