Contents
Configuration
BloomPG settings are session-level unless noted otherwise. Load the module before reading or changing them:
LOAD 'bloompg';
Propagation policy
SET bloompg.transfer_progress_metric = 'ndv'; -- default
SET bloompg.transfer_progress_metric = 'rows'; -- compatibility mode
ndv changes only convergence detection for eligible equality-key transfers.
Scheduling still uses estimated/live row counts. For a canonical, same-type
integral equality class, BloomPG records the exact distinct-key count and a
version per relation. Equal exact NDV proves that a transferred subset did not
change the key domain, so the redundant transfer can be skipped without
storing a second key set.
rows retains the original row-cardinality and filter-lineage propagation.
Composite keys, cross-type joins, approximate Bloom filters, protected join
sides, and unsupported equality classes use this normal path in either mode.
Main settings
| Setting | Default | Purpose |
|---|---|---|
bloompg.enable |
on |
Enable planner integration. |
bloompg.sample_mode |
prepared |
Use persistent prepared or query-local instant samples. |
bloompg.sample_size |
10000 |
Target rows per base-relation sample. |
bloompg.sample_seed |
2 |
Deterministic prepared-reservoir seed. |
bloompg.sample_rate |
0.01 |
Chunk fraction sampled from an already materialized relation. |
bloompg.sample_cache_dir |
auto |
Prepared cache directory; auto uses $PGDATA/bloompg_samples. Superuser-only. |
bloompg.sample_memory_cache |
on |
Retain prepared samples in backend memory; cached CTIDs and hydrated tuples share a limit of half materialization_memory. |
bloompg.excitation_threshold |
1.0 |
Re-excite below this fraction of the preceding cardinality. |
bloompg.local_first_fraction |
0.001 |
Candidate threshold for evaluating a selective local qual first. |
bloompg.bits_per_key |
24 |
Bloom-filter bit budget per estimated key. |
bloompg.max_filter_bytes |
64MB |
Per-filter memory ceiling. |
bloompg.transfer_progress_metric |
ndv |
Equality-transfer convergence signal: rows or ndv. |
bloompg.materialization_memory |
up to 2GB |
Total memory budget for one query’s optimizer-time materializations and parallel DSM copies. The default is one eighth of detected host/cgroup memory, capped at 2GB. |
bloompg.transfer_workers |
4 |
Maximum workers for one eligible transfer scan; 0 is serial. |
bloompg.transfer_parallel_min_rows |
100000 |
Minimum estimated input rows for parallel transfer scanning. |
bloompg.replan_after_transfer |
on |
Run the second PostgreSQL planning pass. |
When this budget cannot hold the next vector allocation, BloomPG abandons its
optimizer work and executes the original PostgreSQL plan. It never silently
turns the materialization into a disk spill. Use bloompg_tune.py to size the
query-wide budget for dedicated analytical deployments and concurrency.
Index-assisted materialization
| Setting | Default | Purpose |
|---|---|---|
bloompg.index_transfer |
off |
Experimentally let exact incoming join keys drive a compatible B-tree path. |
bloompg.index_transfer_max_fraction |
0.15 |
Maximum sampled survivor fraction for choosing that path. |
bloompg.index_transfer_batch_keys |
65536 |
Exact keys in one direct B-tree probe batch. |
bloompg.index_transfer_max_keys |
100000 |
Maximum exact distinct-key population eligible for index transfer. |
bloompg.index_transfer_planner_max_keys |
8192 |
Maximum keys expanded into one private PostgreSQL access plan. |
bloompg.index_guard_min_rows |
100000 |
Large indexed relations wait for an exact incoming join-key set. |
Index-assisted materialization is opt-in. The index guard delays only relations whose base cardinality reaches the threshold and whose join key has a compatible B-tree index. If every active candidate is waiting, BloomPG materializes the smallest current candidate with the best available PostgreSQL access path, falling back to a sequential scan when no exact-key index path is ready. Index readiness controls how a relation is read; it never removes an excited relation from the equality-domain fixed point. Memory or execution-safety failures still retain the native PostgreSQL preview plan.
P1 and materialization
| Setting | Default | Purpose |
|---|---|---|
bloompg.late_materialize |
on |
Allow survivor-CTID materialization for wide relations. |
bloompg.late_materialize_min_width |
128B |
Projected-width threshold for TID mode. |
P1 exposes serial and parallel paths for exact in-memory materializations up to the configured worker ceiling. PostgreSQL’s normal cost model chooses between them. A narrow safety comparison retains the native plan only when P1 selects a more expensive parameterized-index Nested Loop shape.
Diagnostics
| Setting | Default | Purpose |
|---|---|---|
bloompg.profile |
off |
Collect the last query’s structured profile. |
bloompg.profile_log |
on |
Write completed profiles to the PostgreSQL log. |
bloompg.log_transfer_steps |
off |
Log detailed transfer and shared-memory events. |
SET bloompg.profile = on;
SET bloompg.profile_log = off;
SELECT count(*) FROM fact JOIN dimension USING (key) WHERE dimension.keep;
SELECT jsonb_pretty(bloompg_last_profile());
SELECT bloompg_last_trace();
Prepared samples affect scheduling and estimates only. Every row-eliminating filter is built from an exact scan under the active statement snapshot.