Skip to content
v0.6.1

Changelog

0.6.1 (2026-10-25)

Bug fixes

  • Finish creating or deleting an index when storage answers the registry write with a server error (99aaeae)
  • Give up index claims before they lapse when the leadership table cannot be renewed (73cf782)
  • Keep acknowledged documents when an index closes on an interrupted thread (8dc9509)
  • Keep manifest and leadership fields from newer versions during a rolling upgrade (ad8c8d3)
  • Keep pulls working when a push lands in storage but its local manifest write fails (8938a53)
  • Retry the push of a handover flush that failed and was called off (a8faa4c)
  • Stop a failed index create from removing an index another node created under the same name (1d16164)
  • Stop a failed ownership notice from handing an index over without pushing it (ddfcecb)
  • Stop another node taking an index while the shutdown flush is still pushing it (3c971ae)
  • Stop losing writes that arrive while an evicted index pushes its last commit (ec2232b)
  • Stop reporting a conflict after a push whose manifest write landed without an answer (9e29488)
  • Stop two processes with the same node ID from writing the same index (d03c054)

0.6.0 (2026-10-04)

Features

  • Allow fallback fields when sorting (2a8fcd8)

Bug fixes

  • Answer 400 instead of 500 for a distance-sort cursor that holds no distance (e9138a9)
  • Answer 400 instead of 500 for a key expiry later than a key can store (31afff2)
  • Answer 400 instead of 500 when a string value is too long to index (7035e66)
  • Answer 400 instead of 500 when a text or boolean field gets the wrong JSON type (a08deca)
  • Answer 404 instead of restoring search settings deleted during a PUT with If-Match: * (b086567)
  • Answer index:unsupported instead of a 400 when the live generation needs a newer engine (bc80dca)
  • Close an index that was still opening when it was deleted (9a8d4e0)
  • Continue paging when a cursor comes from a larger index instead of answering 500 (b436821)
  • Count requests that match no route as UNKNOWN instead of by their path (209933a)
  • Delete an index created on another node without a false 404 (fb5e3e0)
  • Keep a recreated index’s objects when an old removal sweep runs at the same time (3499ef1)
  • Keep acknowledged writes when an index is handed over after a failed push (1497bc9)
  • Keep indexes readable when two nodes push after the manifest was removed (2fcd6ef)
  • Keep keys and permissions from newer versions when an older node changes the keys (54b92fd)
  • Keep pulling an index after a pull fails with an unexpected error (c6130a5)
  • Keep ranking from using a signal that an update removed (8c8f7ff)
  • Keep the index tie breaker when a fallback sort starts on the same field (25e681b)
  • Keep the removal mark of an index deleted while another node creates it (8301b59)
  • Keep writes a node takes during a quick lose-and-regain of an index (d27cca6)
  • Refuse a cursor sent with another locale instead of skipping or repeating hits (8866fe9)
  • Refuse a JSON body that holds more than one value (3f17008)
  • Refuse a primary key of the wrong JSON type (36eab99)
  • Refuse a request that gives the same JSON property twice instead of keeping the last value (84e8283)
  • Refuse a zero knn vector on a cosine field instead of scoring every hit NaN (e5004c0)
  • Refuse an unencoded ; in request paths (4d3f85b)
  • Refuse definition changes that move a field name onto a wildcard field that indexes it differently (a315000)
  • Refuse definition changes that would block every later write of an indexed field (9bb85a2)
  • Refuse key index patterns that no index name can match (f033ee6)
  • Refuse to promote or delete a generation of an index that needs a newer engine (5dc8b99)
  • Report removed field locales as an incompatible definition change (0c02be8)
  • Restore the remote definition and change log when a pull follows a refused push (c3c666f)
  • Skip an NDJSON line that is valid JSON but not an object instead of failing the batch (895ab1e)
  • Stop a concurrent partial update from bringing back documents a delete by query removed (a9f4cc7)
  • Stop a freshness wait from timing out when the index is promoted mid-wait (13d90c2)
  • Stop a key granted one generation from cancelling the reindex of another (e91a293)
  • Stop a late key refresh from bringing a revoked key back (5bcf276)
  • Stop a node that lost an index from keeping the documents it gave up (d7e8e8a)
  • Stop a promoted reindex from keeping signals the source index removed (b1017c7)
  • Stop answering with old search settings after a revert or a second removal (3375425)
  • Stop deeply nested definitions from turning empty after the index reopens (c6582b6)
  • Stop deleting newer indexes after you restore an older registry in local mode (f39a138)
  • Stop keys granted only an index’s generations from changing its search settings (c238a88)
  • Stop locale patches from leaving stale values in the default locale (ff0d713)
  • Stop pushing a handed-over index when its claim is taken during the handover (de40f93)
  • Stop readers from serving a deleted index after it is created again under the same name (4face53)
  • Stop reads from answering from a demoted generation after a roll back (a15fdf5)
  • Stop the refresh pass from removing an index created while it ran (0179b1d)
  • Treat -0.0 as 0.0 in float and double fields so filters and facets agree at zero (702d783)
  • Warn when EXOFIND_NODE_ADDRESS has no scheme or an invalid host name (30ecc6e)

0.5.0 (2026-09-15)

Features

  • Allow large chunked streaming to batch endpoints (5384ed7)
  • Index a single document by its key (a9ab104)
  • Look up one document by its key over the API (0029295)
  • Support for freshness tokens to be able to request up to date searches (17e3474)
  • Unify and document change path selection for documents and index settings (85dfd8d)

0.4.1 (2026-09-13)

Bug fixes

  • Ensure that a node does not break during start up while generating OpenAPI docs (3d5d827)

0.4.0 (2026-09-13)

Features

  • Allow keys to be rotated and protect against accidental removals of last key (5a850df)
  • Answer 304 when a GET carries an ETag and the resource is unchanged (3517e54)
  • Answer every failed request with a standard JSON error body (96bb3f3)
  • Filter and page the index, key and reindex listings (a9b9080)
  • Generate real query and field types in OpenAPI clients (6104987)
  • Improve batch indexing error handling and allow skipping docs with errors (f626075)
  • Introduce shared cache settings for the entire node (983b10a)
  • Let a deployment cap how many facet values and suggestions a request may ask for (012c483)
  • Measure facet value and explain requests (dcedc22)
  • Normalize error codes for numeric ranges (7d9f1e7)
  • Publish a named Interpret union in the OpenAPI document (7f8acf7)
  • Read and cancel a reindex job under /admin/reindexes (00ff93d)
  • Reindex jobs are now identifiable and carry more metadata (e9bbf70)
  • Rename every error code by family, request part and defect (fd4cb1a)
  • Rename index:not-found to index:not_found (045382b)
  • Rename some request:update errors to index:update (67774a4)
  • Rename the live generation liveGeneration when listing indexes (493d02f)
  • Report enums in the REST API as lowercase (2c1ac3c)
  • Report every error path in the REST API using dotted form (4af6fd5)
  • Report which index generation answered a search (51663ce)
  • Require all parameter to delete all documents (21d1e36)
  • Require indexes.promote permission when auto-promoting reindex (eeb47ec)
  • Return missing primary keys as text (561faac)
  • Return the index with its ETag from commit and pull (068f6cb)
  • Stronger If-Match application in the REST API (3be9a94)
  • Support for ranking signals with non-indexing updates (402b301)

Bug fixes

  • Accept a document key written as another JSON type in a PATCH body (4a6e2f4)
  • Answer index:not_found when trying to reindex a non-existent index (1980fbe)
  • Avoid sending back empty tieBreakers for rankings (53c6755)
  • Cancel a queued reindex without a 15 second wait (b062e1a)
  • Count the clauses of interpret targets against the search clause caps (a68d202)
  • Ignore paging, sort and rescore in explain instead of validating them (8c89ca4)
  • Index documents forwarded over HTTP/2 instead of reporting zero indexed (6933dbc)
  • Keep a closing index copy from overwriting files (64051b3)
  • Keep a registry repair from undoing a delete that lands while it runs (993f066)
  • Keep a rescored search from paging into an empty page (33328ae)
  • Keep a slow registry read from hiding an index another thread just created (1036215)
  • Keep attempting to push indexes if a push fails (830c102)
  • Keep registry entries a newer node wrote when an older node changes it (87ff74e)
  • Keep the definition and change log intact when a node stops mid-write (7ce5358)
  • Mark storage as removed when a delete cannot clear a local copy (6cf9dbf)
  • Refuse a boost weight of NaN or Infinity instead of scoring with it (3204515)
  • Report NDJSON document errors without a documents prefix (f314c49)
  • REST API now answers more calls with 4xx instead of 500 (2f9aad7)
  • Return 400 for an invalid after parameter when reading documents (b4edb2e)
  • Stop a refused reindex from leaving an empty generation behind (b2f2008)
  • Stop omitting score from a search ranked by signals or a second pass (9812afd)
  • Tell apart an empty matched and a blank field name, and point highlight errors at the field (9a44f8b)

Performance

  • Cache typo and prefix matches on small segments too (ffba8f2)
  • Reuse prefix automata across fields and requests (fe3257e)
  • Speed up long and typo tolerant searches by reusing term lookups (1facf2d)

0.3.0 (2026-09-10)

Features

  • Keep replaced index files in the bucket for a grace period before deleting them (7e361b4)
  • Sweep orphaned objects from an open index on a timer (c29cce1)
  • User queries can now match any of the words instead of all words (d4e5806)

Bug fixes

  • A failover no longer loses recently written documents (c003f23)
  • A lost index registry no longer deletes the indexes on a node (ae3d9b6)
  • A push conflict no longer loses the documents written around it (4569113)
  • Handle stale generations in Google Cloud Storage without getting stuck (7069e87)
  • Keep writes made during a reindex instead of dropping them at the promote (b2c43b6)
  • Pulled files that do not match the manifest are rejected instead of used (a602fe8)
  • Recreating a deleted index no longer brings the old documents back (3f6a698)
  • Stop a definition update from emptying an index when taking over indexing for it (37f04a8)
  • Stop a failed push from handing an index over without its writes (efda453)
  • Stop a rejoining node from deleting an index from storage (6eef1f7)
  • Vanished manifests no longer makes readers drop their index files (f3ecdf6)

Documentation

  • Add cross-links and related sections for new pages (50eec3a)
  • Add search powered by project to website (b2aaab3)
  • Add storage layout, glossary, write guarantees, testing and ranking pages (6018451)
  • Improve example copy and relevance (38002ea)
  • Limit snippets in the website search (233e2ac)
  • Loading states for examples (a0a1593)
  • Reset scroll when typing into the website search (3a1fd6e)
  • Stop the loading bar sticking after pressing Back from a demo (66230b8)

0.2.0 (2026-09-06)

Features

  • Improve Google Cloud Storage support (6b2a4d8)
  • Support for AWS and file credentials for object storage (8adbea1)

Bug fixes

  • Report work a shutdown interrupts as stopped instead of a warning (3f8a8b4)

Documentation

  • Add in missing space before email (56294d0)
  • Add info about who’s behind the project on the website (9861540)

0.1.0 (2026-09-06)

Features

  • Ability to add query-time synonyms per index (c395813)
  • Ability to limit the complexity of searches (8da8afb)
  • Ability to list indexed documents (937345b)
  • Ability to rebuild a lost or corrupt index registry (b32053a)
  • Ability to request which nested objects matched a query (69d96ae)
  • Ability to return each matched nested object as a hit of its own (b4aebfc)
  • Ability to set a role on a field to simplify setup (ec2baae)
  • Accept dynamic attribute names inside and for object fields (2fed904)
  • Add benchmark utility (31d195d)
  • Add Gujarati, Kannada, Malayalam, Marathi, Odia and Punjabi as supported locales (729e034)
  • Add health check endpoints (b1cdd3b)
  • Add locale support for Central Kurdish, Nepali and Chinese (Traditional) (d66dab0)
  • Add Malay, Croatian and Bosnian as supported locales (da58cf6)
  • Add Slovak and Slovenian as supported locales (bdde702)
  • Add Urdu as a supported locale (4e8971b)
  • Add Vietnamese as a supported locale (18f68c6)
  • Allow disabling typo-tolerance for certain words (eda49ea)
  • Allow nested objects to specify their key (562e53f)
  • Allow objects to store, highlight and nest further down (6cd000e)
  • Allow ranking signals on requests to compose with the index (d7f1764)
  • Answer exact totals of value hits from index statistics (461b7e3)
  • Answer locale specific fields in the locale the search asked for (3a6e488)
  • Answer repeated facets from a cache and improve count refresh (be71979)
  • Balance indexes between nodes based on write load (8f6c855)
  • Cache the documents of search results in memory, (f75460d)
  • Change nested documents without having to send them all (d7423cc)
  • Change one document with PATCH (cb25ba3)
  • Change only some settings with PATCH (6297850)
  • Check for malformed sha256 root key at startup (2c6d2bb)
  • Combine text and vector rankings by rank with a fuse clause (ce32a59)
  • Count all facets in one sweep instead of one-by-one (34c41e9)
  • Count object-field facets without collecting the matched values (042fe0e)
  • Count value hits straight off their own conditions (b6bffaa)
  • Count wide facet scopes a value at a time (0f82564)
  • Custom document serializing to reduce memory needed to write them (76327e9)
  • Cut allocations when counting facets over object fields (264f850)
  • Declare an index’s locales once instead of on every field (b85b028)
  • Endpoint to explain how a hit scored (7812481)
  • Export metrics surrounding node and index health (e469cd6)
  • Fill a new generation by reindexing from the one it replaces (52febbd)
  • Filter inside nested objects without emptying their own facets (2d698b7)
  • Forward index writes to the correct indexer (ccc7ea1)
  • Hierarchy facets allocate less by reusing parsed paths per segment (22ae8ef)
  • Highlight a page of hits with one term lookup per segment (cb64d23)
  • Improve facet performance with batched counting and bitset collection (cb2be5f)
  • Improve hierarchy facet speed via caching (2c67e39)
  • Improve index and setting refresh timings (efad724)
  • Improve JVM defaults when running in Docker (81e8af0)
  • Improve logging of startup, indexing etc (940bae2)
  • Improve query speed based on benchmark numbers (8208cb1)
  • Improve query speed when using ranking signals (8009dd7)
  • Improve sort and facet performance for number fields (1781412)
  • Improve speed of cold typo searches (7ec0d9c)
  • Improve speed of searches that ask for highlights (da7478a)
  • Improve speed of sorting on distance (b918882)
  • Include decimals in tookMs (c03614d)
  • Indexer nodes now spread writes to indexes between them (d9bcf7a)
  • Initial commit (3b3071f)
  • Introduce nested vs flattened object representations (20090ae)
  • Korean support for compound nouns (1cf9916)
  • Let each document control if nested objects are surfaced in its place (fafce10)
  • Let ranking be tuned per index without updating it (136ed4f)
  • Metrics for how long indexes take to open (98e4fe0)
  • OpenAPI documentation (4e3b12f)
  • Order facet values as declared and label them per locale (84eae2c)
  • Parse field values from query (59b82cb)
  • Parse numbers in query strings into queries (d9786a4)
  • Poll S3 less by utilizing the registry to carry update hints (fac537b)
  • Prefix every environment variable with EXOFIND_ (694816a)
  • Preload and warm facets when an index opens (8dacf08)
  • Prepare an index for writing as soon as a node takes it over (5047ba7)
  • Push an index in its merged form after writing stops (4f6695d)
  • Read flat per-segment columns instead of doc values for facets (2d4b1c1)
  • Record which documents change so a rebuild copy can be caught up (633b0b0)
  • Record which reindex jobs are active to reduce S3 use (650a78b)
  • Refuse searches asking for fields the index can never return (2c4f6c2)
  • Reject dots in field names in favor of explicit objects (82df057)
  • Remove deleted indexes from object storage after a grace period (5e2988d)
  • Reopen the indexes a node served before it restarted (650b8a6)
  • Rerank the best results in a second pass (6dc56b0)
  • Return single fields from inside objects in search results (adff0b9)
  • Rework locale data and support for Icelandic (a5d753e)
  • Score text searches through dense norms instead of a sparse lookup (8d1949d)
  • Search a document’s chunks by vector with knn inside a nested object (6da5f80)
  • Search using multiple threads (1462daf)
  • Searches no longer wait on a shared lock on the index (32aada5)
  • Searches with typo tolerance ignore number typos (8e41a08)
  • Speed up and reduce memory used when decoding source fields (eabe5d7)
  • Speed up facets when only their own filter, or nothing, narrows the search (a13ed61)
  • Speed up multi-word text search on fields that support autocomplete (51bf060)
  • Speed up searches by disabling disjunction query tie-breaking (2bb0ed8)
  • Speed up searches that repeat a misspelled or half-typed word (ee432c6)
  • Speed up typo tolerant queries (77ef291)
  • Speed up typo-tolerant search by walking each misreading less times (4e63300)
  • Split Finnish compound words (d44290f)
  • Spread the first orphan sweep of each index after a node restart (f17b8d7)
  • Stop recounting facets when promoting sub-documents to hits (e516aff)
  • Stop recounting whole-index object-field facets on every search (9d49155)
  • Support for searching facet values by prefix (d9e3f7f)
  • Support suggesting queries (cd25a1c)
  • Switch highlights to use postings (683f744)
  • The admin API now shows which node writes each index (9c89c69)
  • When editing an index definition check compatibility before allowing (0405cca)

Bug fixes

  • Adjust config names so that ENV-vars can reach them (49a2489)
  • Create an index without it sometimes failing as readonly (46f4d3d)
  • Documents accepted just before a shutdown survive a fast takeover by another node (4c40e98)
  • Enable fsync of manifest and index files (d8df834)
  • examples: Make sure the livsmedel example no longer renders [object Object] (3c23882)
  • Keep index data when a node stops while a reindex copies (7dc85a4)
  • Keep one slow index from delaying the failover of others (b05ed8d)
  • Keep writing indexes when S3 reports a conditional write conflict (ad4c925)
  • Reject malformed Authorization headers (f5cbea4)
  • Stop a node whose claim lapsed from overwriting its successor’s work (207ed73)
  • Stop a reindex from promoting after the index moves to another node (f9d8406)
  • Stop reporting a failure for a registry change that was made (4fe8dbb)
  • Upload every file again when the remote index was emptied (d19d2e4)

Documentation

  • Add aside about locale data in the configuration section (352282e)
  • Add cross-links to how-to guides (9220d7d)
  • Add Discogs example to show off sub-documents (0611242)
  • Add examples to REST API (5b11189)
  • Add llms.txt and Markdown versions of website (45705dd)
  • Add more documentation (8bcf0f6)
  • Add number and field parsing to Discogs demo (4d92244)
  • Add OpenGraph images (a0aabf1)
  • Add some tentative deploy docs for Kubernetes (d271ed6)
  • Clear filters when sample queries are pressed (b3637fa)
  • Document how merged files are handled in the object storage bucket (b1cef52)
  • Document some traps surrounding benchmarks (95ab7e8)
  • Document that /q/metrics does not use authorization (2bf74f3)
  • Document that EXOFIND_NODE_ADDRESS should be private or use https (f9302de)
  • Fix example intros (691d2ec)
  • Fold facets on smaller screen sizes (5a41150)
  • Give proto files a documentation pass (52f7c13)
  • How to for modelling dynamic attributes (e0e7cff)
  • Improve frontpage copy and add links (b203359)
  • Improve page transitions on website (a1e1844)
  • Improve synonym docs (c5c2ec5)
  • License under Apache 2.0 (949e22f)
  • Move documentation site to exofind.dev (c06873a)
  • Normalize names of pages (d4f3590)
  • REST API section for website (8594b63)
  • Reveal sidebar entries as website is navigated (7f235c6)
  • Rework docs in an attempt to make them clearer (7b4ed67)
  • Rework website theme (e1b406b)
  • Rewrite the OpenAPI descriptions (2fe3bfd)
  • Stop the page blanking when moving between documentation pages (f4cf27a)
  • Update CLAUDE.md (d563de7)
  • Update deployment shapes explanation with some more details (a3573fe)
  • Update documentation skill (2e4f8b8)
  • Update documentation skill (06f287b)
  • Update documentation skill slightly (6edb000)
  • Update explanation doc for index generations (4e460d0)
  • Update website and tutorials (ec99cf8)
  • Update website navigation (91c2d2c)
  • Upgrade Astro and Starlight (c79dbde)
  • Use bossa nova instead of gatefold as example query in Discogs demo (cfd5d8e)
  • Website built from documentation and examples (93cb06f)

Internal

  • Add CI and publish images to GHCR (054341b)

Exofind is built by Level Four AB and is available under the Apache License 2.0.