ig vs RTK -- Head to Head
115 cases across 12 domains, run on the iautos SaaS monorepo (347,843 files raw, 3,146 after ig's default excludes).
2 warm-up passes + median of 3 wall-time runs per case. ig 1.10.0 against rtk 0.37.2. Bytes measured with wc -c.
The Verdict
First release where ig beats rtk on aggregate bytes and aggregate wall time simultaneously.
The two new v1.10.0 capabilities (--top N BM25, --semantic PMI) account for 15 of ig's 57 bytes wins — they are structural advantages rtk cannot close without building its own persistent index.
Totals -- 115 cases
| ig 1.10.0 | rtk 0.37.2 | |
|---|---|---|
| Total bytes emitted | 896 KB | 1.04 MB |
| Total wall time | 1.74 s | 2.88 s |
| Bytes wins (tie: 4) | 57 / 115 | 54 / 115 |
| Time wins (tie: 8) | 80 / 115 | 27 / 115 |
Raw CSV + markdown report: results.csv, summary.md, per-domain.md.
Per-Domain Breakdown
| # | Domain | ig B wins | rtk B wins | ig T wins | rtk T wins |
|---|---|---|---|---|---|
| 1 | literal search | 5 | 5 | 9 | 1 |
| 2 | regex search | 3 | 7 | 6 | 4 |
| 3 | flag variants | 7 | 3 | 9 | 1 |
| 4 | listing | 2 | 8 | 7 | 3 |
| 5 | read full | 0 | 10 | 8 | 0 |
| 6 | read signatures | 9 | 1 | 10 | 0 |
| 7 | git proxy | 7 | 2 | 8 | 0 |
| 8 | varied identifiers | 3 | 4 | 10 | 0 |
| 9 | smart summaries | 4 | 6 | 0 | 10 |
| 10 | generic proxy | 2 | 8 | 4 | 3 |
| 11 | --top BM25 moat | 10 | 0 | 7 | 3 |
| 12 | --semantic PMI moat | 5 | 0 | 2 | 2 |
The Index Moat
rtk is a generic output-compression proxy: it shells to rg, git, find... and compresses their output.
ig is a search engine with a persistent index — which unlocks capabilities rtk cannot match without completely redesigning itself.
--top N (BM25 ranking)
Score each matched file by Okapi BM25 and return only the top N. rtk has no tf / df / avdl so it cannot rank — it can only cap flat output length.
ig --top 10 "export default" → 743 B rtk grep "export default" → 19 403 B (96% more)
--semantic (PMI expansion)
Synonyms learned from the corpus at index time (count-weighted PPMI), zero ML model. rtk has no co-occurrence store; there's nothing to expand against.
ig --semantic --top 5 throw → got, inattendu, denied, autorisé, trouvée, manquant → 3 368 B rtk grep throw → 17 717 B
Where rtk Still Wins -- and Why It's a Trade-off
- Read full (10/10 bytes to rtk). ig keeps the
42: contentline-number prefix because it's what lets the Edit tool round-trip precisely. Dropping it saves ~15% bytes per file and halves the utility. Deliberate trade-off, not a gap. - Listing singles (8/10 bytes). rtk's
rtk lsemits a placeholder 8 B for top-level dirs. Fewer bytes, less information; ig emits a compact listing that's still actionable. - Smart per-file (6/4 bytes). Byte difference is 50-150 B per case — noise-level. In aggregate, ig's dir-aggregate mode is already 200× smaller than the legacy per-file walk (see cli docs).
Feature Comparison
| Feature | ig | rtk |
|---|---|---|
| BM25 --top N ranking moat | v1.10.0 | No (no index) |
| --semantic PMI query expansion moat | v1.10.0 | No (no index) |
| Auto-compact on pipe | v1.10.0 | Always |
| Path ellision in compact headers | v1.10.0 | No |
| Dir-aggregate smart summaries | v1.10.0 | No |
| Trigram-indexed search moat | Yes | No (wraps rg) |
| Sub-ms Unix-socket daemon moat | Yes | No |
| IDF-weighted sparse n-grams moat | Yes | No |
| Bloom + locMask (3.5-gram) moat | Yes | No |
| Pre-computed filedata cache moat | Yes | No |
| Budget mode (entropy-scored) moat | Yes | No |
| Relevance boost (-r) moat | Yes | No |
| Delta reads (git changes) moat | Yes | No |
| Token savings dashboard | ig gain (top-20 default) | rtk gain |
| Git output compression | Yes | Yes |
| ls / tree compression | Yes | Yes |
| File reading modes moat | 4 modes | 3 modes |
| Pipelines in rewrite | Yes | Yes |
| Env / sudo prefix stripping | Yes | Yes |
| Absolute path normalisation | Yes | Yes |
| Git global opts (-C, --git-dir) | Yes | Yes |
| Dedup consecutive output | Yes | Yes |
| Rewritten command categories moat | 91 bins | 72 rules |
moat rows mark structural advantages — they require a persistent index, which rtk does not have.
ig gain Dashboard
Real output from ig gain (v1.10.0 defaults to showing the top 20 commands; --full for the complete list).
ig Token Savings ================================================================ Total commands: 3,445 Input bytes: 28.7M Output bytes: 21.4M Bytes saved: 7.3M (25.4%) By Command (top 20) ----------------------------------------------------------------------- # Command Count Saved Avg% Impact ----------------------------------------------------------------------- 1. ig read -s 343 3.9M 92.7% ========== 2. ig git diff 184 1.9M 70.6% ===== 3. ig run curl 30 716.0K 92.1% == 4. ig run cargo test 43 555.9K 76.1% = 5. ig git log 145 476.6K 46.2% = 6. ig ls 491 358.1K 77.2% = … 20. ig run /tmp/bench/mocks... 14 24.5K 29.3% ----------------------------------------------------------------------- Showing top 20 of 143 commands. Use `ig gain --full` to see the full list.
Reproduce
The full script, the 115-case CSV, and the per-domain markdown report are published alongside this release:
documentation/public/bench/v1.10.0/results.csv-- one row per case (id, domain, label, ig bytes, ig ms, rtk bytes, rtk ms, winners)documentation/public/bench/v1.10.0/summary.md-- totals, per-domain table, honest caveatsdocumentation/public/bench/v1.10.0/per-domain.md-- every case listed individually