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:

# Foreground mode (for debugging or supervisor units)
ixd /path/to/repo

# Detach and run in the background (native double-fork)
ixd --daemon /path/to/repo

# Stop the running daemon
ixd --stop /path/to/repo

# Watch multiple directories in one process
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

The ix service CLI provides convenient daemon control across all Unix platforms without requiring systemd:

# Start background daemon (defaults to CWD or specified path)
ix service start /path/to/repo

# Check status
ix service status /path/to/repo

# Stop running daemon
ix service stop /path/to/repo

# Restart daemon
ix service restart /path/to/repo

# (Optional on Linux) Install as a user-level systemd service
ix service install /path/to/repo

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.

Index Statistics

Show what's inside an index — file count, trigram count, on-disk size:

# Human-readable
ix stats /path/to/repo

# JSON output
ix stats --json /path/to/repo

This is distinct from ix --stats "pattern" (the search flag that shows per-query statistics). ix stats inspects the index itself.

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, 80% proportional-RSS 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.14.0-cp312-cp312-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.12Windows x86-64

moeix-0.14.0-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.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

moeix-0.14.0-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.14.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: moeix-0.14.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for moeix-0.14.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 cf676c2c0542c6e4e5928f45cfb39174acf15aac41504e37d16502e8555fbcf3
MD5 cdf14ed35f331cb1908c10a14d2fb5dd
BLAKE2b-256 1f20cb62939f861e989d64d16c7c08f7022fae0e2e8390742a4b35ec26dfe92d

See more details on using hashes here.

Provenance

The following attestation bundles were made for moeix-0.14.0-cp312-cp312-win_amd64.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.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for moeix-0.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5438d184685beb21411b89b28479ea42dcffeee1114e884dfbb921db788b6bdc
MD5 c37b99725e33033717800c8283591aa7
BLAKE2b-256 500464583a8ed5ae01d16fe49d17fee61b021511ecd4b803ef11de5d30034a96

See more details on using hashes here.

Provenance

The following attestation bundles were made for moeix-0.14.0-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.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for moeix-0.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a38ff730ae4ff2757e96793ce57692dd432c7aa4398d26e969046e5ef0daed32
MD5 4379f69f81752b70ca3c5cf2a7f485b8
BLAKE2b-256 86af216ca488652fbbaf03f22cf97d7669cb8fce0105a1a971f021990b7f8edb

See more details on using hashes here.

Provenance

The following attestation bundles were made for moeix-0.14.0-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.14.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for moeix-0.14.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 908e9925ebc2f871611feefbbdaed3f82e7515e882b5410e14842cea393fb3f0
MD5 b4f29ff27795bb3ae205f8ea279a28ed
BLAKE2b-256 4b7ccd0d39b79ca8a7e00ec163554c6bde5fcd0d71d3e1aab8d87f38948cfd38

See more details on using hashes here.

Provenance

The following attestation bundles were made for moeix-0.14.0-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

This release

0.14.0 This release

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

0.12.5

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