<!-- generated by build_articles.py — edit content/compare/xerj-vs-elasticsearch-local.md instead -->
---
title: "XERJ vs Elasticsearch run on one machine"
canonical: "https://xerj.org/compare/xerj-vs-elasticsearch-local"
updated: "2026-08-23"
source: "content/compare/xerj-vs-elasticsearch-local.md"
---

# Is there an Elasticsearch-compatible engine that isn't Elasticsearch?

**TL;DR** — One published board measures both engines on one host: 55 wins, 26 ties, 4 losses and 3 not-applicable across 88 cells against a live Elasticsearch 8.13.4 at 100,000 documents. Every one of the 4 losses is read p99 under a write flood. XERJ is single-node only.

## Agent prompt

```text
Act as a coding agent. Read https://xerj.org/llms.txt, start one XERJ node, index a folder of logs with xerj autoindex, send the same Elasticsearch query DSL you would send to Elasticsearch 8.x, and read the four published read-under-write losses before you recommend either engine.
```

## Commands

### Command 1

Note: Start one node. There is no JVM and no container runtime on this path.

```sh
xerj --insecure --data-dir ./xerj-data
```

### Command 2

Note: The root document advertises version 8.13.0, which is the wire bridge and not a fork.

```sh
curl -s http://127.0.0.1:9200/
```

### Command 3

Note: Read a folder of mixed files directly. Elasticsearch has no equivalent command.

```sh
xerj autoindex ./logs --prefix logs --state-dir ./state-logs
```

## What the board measures, and what it does not

The capture runs an identical workload on one machine against both engines, single-node, with security off. The corpus is synthetic telemetry at 100,000 documents for the read cells. Ratios are normalized so that a value above one means XERJ was faster.

Read that as a shape on one host, not as a ranking of search engines. It is not a scale test, not a cluster test, and not a test of your data.

One of the 55 wins deserves a footnote. The kNN recall@10 cell scored 100.0% on both engines, so it is a draw that the board counts as a win. Read the board as 54 wins and 27 draws.

## The four losses, published in full

Every loss is a read p99 measured while an open-loop writer offered 40,000 docs/s to both engines. XERJ achieved 39,626 docs/s and Elasticsearch achieved 39,688 docs/s, so both sides carried the same write load.

| cell, p99 under write | XERJ | Elasticsearch | verdict |
| --- | --- | --- | --- |
| mixed `match_all` | 13.57 ms | **3.45 ms** | LOSE |
| mixed `bool` | 13.45 ms | **6.76 ms** | LOSE |
| mixed `range` | 10.27 ms | **3.68 ms** | LOSE |
| mixed `terms` | 10.74 ms | **3.57 ms** | LOSE |

The cause is documented and structural. A read that touches the live memtable waits behind the writer's per-shard lock, and XERJ is single-node only, so there is no replica to serve the read instead.

If your workload reads while a heavy writer runs, this table is the answer to your question. Elasticsearch wins that cell today.

## The second loss, which is not a latency cell

The XERJ server retains heap for every document it indexes. That is an open, tracked defect, not a tuning knob.

One lexical-mode node was observed resident at 20.2 GB part-way through a large multi-repository code corpus. Index one corpus at a time, watch the process, and restart the node between corpora. A restart with the same data directory keeps every index.

## Wire compatibility is a bridge, not a fork

`GET /` advertises version 8.13.0, and the query DSL an agent already writes lands without a translation layer. XERJ is a from-scratch Rust engine that shares no code and no architecture with Elasticsearch or Lucene.

The conformance figure is 1,366 of 1,369 ES-YAML assertions, and it carries a mandatory caveat: it is a curated 200-file subset, and `catch:` assertions in it are unverified. Some request shapes still differ on both sides. In the same capture Elasticsearch answered `match_phrase_prefix`, `combined_fields` and `_count` with a 400, and other shapes will differ the other way.

Plan a bridge, not parity. Send your real queries at a XERJ node and read the responses before you move anything.

One difference runs the other way. Elastic's subscription matrix marks Reciprocal Rank Fusion for hybrid search and the Inference API as Enterprise-tier features. XERJ fuses with Reciprocal Rank Fusion at no license tier, and it is Apache-2.0.

Read that with the disclosure it needs. The XERJ default embedder is lexical feature hashing, not neural, so fusion on the default path carries no meaning-based signal. Neural embeddings are opt-in through `--embed-mode neural`, and they are CPU-only.

## One node is the whole deployment

XERJ is single-node only. There is no data-plane replication, no failover, no shard rebalancing and no multi-region mode.

Elasticsearch is a distributed system by design, and that is the difference that decides most production questions. If a host loss must not lose the index, XERJ needs a snapshot plan and Elasticsearch already has an answer.

## What you stop running

Elasticsearch ships a bundled OpenJDK, and the documentation recommends the bundled JVM. XERJ is one static Rust binary of about 36 MB with a sub-second start, so an agent can start its own search engine as a subprocess.

The other difference is how documents arrive. Elasticsearch expects you to define mappings and push documents. Filebeat follows the log files you name and forwards them. An ingest pipeline then transforms what you already send.

Binary formats need a plugin on that side. The attachment processor reads PDF and Office files through Apache Tika. It wants base64 encoded input, and it truncates at 100,000 characters by default.

XERJ reads a folder directly:

```sh
xerj autoindex ./logs --prefix logs --state-dir ./state-logs
```

The command reads a content signature rather than the file extension. It infers field types, writes explicit mappings, and files what it learned in a catalog index. The families it covers are JSON and JSONL, CSV, structured logs, SQL exports, SQLite, PDF, DOCX, HTML, XML, YAML, plain text, code and gzip variants.

Two honest limits sit on that path. `autoindex` is CLI-only, so it must run where the files are. No HTTP endpoint makes a remote node walk a folder.

XERJ also does no optical character recognition. A page image with no text layer is junk on both engines until a separate tool gives it a text layer.

## Where the board went the other way

The wins sit in aggregations and in read latency on an idle node. Percentile aggregations and scripted metrics were the widest cells.

Index size on disk was 176.2 MB against 283.0 MB at 100,000 documents, a ratio of 1.61x. That ratio is a different measurement from the older disk figure this project retracted. It is not a better result for the same thing.

Those are one-host numbers on one corpus. They do not survive a move to a cluster, and this page does not claim they do.

## When to choose Elasticsearch instead

Choose Elasticsearch when reads must stay fast while a heavy writer runs. The four p99 losses above are the measured reason, and they are structural rather than a tuning gap.

Choose Elasticsearch when one host is not enough. XERJ is single-node only, so replication, failover and growth across machines are all reasons to stay.

Choose Elasticsearch when the corpus grows past a few million documents on one node. The server memory defect is open.

Choose it for the ecosystem: dashboards, shippers, index lifecycle management and alerting. XERJ has no alerting and no scheduler.

## When one binary is the better local answer

Choose XERJ when the job is one machine, one agent and a folder that is already on disk. The folder becomes queryable with one command and no mapping work.

Choose it when you want the Elasticsearch REST API without the runtime around it. Choose it when the agent primitives belong in the same process.

Those primitives are namespaced agent memory, an MCP server in the same binary, and a catalog an agent can read before it asks anything.

## What was not measured for this page

No head-to-head of `xerj autoindex` against a shipper pipeline was run. No OpenSearch measurement was run. No comparison at cluster size was run, and none is possible while XERJ is single-node only.

The board above is the only measured comparison here, and its four losses travel with it everywhere it is quoted.

## FAQ

### What is the published score against Elasticsearch?

55 wins, 26 ties, 4 losses and 3 not-applicable across 88 cells against a live Elasticsearch 8.13.4 at 100,000 documents on one host.

### What are the four losses?

All four are read p99 under a sustained write flood: match_all, bool, range and terms. Elasticsearch is faster in every one of them.

### Is XERJ a drop-in for Elasticsearch?

No. The wire compatibility is an adoption bridge. XERJ shares no code with Elasticsearch or Lucene, and some request shapes differ.

### Can XERJ replace an Elasticsearch cluster?

No. XERJ is single-node only, with no data-plane replication and no failover. One host is the whole deployment.

### Can I get ES query DSL without the JVM?

On the compatible surface, yes. XERJ is one static Rust binary of about 36 MB with a sub-second start, so no JVM and no container runtime is involved, and some request shapes still differ.

### I just want to search logs on my laptop. I don't want Elasticsearch in Docker.

Then run the binary on the host. Elasticsearch expects a shipper or an ingest pipeline; XERJ reads the log folder directly with xerj autoindex and needs no container runtime.

### What is the memory risk with XERJ?

The server retains heap per indexed document. One node was observed at 20.2 GB resident on a large code corpus, and that defect is open.

### When should I stay on Elasticsearch?

When you read while a heavy writer runs, when you need more than one host, or when your corpus grows past a few million documents.

## Evidence

- The published board is 55 WIN, 4 LOSE, 26 TIE and 3 N/A over 88 cells at 100,000 documents against a live Elasticsearch 8.13.4 on one host. — `demo/playbooks/SCORECARD.md`
- The four losses are the mixed read-under-write p99 cells, a known architectural gap where live-memtable reads sit behind the writer's per-shard lock. — `demo/playbooks/SCORECARD.md`
- The XERJ server retains heap per indexed document, an open tracked memory defect, and one lexical-mode node was observed resident at 20.2 GB part-way through a large multi-repository corpus. — `landing/llms.txt:217`
- An Elasticsearch index is a logical grouping of physical shards distributed across nodes, and a replica shard is a copy of a primary shard. — [https://www.elastic.co/guide/en/elasticsearch/reference/8.13/scalability.html](https://www.elastic.co/guide/en/elasticsearch/reference/8.13/scalability.html)
- Elasticsearch includes a bundled version of OpenJDK in each distribution, and the documentation states that the bundled JVM is the recommended JVM. — [https://www.elastic.co/guide/en/elasticsearch/reference/8.13/install-elasticsearch.html](https://www.elastic.co/guide/en/elasticsearch/reference/8.13/install-elasticsearch.html)
- Elastic documents the routes for getting data in as document APIs, language clients, connectors, a file uploader and Elastic Agent integrations, and Filebeat is the shipper that watches log files on a server. — [https://www.elastic.co/guide/en/beats/filebeat/8.13/filebeat-overview.html](https://www.elastic.co/guide/en/beats/filebeat/8.13/filebeat-overview.html)
- Elasticsearch extracts text from PDF and Office attachments through the ingest attachment processor, which uses Apache Tika, requires base64 encoded input and truncates at 100,000 characters by default. — [https://www.elastic.co/guide/en/elasticsearch/reference/8.13/attachment.html](https://www.elastic.co/guide/en/elasticsearch/reference/8.13/attachment.html)
- Elastic's subscription matrix marks Reciprocal Rank Fusion for hybrid search and the Inference API as Enterprise-tier features. — [https://www.elastic.co/subscriptions](https://www.elastic.co/subscriptions)

## Related

- [Is there a single-binary local search engine I can just run?](/answers/search-engine-without-docker)
- [How do I index Markdown into the Elasticsearch API?](/answers/index-markdown-into-elasticsearch-api)
- [What can I use for low-volume log search?](/answers/cheap-low-volume-log-search)
- [Migrate from Elasticsearch](/docs/recipes/migrate-from-elasticsearch)
