cd /news/artificial-intelligence/jev-speaks-binary · home › topics › artificial-intelligence › article
[ARTICLE · art-151557] src=columnar.tech ↗ pub= topic=artificial-intelligence verified=true sentiment=↑ positive

Jev speaks binary

TypeSafe released Jev 1.14 on October 14, adding experimental image support that accepts images as multipart/form-data file parts byte for byte instead of Base64-encoded JSON, which TypeSafe's docs say makes each image about a third larger. Columnar Tech's Jevaro 0.5.0 followed with support for the new features, including a Box answer type modeled as an Arrow struct or as a geoarrow.box, Arrow IPC stream input for states, and throughput of about 1,040 states per second over four HTTP/2 connections, rising to about 2,000 states per second with the rows_per_call option at 28% fewer input tokens. MotherDuck's prompt_jev() function now also works on images, making images just another column in MotherDuck.

by read6 min views1 publishedOct 16, 2026
Jev speaks binary
Image: Columnar (auto-discovered)

When we wrote What if Jev spoke Arrow? in late September, the TypeSafe API spoke only JSON, so we built Jevaro to find out what an Arrow interface to Jev would feel like. A lot has happened in the few weeks since. TypeSafe released a new version of Jev that can look at images, we released four new versions of Jevaro, and MotherDuck took on one of computer vision’s most pressing questions: hot dog or not hot dog?

One detail of TypeSafe’s release stood out to us more than the rest: to send images, the API now accepts binary data, with no Base64 encoding needed. Here’s a quick tour of what’s new, and why that detail matters for Arrow.

What’s new in Jev #

Jev 1.14, released on October 14, can look at images in a request’s state, instructions, or criteria. It also adds Box, a question type that returns the bounding box of one thing in an image, and an option for longer context. All three are experimental and opt-in: each request that uses them needs a TypeSafe-Danger-Zone-* header.

What interests us most is how the images get there. The API now accepts multipart/form-data requests: a JSON part named request, then each image as a file part, byte for byte. Images Base64-encoded in the JSON work too, but TypeSafe’s docs recommend multipart, because Base64 makes each image about a third larger.

What’s new in Jevaro #

Jevaro 0.5.0 supports all of these new features. The main point of Jevaro was to model Jev’s answers in an Arrow schema, so that each question becomes a typed column that analytic tools can use directly. Box is the first new answer type since our last post, so it needed a column type of its own:

Box
  struct<
    box: struct<
      top: float64 not null,
      bottom: float64 not null,
      left: float64 not null,
      right: float64 not null
    > not null,
    confidence: float64
  >
  metadata: {}

Each edge is a fraction of the image’s height or width, and confidence is null when TypeSafe doesn’t report one. But a box like this is also one of the most common shapes in geospatial data, and GeoArrow already defines a standard Arrow type for it. So we made that an option: with "box_format": "geoarrow", the box field is a geoarrow.box instead, and tools that understand GeoArrow can read it as a rectangle.

Answers are only half of the Arrow story, though. Our last post promised Arrow input, and Jevaro now has it, so it speaks Arrow in both directions. A multipart/form-data request has the questions in a JSON part and the states in an Arrow IPC stream, one state per row. That means a table from DuckDB, Polars, or pandas can go in, and a table of answers comes back in the same row order, ready to join to it. Images fit the same model: an Arrow binary column holds one image per row. Jevaro also accepts images the two ways TypeSafe does, Base64-encoded in JSON or as multipart file parts.

Jevaro has also gotten faster. With more calls in flight over four HTTP/2 connections, it handles about 1,040 states per second at one state per call, more than twice the rate in our last post. A new rows_per_call option packs many states into each call. That sustains about 2,000 states per second with 28% fewer input tokens, and a 10,000-state job finishes in about a second, though answers shift slightly. In a test of Box questions about 2,000 small generated PNGs, Jevaro streamed answers at 1,130 images per second.

Meanwhile, at MotherDuck 🌭 #

We’re not the only ones putting Jev’s new image support to work. MotherDuck’s prompt_jev() function now works on images, which makes images just another column in MotherDuck. In Arrow terms, that’s a binary column, the same way Jevaro accepts them. On the Food-101 dataset, Jev was the fastest and cheapest model they tested. On its own it was also the least accurate, but when they kept only answers with a confidence of 0.8 or more, about 80% of them, Jev was right 97.7% of the time.

Then they built hotdogbench.com, which asks ten models whether each of 1,000 photos shows a hot dog. Every model scored between 96.9% and 98.5%, but Jev classified 250 photos per second, five times as fast as the next fastest model. In MotherDuck’s words, “Jev isn’t the top dog, but it’s the first one to the bun.”

Jev speaks binary #

Now, back to that detail of how images reach Jev. Arrow is a binary format, and until Jev 1.14, every request to the API was JSON text. Now a request can have binary parts beside its JSON. That’s the same shape Jevaro uses for Arrow input, with the questions in a JSON part and the states in an Arrow IPC stream part.

Binary parts also mean no Base64 encoding, and in the Arrow community, we’re well-known Base64 haters. Base64 makes binary data a third larger and costs time to encode and decode. When we benchmarked the same image requests sent both ways, TypeSafe processed them equally fast, but once the network uplink was full, Base64 delivered 14–16% fewer images per second. And because the API’s 32 MiB limit counts the decompressed request body, a request can have at most 24 MiB of Base64-encoded images, even with compression. Multipart avoids all of that, and because each part has its own Content-Type, it fits right into HTTP.

One thing hasn’t changed: even with images, each request to the TypeSafe API still has just one state. So bulk jobs like hotdogbench and our Box test have to be split into many separate calls, and those calls are what limit throughput. With multipart in place, though, it’s easy to see how Arrow could fit in. An Arrow IPC part could hold all of a job’s states, and a multipart/mixed response could return the answers as an Arrow IPC stream, beside a small JSON part with usage details.

An old idea, newly fast #

Multipart isn’t new. MIME introduced it in 1992, browsers have uploaded files with it since 1995, and multipart/form-data got its current specification in 2015. But its implementations have come a long way recently. Python’s standard library has only ever offered the cgi module (removed in Python 3.13) and the email package (which “is not designed for form data or large uploads at all,” as Marcel Hellkamp, who maintains the multipart library, puts it). In his benchmark, multipart and python-multipart parse uploads at about 6 to 8 GB/s, against 91 MB/s for cgi and 61 MB/s for email. When we built Jevaro’s Arrow input, we measured python-multipart at about 30 times the speed of email. In JavaScript, fetch and FormData let any browser or Node.js program send multipart in a few lines, which is how Jevaro’s JavaScript SDK sends Arrow states and images.

What’s next #

Jev speaks binary now. We have a hunch it won’t stop there. Stay tuned.

Next steps #

── more in #artificial-intelligence 4 stories · sorted by recency
── more on @typesafe 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/jev-speaks-binary] indexed:0 read:6min 2026-10-16 · —