· 6 min read ·

JSONata's Interpreter Overhead at Scale: Breaking Down the $500k AI Rewrite

Source: hackernews

JSONata is a JSON query and transformation language designed at IBM and now embedded across enterprise integration middleware. The reference implementation is pure JavaScript, built for transforming JSON payloads in integration workflows where expressions run occasionally and correctness matters more than throughput. That context did not include processing millions of security events per day.

Reco AI’s recent post describes rewriting their JSONata-based processing pipeline using AI assistance in a single day and saving $500k per year in cloud costs. The headline earned nearly 250 upvotes on Hacker News, but the more useful story is in what made that rewrite tractable and what the savings figure actually represents.

What JSONata’s performance profile looks like at scale

The jsonata-js interpreter follows a straightforward evaluation model. Expressions are parsed into an AST, and evaluation walks that tree, resolving path navigation, filter predicates, function calls, and transformations recursively. The language is genuinely expressive: it supports closures, higher-order functions, and a standard library covering string, math, date/time, and aggregation operations. Here is a representative expression that normalizes a security event:

{
  "actor": $lowercase($.actor.email),
  "resource": $.resource.path,
  "risk_score": $sum($.findings.*.score) / $count($.findings),
  "tags": $.findings[severity = "HIGH"].rule_id
}

For a single invocation this is fine. At tens of thousands of invocations per second, interpreter overhead compounds. The JS runtime has to parse and allocate AST nodes, traverse the input document tree, and evaluate closures, all on a single thread per Node.js process. You can cache parsed expressions and you can run multiple Node.js processes, but you cannot escape the fundamental cost of interpreted evaluation at each call site.

Benchmark numbers for jsonata-js on moderately complex expressions over typical payloads land in the range of 50,000 to 200,000 evaluations per second per core, depending on expression complexity and payload size. A compiled Rust or Go implementation of the same semantics runs an order of magnitude faster in most cases. That gap is large enough that at production scale, the cloud bill difference becomes real money.

Why these conditions favored an AI-assisted port

A specific set of conditions made this job well-suited to AI assistance, and those conditions are what separate this story from generic AI productivity claims.

The first condition is a comprehensive test suite. The JSONata project maintains an extensive collection of test cases covering path navigation, array operations, function semantics, type coercion edge cases, and undefined-value handling. These tests encode the behavioral contract of the language. A port that passes them is correct to the degree the tests cover, and for JSONata that degree is reasonably high. This is fundamentally different from rewriting application logic, where the specification lives in requirements documents and institutional knowledge.

The second condition is structural coherence. jsonata-js has been maintained since 2016. The parser, evaluator, and standard library are clearly separated. An LLM asked to port this to Rust or Go can work with a coherent structure rather than disentangling accumulated side effects.

The third condition is that the translation is mostly mechanical. Rewriting an interpreter does not require architectural invention. The data structures (AST nodes, evaluation context, function registry) have direct analogs in any systems language. The genuinely tricky parts are language-specific semantic behaviors: how closures capture scope, how undefined values propagate through path expressions, how the $$ root binding resolves in nested contexts. Those behaviors are precisely what the test suite exercises.

The practical workflow for this class of rewrite is: provide source code to the model in coherent chunks, generate the port, run the test suite, feed failing cases back to the model with context, iterate. The LLM handles repetitive structural translation; the developer handles semantic edge cases the model gets wrong on the first pass. A one-day timeline is plausible under these conditions if the model gets the common evaluation path right and the remaining failures are isolated to known edge cases.

Unpacking the $500k number

Reco is a SaaS security platform that ingests and analyzes cloud and SaaS telemetry. Security data pipelines at enterprise scale process millions of events daily through normalization, enrichment, and rule-matching stages. When JSONata expressions sit in the hot path of that processing, CPU costs accumulate quickly.

$500k per year is roughly $41,600 per month in compute. On AWS, that is in the range of 50 to 100 c5.2xlarge instances running continuously, or an equivalent volume in Lambda invocations. The exact source of the savings depends on their specific architecture, but the number is consistent with a company running production-scale security analytics where a CPU-intensive interpreted step processes every event.

The comparison to the cost of the rewrite is the more striking calculation. One senior engineer spending two days on an AI-assisted port costs the company perhaps $2,000 to $3,000 in loaded engineering time. Against $500k per year in infrastructure savings, the ROI is straightforward. The more interesting question is why this kind of rewrite gets deferred at all. The answer is that before AI-assisted development, porting a library like jsonata-js might represent two to three months of careful engineering work. At that cost, the ROI math shifts enough that teams continue paying the cloud bill instead of taking on the project.

This is the real change the story illustrates. The upfront investment threshold for a “should have done this years ago” rewrite has dropped by roughly an order of magnitude for problems that fit the pattern.

What the story does not cover

A custom port of JSONata that passes the published test suite is not identical to the reference implementation. The test suite covers documented behavior, but JSONata has corner cases in its sequence semantics, its handling of singleton arrays versus scalars, and its function binding rules that surface on production data in unpredictable ways. The reference implementation has accumulated hundreds of bug fixes since 2016. A port captures a snapshot of the behavior at a point in time.

Maintainability is the ongoing cost the savings number omits. jsonata-js is actively developed. New standard library functions get added; edge case behavior changes. The 2.x release introduced async expression evaluation, which changes the execution model substantially. A custom port that diverges from upstream means the team owns the delta indefinitely. That is a reasonable trade when the expression subset in use is stable and well-characterized, but it is a real ongoing cost that belongs in the calculation alongside the $500k savings figure.

None of this invalidates the decision. Reco’s team uses a bounded subset of JSONata’s features. They know which expressions run in their pipeline. Owning a port of that specific behavior is maintainable. The point is simply that “rewrote with AI in a day” describes the initial implementation cost, not the total cost of ownership over years of production use.

What this generalizes to

The Reco story is a specific instance of a category becoming more common: AI-assisted rewrites of well-specified components where the specification is testable. Library ports, protocol implementations, codec adapters, query engines. The LLM provides leverage on mechanical translation; the test suite provides verification; the developer handles the judgment calls that require semantic understanding.

This is different from using AI to implement new features where requirements are fuzzy. It is also different from using AI to refactor application logic where correctness is contextual and partially informal. It is closer in spirit to using a compiler: you define target behavior precisely through tests, and you use a tool to generate code that satisfies those tests. The developer’s role shifts toward curating the specification and validating coverage rather than writing the implementation.

Library components that previously required months of careful porting work are now week-long projects when the test suite is solid. That shift in what a small engineering team can afford to prioritize is a genuine change in the economics of software maintenance, and JSONata’s story is one of the cleaner examples of it playing out in production.

Was this interesting?