Skip to main content

ix

crates.io docs.rs License: MIT CI

Sub-millisecond code search via sparse trigram indexing.

ix builds a compressed trigram index that is typically 2-3× the source size for pure code, and can be smaller than the source for repetitive or binary-heavy repos (measured: 0.13× on a 1 GB mixed-content repo). The compaction pipeline — delta encoding → protobuf varint → ZSTD level 3 — achieves 88% reduction vs raw u32 storage and 60% additional savings on top of varint alone. The CDX trigram table uses a B-tree page architecture (block index → ZSTD-compressed 1024-entry blocks) for sub-50μs random access into compressed data.

This eliminates the linear-scan bottleneck of traditional tools on large codebases. Target hardware floor: 2015 CPU, 8 GB RAM.

Documentation

For Read
Getting started (tutorial) docs/QUICKSTART.md
CLI flag reference ix --help
Running the daemon docs/DAEMON-RUNBOOK.md
.ixd.toml config docs/.ixd.toml.md
Socket API (tool builders) docs/SOCKET-API.md
Index delta format docs/DELTA-FORMAT.md
Performance benchmarks docs/BENCHMARKS.md
Contributing docs/CONTRIBUTING.md
Release history CHANGELOG.md
Upgrade from v0.7.x docs/v0.8.0-UPGRADE-GUIDE.md

Install

cargo install moeix

Installs two binaries:

  • ix — CLI search tool
  • ixd — background daemon (requires notify feature, enabled by default)

You only need ix for search. Install ixd if you want continuous indexing.

Quick Start

# Build the index
ix --build /path/to/repo

# Literal search
ix "fn validate"

# Regex search
ix --regex "fn\s+\w+_handler"

# Context lines around each match
ix --context 3 "TODO"

# Show query statistics
ix --stats "struct Config"

# Only matching file paths
ix --files-only "error"

# Count matches only
ix --count "TODO"

# Filter by file extension
ix --type rs --type py "fn main"

Daemon

ixd watches one or more directories for file changes and incrementally updates the index:

# Single directory
ixd /path/to/repo

# Multiple directories (v0.9+)
ixd /project-a /project-b /project-c

Each directory runs on its own thread with independent index, watcher, beacon, and Unix domain socket. Signal handling and memory monitoring are shared.

Service Management (Linux / systemd)

# Install as a user-level systemd service
ix service install /path/to/repo

# Start / stop / restart / status the service
ix service start
ix service stop
ix service restart
ix service status

The service auto-starts on login and survives reboots. See docs/DAEMON-RUNBOOK.md for full operation guide.

Daemon Socket

The daemon exposes a Unix domain socket for external consumers (editors, tooling):

$XDG_RUNTIME_DIR/ixd/{hash}.sock

Protocol is NDJSON — one JSON object per newline-terminated line. See docs/SOCKET-API.md. The ix CLI reads the index file directly, not through the socket.

Configuring the Daemon

Scope what ixd watches and ix --build indexes with .ixd.toml:

# .ixd.toml
watch_roots = ["src", "lib"]
exclude_patterns = [".git", "node_modules", "target", "vendor"]

See docs/.ixd.toml.md for full schema and examples.

How It Works

  1. Extractix --build walks the directory, extracts byte-level trigrams (skipping null bytes to nullify binary noise), and caps at 64 offset samples per trigram for files >1 MB.
  2. Accumulate — Trigrams are grouped into posting lists (one per unique trigram). An external sort with 500K-entry flush threshold keeps RAM constant regardless of repository size.
  3. Compress — Posting lists and the trigram table use the same pipeline: delta-encode adjacent file IDs and offsets → protobuf varint → ZSTD level 3. The CDX trigram table is organized as a B-tree: a 12-byte-per-1024-entry block index for O(log N) lookup, then decompress one ~5 KB block to find the target.
  4. Plan — On search, the query is decomposed into trigrams. The block index finds the target block, one ZSTD call decompresses it, and a linear scan finds the posting list offset.
  5. Verify — Candidates are filtered through per-file bloom filters (256 B, 0.7% false-positive rate), then streamed through a regex matcher with constant memory usage.

Compaction Pipeline (measured)

Raw u32 entries  →  delta-encode  →  varint  →  ZSTD level 3
  10.6 MB             2-3× smaller     60% more     88% total reduction
                                                      (1.3 MB final)
Stage What it catches Typical savings
Null-byte skip Binary files (30-80% null bytes) near-zero trigram cost
Offset sampling Repeated patterns in large files 64 offsets max per trigram
Delta encoding Sequential file IDs, clustered offsets 2-3× vs raw u32
Protobuf varint Small values fit in 1 byte (<128) dense trigrams stay compact
ZSTD level 3 Byte-pattern redundancy in varint runs 60% on top of varint

Index Format (v1.3)

All integers little-endian, offsets absolute from file start, 8-byte aligned.

Section Size (example, 70 files) Description
Header 256 B magic IX01, version, flags, CRC, section offsets
File table 3.4 KB 48 B per file: path offset, content hash, size, mtime
Posting lists 1,332 KB (90.1%) Per-trigram file entries: delta+varint+ZSTD
CDX trigram table 122 KB (8.3%) 4.9 B/trigram (75% vs naive 20 B)
CDX block index 312 B (0.02%) 12 B per 1024-entry block, O(log N) binary search
Bloom filters 18 KB (1.2%) 256 B per file, 5 hashes, 0.7% FPR
String pool 1.9 KB Interned file paths

CDX compression is always-on since v1.3. Not backward compatible with v1.1/v1.2 — rebuild indexes after upgrading:

rm -rf .ix/
ix --build .

Performance

Measured on a 2015-era CPU (Haswell equivalent), 8 GB RAM. All ratios verified from actual indexes.

Workload Source Index Ratio
Source code (70 files) 576 KB 1,477 KB 2.56×
Mixed-content repo (426 files) 1,069 MB 138 MB 0.13×
Metric Value Notes
Posting data vs raw u32 88% reduction 10.6 MB → 1.3 MB
ZSTD on varint buffer 60% savings varint 3.3 MB → zstd 1.3 MB
CDX trigram table vs naive 75% smaller 4.9 B vs 20 B per entry
Block index overhead 0.02% of index 12 B per 1024 trigrams
CDX lookup latency <50 μs block index search + 1 ZSTD call
Build RAM peak <8 MB HashMap flushes at 500K entries
Safety ceiling 60% RAM ResourceGuard (llmosafe), 80% fallback
Cold start <3 s From disk to first result
Selective query (10% match) 40 ms 10× fewer files than ripgrep

ix wins when the trigram index eliminates most files from scanning. On small repos or queries where every file matches, linear-scan tools like ripgrep are faster.

Feature Flags

Flag Default Description
notify yes File watcher + daemon (ixd)
decompress no gz/zst/bz2/xz decompression
archive no zip/tar archive support
full no All optional features

Library

ix is also a library (moeix on crates.io, ix as the crate name):

[dependencies]
moeix = "0.12"
use ix::reader::Reader;
use ix::executor::{Executor, QueryOptions};
use ix::planner::Planner;

let reader = Reader::open(".ix/shard.ix")?;
let plan = Planner::plan("struct Config", false);
let mut executor = Executor::new(&reader);
let (matches, stats) = executor.execute(&plan, &QueryOptions::default())?;

See docs.rs/moeix for the full API reference.

Building

cargo build --all-features
cargo test --all-features
cargo clippy --all-features -- -D warnings

Requires Rust 1.85+.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

moeix-0.12.5-cp312-cp312-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.12Windows x86-64

moeix-0.12.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

moeix-0.12.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

moeix-0.12.5-cp312-cp312-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file moeix-0.12.5-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: moeix-0.12.5-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for moeix-0.12.5-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 832b390075828361c2d4d2322d303ace5fe07389d9c5600353a6f7a435831c87
MD5 c3b56a9d0616923775c1aea1280b84a6
BLAKE2b-256 fc371171acac21787465fa01430b0c85fe4c17f9b27f715fa82613c8dcee89a7

See more details on using hashes here.

File details

Details for the file moeix-0.12.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for moeix-0.12.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a7dc515ab9dd2285f33e49349dafa12489ca2f1e64f09cc03cd062ca943aec9d
MD5 66d13f8fa0483e05f23367f9a6cdca7e
BLAKE2b-256 03d21bdacffc99fe2feb64c341f069c8c09db67cf16bb5d22014fea640f4fcd4

See more details on using hashes here.

Provenance

The following attestation bundles were made for moeix-0.12.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on moeshawky/ix

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moeix-0.12.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for moeix-0.12.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 82e95588a25666ceaf350fcaa24dd1dfb3f46f9d0c3dc6d1970401169a696f3a
MD5 cbe0d726792a7bf4c44ba1d38ab2f207
BLAKE2b-256 e48d49e54400f39dfc13a27c4b82d46a5ca653efa23a8c874ce9bdfc47db1037

See more details on using hashes here.

Provenance

The following attestation bundles were made for moeix-0.12.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: wheels.yml on moeshawky/ix

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file moeix-0.12.5-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for moeix-0.12.5-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e27504a2e2dc7fe44325889453c013e9c244b04342b3476593a1bf911f8b6296
MD5 56127f6f3ef0e6458c2221acf937cd05
BLAKE2b-256 7bec10e12e225796fe818efa6d69ed149f108b33874268ca8cc878fdccb6837e

See more details on using hashes here.

Provenance

The following attestation bundles were made for moeix-0.12.5-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: wheels.yml on moeshawky/ix

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.14.1

3 files

0.14.0

4 files

0.13.4

3 files

0.13.3

3 files

0.13.2

3 files

0.13.1

3 files

0.13.0

4 files

0.12.9

4 files

0.12.8

1 file

0.12.7

1 file

0.12.6

2 files

This release

0.12.5 This release

4 files

0.12.4

2 files

0.12.3

1 file

0.12.1

2 files

0.12.0

1 file

0.11.9

2 files

0.11.8

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page