← All articles

v1.15: parallel indexing, live replies, fewer tokens

v1.15 is live, and it is the biggest round of work since the summer. Your Bunny reads several files at a time, answers while it is still writing, spends fewer tokens doing both, and two defects that could keep a file looping through the indexer are gone.

The BunnyQuery bunny, magnifying glass in hand

These are the changes since v1.11.0 at the end of September, in the order you are most likely to notice them.

Several files at once, and each one faster

Indexing used to take one document at a time per project, window by window, with a paid model call for every pass. That changed in four places.

  • Three documents at once. A project now indexes three of your documents at the same time, oldest first, instead of one. Twelve files no longer wait in a single line.
  • PDF pages are read in parallel from the first page. A long PDF is read in several lanes at once, sized to what your AI platform allows, from the first window instead of after it. Word, text and e-mail files get lanes too, so a long document reads several times faster than it did.
  • Text pages are read as text. A run of PDF pages that carries a text layer and no pictures is read as text, fifteen pages at a time, instead of being rendered as pictures five at a time. Pages with pictures, drawings or scans keep the vision path. That is about three times fewer passes on an ordinary born-digital PDF.
  • Spreadsheet rows go straight into the database. A 1,000-row sheet used to take more than twenty minutes, about one row a second, with a model call on every continuation pass. The rows are now stored directly, without a model call and without a token billed for them.

And a file no longer gets stuck on "indexing" when the server recycles underneath it: the window that was running is sent again and the run carries on.

Drop three thousand files

  • Bulk uploads make hundreds of requests instead of thousands. Upload links are issued a hundred files per request, the records for them are written in batches, and folder sizes are updated per batch. In our test, 3,000 small files dropped on the Files page at once were all stored in 26 minutes, none failed, and the tab stayed responsive throughout.
  • Nothing is lost quietly. An upload the storage refused is reported as a failure, and an upload that stalls gives up after two minutes instead of hanging.
  • A summary at the end reads "N stored, M indexed, F failed, D skipped as duplicates", with the failed list as a download. You can leave the page: indexing continues on the server, and a "Notify me when indexing finishes" button asks your browser once and then tells you.
  • Big drops do not fill your disk. The browser keeps at most 512 MB of resumable copies. Past that, files upload as usual without a saved copy, and the summary says so.

The same file is not uploaded twice

A new setting in Project Settings, Skip duplicate files, is on for every project. A file with the same name and size that your account already uploaded is skipped, whichever folder it sits in. The summary lists it as "already uploaded (same name and size)". A file attached in the chat that you already uploaded is not sent again either: the message uses the stored copy and the chip says "already uploaded". Turn the setting off and every file is uploaded again, as before. On the embedded widget the host page can switch it off with the skipDuplicateFiles option, and can only switch it off: the project setting is the ceiling.

Two loops, closed

The critical ones.

Scanned pages that could not be read. A page image handed to your AI platform was stored in your project's own region but could be signed as if it lived in another. Storage refused the download, the platform reported a 400, the pass failed, the window was tried three times, and the run ended in error. An app that queues a failed file again at once kept the indexer busy around the clock: one 26-page PDF was queued 564 times in ten minutes, and a 576-page manual 130 times in forty. The link is now signed for the region that holds the image, in all regions.

A file that is not what its name says. A PDF saved as report.hwp went to the HWP parser, which failed. The same window was tried three times, each with a model call, and the run closed with "The chain ended without confirming the whole file was read", which never said what the file was. The bytes are now checked against the extension before a parser is chosen and before any model call. A mismatch, or a damaged file the parser cannot open, is refused once, with a sentence that names the file and what it is:

'report.hwp' is not a Hangul (HWP) document: the file is a PDF. Rename it to .pdf and upload it again.

The indexing row shows that sentence, and a spreadsheet is checked before its rows are read, so nothing is spent on it either.

One more, smaller. When the chat lists records by a tag, the server also looks up other spellings of the tag. Indexing passes were running that lookup too, for no benefit, and waiting on it. Under the new parallel load it timed out, 2.5 seconds at a time, thirty to fifty times a second, for sixteen hours in Seoul on October 12 and 13. Indexing passes skip the lookup now, the chat keeps it, its answers are cached for half a minute, and a lookup that fails three times in a row is set aside for a minute instead of holding every request.

Replies arrive as they are written

  • Replies stream. Your Bunny's answer appears as it is written instead of landing in one piece at the end. On bunnyquery.com every piece comes over the WebSocket the moment the server relays it, so the text lands as fast as the model produces it. The embedded widget streams by default as well, reading the relayed text once a second. A host page that uses no realtime of its own can add liveStreamingRealtime: true to get the socket too.
  • Stop waiting for a reply. The "Thinking" bubble has a small x. It cancels the request on the server, so no answer is stored for it, marks your question "(cancelled)", and starts the next message you had queued. The composer is free at once. A model call that was already running finishes on its own, within about a second when it was streaming.
  • The first chat load no longer waits on your indexing history. A project with thousands of indexing passes took a minute and a half to show its first message, because the history walk read every pass on the way to the chat rows. It now reads an index: a third of a second on the same project.
  • The time under a reply is when the answer arrived, not when your browser noticed.

Fewer tokens per answer

The bill for tokens comes from your AI platform, on your own key, so this is money.

  • A shorter tool list on every step. The model re-reads the list of tools at every step of an answer. A chat turn now gets the 18 tools a chat needs, about 33 KB, where an owner's full list is 80 KB. An indexing pass gets 10 tools in 22 KB.
  • Tool results without indentation. 28% fewer tokens per result and 38% fewer pages, measured on real spreadsheet records.
  • Pages sized to the model. A long result is paged in pieces sized to the model's context window instead of a flat 10,000 characters. Reading 1,000 spreadsheet rows takes 13 round trips instead of 73.
  • Rows and plain pages cost nothing extra. Spreadsheet rows are stored without a model call, text pages are read fifteen at a time, and the text the model transcribes from a scanned page is stored once.

Answers you can check

  • Page text and exact search. Every file indexed from now on stores its page text, verbatim, page by page: the text layer where there is one, and the model's transcription of a scanned page, once. Your Bunny can search it for an exact phrase or number and answer with the page it found it on. A file indexed earlier shows no "Page text" chip on the Files page; re-index it to add the text.
  • Citations. An answer names the file and the page it came from.
  • Only from your data. The chat follows three new rules. Answer only from what the tools returned, the attached file, the project description or what you said. When the data does not have it, say so, and say what was searched. Keep what the data says apart from what was worked out from it.
  • The web is off unless you turn it on. A new switch in Project Settings, Web access for answers, is off for every project. Until you turn it on, an answer never reaches the open web. The widget takes a webAccess option, and as with the other switch the host can only restrict.
  • Default access is honoured on every path. The records your Bunny writes while indexing a file take the file's access group, the one you set under Default access, whether they are written from the dashboard, by the server-side pass or as spreadsheet rows. The last two used to write "authorized" regardless.

Stop them all

The Stop button on a file's indexing row asks before it stops, as before. The dialog now has a checkbox, "Also stop the N other files being indexed", so one confirmation stops everything in flight. And a pass the server retried on its own no longer paints the file red: it is shown as retried, and the file's status is read from the pass that counted.

New models, new defaults

  • Claude Haiku 5.5 is in the Claude list. It is Anthropic's fastest and cheapest current model, with the same 1,000,000-token window as the rest of the Claude 5 line, at a list price of $0.10 in and $0.50 out per million tokens for prompts up to 100,000 tokens. It is now the model a new Claude project starts on.
  • GPT-6.1 Sol is in the ChatGPT list, OpenAI's upgrade to GPT-6 Sol. A new ChatGPT project now starts on GPT-6 Luna, OpenAI's most efficient model.
  • Your project keeps its model. Nothing was switched for you. The window setting is now called "Input context window", and its options are named by the input room each one gives you, recomputed for the model you pick.

More news coming up!

Subscribe to the newsletter from your account profile page so you do not miss anything, and past articles are always at bunnyquery.com/articles.

That is it for this round. Enjoy your Bunny!