01 · START
Quickstart
Start the server, create an index, ingest some data, run a query. Sixty seconds if you already have a binary.
1 · Start the server
XERJ is a single static binary. Drop a config next to it and run:
$ xerj --config xerj.toml # dev-mode flags: $ xerj --config xerj.toml --insecure --data-dir /tmp/xerj
2 · Create an index
Indices are created explicitly with a field mapping so encoders can be chosen at write time.
$ curl -sX PUT http://localhost:8080/v1/indices/logs \
-H 'Content-Type: application/json' \
-d '{
"fields": {
"@timestamp": "date",
"service": "keyword",
"level": "keyword",
"host": "keyword",
"message": "text"
}
}'
3 · Ingest at line rate
Two ingest paths. turbo-ingest takes NDJSON and parallel-tokenizes across cores.
$ curl -sX POST http://localhost:8080/v1/indices/logs/turbo-ingest \
-H 'Content-Type: application/x-ndjson' \
--data-binary @nginx.jsonl
4 · Query
Unified search endpoint — full-text, term, range, KNN, hybrid. Everything shares one planner.
$ curl -sX POST http://localhost:8080/v1/indices/logs/search \
-H 'Content-Type: application/json' \
-d '{
"query": {
"bool": {
"filter": [
{ "term": { "level": "error" } },
{ "range": { "@timestamp": { "gte": "now-1h" } } }
]
}
},
"aggs": {
"by_service": { "terms": { "field": "service", "size": 10 } }
}
}'
5 · Scrape metrics
Prometheus text format. Scrape-friendly. No sidecar.
$ curl -s http://localhost:8080/v1/metrics | head
Source · engine/README.md · engine/crates/api/src/router.rs