Repository navigation
perf(mongodb): measure missing_params cost; HFS_MONGODB_MISSING_METADATA opt-out (#2006) - #2209
Conversation
… cost bench (#2006) Adds `missing_metadata` (default on, `HFS_MONGODB_MISSING_METADATA`). Off, writes record no `missing_params` (an update removes the field), `idx_resources_missing_params` is neither built nor required, and `:missing=true` takes the value-index route, which returns the same results. This is both the A/B lever for #2006 and the opt-out the issue asks to evaluate. Adds the #[ignore] `missing_params_cost_bench`: loads the same Synthea mix with metadata on and off and reports create/update/$bulk-submit throughput and p50/p99/p99.9, collection and index sizes, WiredTiger cache deltas and the per-type absent-name profile.
`:missing` on `_id` or `_lastUpdated` never reads `missing_params` (`is_missing_resource_parameter` excludes them; both are columns of every resource document), yet every resource without `meta.lastUpdated` in its body -- all of the Synthea corpus -- recorded `_lastUpdated` as absent: one array entry and one multikey index key per resource that nothing reads. Both checks now share `records_missing_metadata`. Tests: the recorded set omits both columns but keeps other absent meta parameters; and the `missing_metadata: false` switch clears what an enabled writer left, skips the index build, and answers `:missing=true` and `:missing=false` exactly as with metadata.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
# Conflicts: # crates/persistence/tests/mongodb/missing_index.rs
# Conflicts: # crates/persistence/tests/mongodb/missing_index.rs # crates/persistence/tests/mongodb_tests.rs
Review: tested with and without the change, plus a cost benchVerdict: the opt-out is correct and costs nothing measurable on writes. Dropping Correctness
Cost benchSetup: MongoDB 8.0 single-node replica set,
This agrees with the PR body. The write differences are run-to-run noise. The cost is storage and cache traffic. The Read sideThe recommendation to keep metadata on covers only writes. For searches, the metadata route is currently slower whenever many resources match. This is already on main and not caused by this PR. Medians of 7 warm runs, page with an accurate total. Totals were identical on every row.
The cause is the Smaller points
|
Refs #2006. This PR adds an opt-out for
missing_params, removes one never-read entry from it, adds a cost benchmark, and reports 1M-resource measurements with a recommendation.Changes
HFS_MONGODB_MISSING_METADATA(MongoBackendConfig::missing_metadata, defaulttrue). When it isfalse:missing_params, and each update or reindex removes the field;idx_resources_missing_paramsis neither built nor required (an existing one is left in place);:missing=truetakes the value-index route, as it does before mongodb: build idx_resources_missing_params under HFS_MONGODB_INDEX_BUILD instead of blocking startup #2001's build finishes, and returns the same results.The switch hooks into
search_index_documents_checked, which every writer (create, update, transaction, bulk ingest, deferred index, reindex) goes through._lastUpdatedand_idare no longer recorded.is_missing_resource_parameternever answers:missingon them from the array, because both are columns of every resource document. Even so, every resource withoutmeta.lastUpdatedin its body recorded_lastUpdatedas absent, which covers all of Synthea. That was about 1 of the ~18 entries per resource, each one written and indexed but never read. Both places now sharerecords_missing_metadata.missing_params_cost_bench(#[ignore]). It loads the same Synthea type mix into a fresh database with metadata on and then off, and reports:$bulk-submit;$collStatssizes;Tests.
_idand_lastUpdatedbut keeps other absent meta parameters.:missing=trueand:missing=falsereturn exactly what they return with metadata (Accurate and Estimate totals).missing_indextests pass; 129 missing/deferred/reindex integration tests pass; 489 Mongo lib tests pass.Measurements
Setup
wiredTigerCacheSizeGB=2; release build; 32 concurrent writers.$bulk-submitinto a second tenant. That makes 1.2M resources.Run 2 (clean,
offthenon)$bulk-submitres/sresourcesdataidx_resources_missing_paramsresourcesindexesReading the numbers
Write throughput and latency: no cost was measurable on one node. The
onarm ran second and came out slightly faster, which is the corpus being warm in the OS page cache, not an effect of the metadata.Run 1 (
onthenoff): theonarm overlapped other builds and benchmarks on the host and showed −7% create, −62% update and −50% bulk. Run 2 does not reproduce those gaps, so they were contention.The real costs are storage and cache:
resourcesindex combined, roughly 1.5–1.6 KiB per resource;resourcesdata;On a single node this does not yet show up as write latency. A deployment whose working set already fills the cache is where it would.
What the array holds: ~18.0 names per resource, ranging from 25.7 for Observation to 6 for CareTeam. 80% of entries are names absent from at least 99% of resources of their type. Examples:
_security,_source,_tagandidentifieron most types, andperformer,specimenandmethodon Observation.Recommendation
:missing=true. It saves the index (about 1.5 GiB per million resources here) and 15% of resource data._id/_lastUpdated.:missing=truequery would match broadly.