MontuDB is a PostgreSQL 17.2 fork whose optimizer measures the real cardinality of your data combinations instead of guessing it. When a reporting segment is effectively empty, it skips the multi-million-row scan — and returns the exact same result in milliseconds.
Before running a query, every database estimates how many rows each step produces. PostgreSQL assumes column independence: that two filters applied together behave as if unrelated. In a real data warehouse they're correlated — enterprise vendors sell only electronics, smb vendors sell only grocery. Ask for "enterprise × grocery" and that segment is genuinely empty. PostgreSQL doesn't know that. It multiplies selectivities, assumes plenty of rows, and scans an entire 22-million-row fact table only to return zero rows.
The core of the Montu optimizer is measured-cardinality probing. During planning of a hinted query, it probes the real post-filter intersection of joined dimensions — and when that intersection is provably empty, it forces an empty-first plan so the giant fact table is never executed.
Finds dimension pairs and trios directly connected by a join edge — e.g. vendors ⋈ products.
Measures the real intersection after WHERE filters are applied, instead of multiplying selectivities the way PostgreSQL does.
If the post-filter intersection is provably empty with full coverage, it records an empty-intersection cascade.
The empty branch is resolved first under a controlled planning budget, so the fact table is never run.
Montu only probes pairs joined by a real edge. It never executes a cartesian probe — which would be ruinously expensive.
It applies the correction only when the measurement has enough coverage to be trustworthy.
In any ambiguous situation, Montu disengages and returns PostgreSQL's standard plan. That's why it never makes the result worse.
SELECT /*+ montu_optimizer(5) */ region, sum(amount) FROM order_items oi JOIN products p ON p.id = oi.product_id JOIN vendors v ON v.id = p.vendor_id WHERE v.vendor_tier = 'enterprise' AND p.category = 'grocery' GROUP BY region; -- Without the hint, behaviour is pure PostgreSQL 17.2, byte for byte.
Metric rule (applies to every table): every "Nx faster" is PostgreSQL Execution Time ÷ MontuDB Execution Time, reading only the Execution Time: line of EXPLAIN (ANALYZE, BUFFERS). Planning time, Montu's probe time and wall-clock are reported in separate columns — they are never folded into the headline number. Results are always identical (same rows).
Environment: MontuDB (PostgreSQL 17 fork), Raspberry Pi 5. Synthetic warehouse mktg_db (~9.2 GB): order_items 22M, campaign_events 28M; customers 3.5M, products 50k, vendors 2k. Single-thread (max_parallel_workers_per_gather=0), fresh basic stats, useful indexes present. The empty: vendor_tier × category are perfectly anti-correlated, so "enterprise × grocery" is genuinely empty. Medians of 5 runs.
| Query | Business report | PG exec | Montu exec | Speedup (exec) | Montu probe | Same result |
|---|---|---|---|---|---|---|
| QV22_01 | Grocery revenue by region | 18,211 ms | 21.4 ms | 850× | 14.2 s | |
| QV22_10 | Grocery revenue by customer status | 17,912 ms | 21.3 ms | 841× | 12.9 s | |
| QV22_05 | Grocery revenue by country | 17,856 ms | 21.4 ms | 835× | 13.3 s | |
| QV22_16 | Grocery units / top line by region | 17,744 ms | 21.5 ms | 825× | 14.2 s | |
| QV22_03 | Distinct grocery customers by region | 17,677 ms | 21.6 ms | 820× | 14.1 s | |
| QV22_02 | Grocery units / lines by year | 14,298 ms | 21.3 ms | 670× | 12.8 s | |
| QV22_17 | Grocery revenue + avg ticket by country | 3,728 ms | 21.3 ms | 175× | 12.9 s | |
| QV22_15 | Grocery revenue by region and year | 3,451 ms | 21.4 ms | 162× | 14.4 s |
⚠ These are single-run points where Montu's probe (~69 s) overruns the budget and PG's execution. Shown for completeness only.
| Query | Business report | PG exec | Montu exec | Speedup (exec) | Montu probe |
|---|---|---|---|---|---|
| QV22_07 | smb-electronics units by region | 59,178 ms | 24.4 ms | 2425× | ~69 s |
| QV22_08 | smb-electronics lines by year | 32,520 ms | 21.5 ms | 1516× | ~69 s |
| QV22_09 | smb-electronics customers by region | 5,320 ms | 28.0 ms | 190× | ~68 s |
172 varied queries (the "100Q" report suite plus an out-of-sample suite with CTEs, subqueries, unions, aggregations). This battery exists to prove the gain comes with no hidden regressions.
| Query | PG exec | Montu exec | Saved | Speedup | Same result |
|---|---|---|---|---|---|
| q029 | 122.636 ms | 1.732 ms | 120.9 ms | 70.81× | |
| q027 | 89.047 ms | 1.792 ms | 87.3 ms | 49.69× | |
| q024 | 84.149 ms | 1.726 ms | 82.4 ms | 48.75× | |
| q033 | 63.424 ms | 24.580 ms | 38.8 ms | 2.58× | |
| q039 | 61.326 ms | 24.313 ms | 37.0 ms | 2.52× | |
| q034 | 59.549 ms | 24.380 ms | 35.2 ms | 2.44× | |
| q038 | 59.646 ms | 24.485 ms | 35.2 ms | 2.44× | |
| q019 | 18.651 ms | 12.666 ms | 6.0 ms | 1.47× |
Across 172 queries MontuDB improved 21 and hurt none, always returning identical results. Largest speedup 70.81× (q029); 172/172 results byte-identical. Where PostgreSQL is already good, MontuDB is neutral.
Montu probes the real intersection of your dimensions during planning. Where PostgreSQL multiplies selectivities and misses, Montu measures and hits.
Opt-in: without the hint, behaviour is byte-for-byte PostgreSQL 17.2. On any doubt, Montu disengages and returns the standard plan. It never makes results worse.
Same protocol, same tools, same backups. Installs side-by-side under /opt/montudb, without replacing your existing PostgreSQL or its psql.
Enterprise adds evolving RealCost cache and cost-governance features on top.
| Feature | Community | Enterprise |
|---|---|---|
| RealCost optimizer (measured cardinality + empty-first plan) | ✓ | ✓ |
| Auditable RealCost EXPLAIN | ✓ | ✓ |
| Per-query RealCost cache (fail-closed, safe) | ✓ (basic) | ✓ |
| Evolving RealCost cache | — | ✓ |
| Measured-cost extraction & injection | — | ✓ |
| Drift-validation policies (STRICT / DRIFT_PCT / TRUST) | always STRICT | ✓ |
The features above are real. Commercial terms (pricing, limits) for Enterprise are being finalized — talk to us before deploying the editions table publicly.
Based on PostgreSQL 17.2 · distributed under the PostgreSQL License · reports as PostgreSQL 17.2 (MontuDB 4.8). Production builds (optimized -O2, assertions off, stripped).
Installs under /opt/montudb/4.80. Doesn't touch the system psql or the postgresql service.
It does not initialize or start a cluster automatically. You run initdb / pg_ctl yourself.
So it never clashes with a PostgreSQL on 5432.
Uses the arm64 artifacts. amd64 and arm64 are both first-class.
| Platform | Format | Size | SHA-256 | |
|---|---|---|---|---|
| Debian / Ubuntu / RPi OS 64-bit arm64 | deb | 4.7 MB | ba4f5d5c…65476fe8 |
.deb |
| Debian / Ubuntu amd64 | deb | 5.2 MB | ba3ff885…9f54270b |
.deb |
| RHEL / Rocky / Alma / Oracle Linux x86_64 | rpm | 5.6 MB | b5374f27…09145f2a |
.rpm |
| RHEL / Rocky / Alma / Oracle Linux aarch64 | rpm | 5.5 MB | 60698f0c…1d067fce |
.rpm |
| Portable tarball amd64 | tar.gz | 8.1 MB | 789b8425…fb2e4f62 |
tar.gz |
| Portable tarball arm64 | tar.gz | 7.9 MB | 36ebbff8…8b15049c |
tar.gz |
| Docker image amd64 | docker | 52 MB | 7ea79862…7d332eef |
.tar |
| Docker image arm64 | docker | 52 MB | 7e45bb49…b93a1ff0 |
.tar |
Verify integrity:
SHA256SUMS ·
release-manifest.json.
On Linux: sha256sum -c SHA256SUMS.
# .deb sudo dpkg -i montudb_4.80-1_arm64.deb # RHEL / Rocky / Alma (x86_64) sudo rpm -i montudb-4.80-1.x86_64.rpm # Docker docker load -i montudb-4.80-docker-arm64.tar
/opt/montudb/4.80/bin/initdb -D /path/to/data
/opt/montudb/4.80/bin/pg_ctl -D /path/to/data \
-o "-p 55432" -l log.txt start
/opt/montudb/4.80/bin/psql -p 55432 -c "SELECT version();"
# -> PostgreSQL 17.2 (MontuDB 4.8) ...
Documentation: Manual (PDF) · README · Release notes.
MontuDB's numbers are real and audited, but only true inside a precise definition. Speedup = Execution Time only — PostgreSQL's Execution Time ÷ MontuDB's, from EXPLAIN (ANALYZE, BUFFERS). Results are identical (verified by row identity / md5). The winning reports return an empty result (0 rows) — a real emptiness between dimensions. Fresh basic stats; no pg_statistic edits, no n_distinct tricks.
The fixture is synthetic and single-thread: the emptiness is constructed (perfectly anti-correlated tiers). The mechanism is real; the magnitudes are fixture-specific. The 2425× point is a single run with probe overrun — footnote, never a headline.