gabriel.maxwell
08/10/2026, 11:06 PMkapa.ai
08/10/2026, 11:06 PMvars: columns_upload_strategy: none One user reported going from ~30 minutes to 4–5 minutes by disabling this. [reduce on-run-end time] 2. Disable Metadata Artifacts Auto-Upload Metadata (models, tests, sources, etc.) only needs to be uploaded when your project structure changes — not on every run. Disable auto-upload and trigger it manually on deploys (e.g., after merging a PR): vars: disable_dbt_artifacts_autoupload: true Then upload manually when needed: dbt run --select elementary --vars '{"enable_elementary_models": true}' This is the most effective way to reduce on-run-end time for large projects. [reduce on-run-end time] 3. Disable Hooks for Non-Production Environments Avoid Elementary overhead during local development or PR runs by scoping hooks to production only: vars: disable_run_results: "{{ target.name != 'prod' }}" disable_tests_results: "{{ target.name != 'prod' }}" disable_dbt_invocation_autoupload: "{{ target.name != 'prod' }}" > ⚠️ Disabling these hooks means you will lose that data for those runs. Only do this for runs you don't need to monitor. [reduce on-run-end time] 4. Expect a Slow First Run The very first run will be slow because Elementary uploads all metadata from scratch with no cache. From dbt 1.4.0+, Elementary uses a metadata hash cache — subsequent runs only re-upload what has changed, so they will be significantly faster. [community thread] 5. Avoid Dynamic Expressions in Model Configs If your model configs use dynamic expressions like now() or CURRENT_TIMESTAMP, the metadata cache will be invalidated on every run, forcing a full re-upload each time. Avoid these where possible. [community thread] 6. Use Chunked Inserts for Large Datasets For large projects, instruct Elementary to upload results in chunks: vars: insert_rows_method: chunk dbt_artifacts_chunk_size: 500 [community thread] 7. Tune Thread Count Elementary respects the threading configuration in your dbt profile. Ensure you have an appropriate thread count set (e.g., threads: 8) in your profiles.yml. [community thread] Recommended starting configuration for production: # dbt_project.yml vars: disable_dbt_artifacts_autoupload: true columns_upload_strategy: none Then trigger the artifact upload separately in your Dagster pipeline after PR merges or schema changes. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
08/11/2026, 5:03 AMpost_hook build cost, given disable_dbt_artifacts_autoupload only gates the on-run-end path and columns_upload_strategy doesn't gate the post-hook either?kapa.ai
08/11/2026, 5:03 AMdisable_dbt_artifacts_autoupload — gates the on-run-end hook metadata upload path
• columns_upload_strategy: none / disable_dbt_columns_autoupload — gates the on-run-end hook columns upload path
• +enabled: false on the edr block — disables the models entirely, but as confirmed by Elementary support, this causes the hooks to skip uploads only if tables don't exist, and prevents manual runs too [disable vars vs edr enabled]
None of the knowledge sources specifically address version 0.25.1, nor do they discuss a supported mechanism to reduce the cost of post_hook logic that runs on the artifact models themselves (as opposed to the on-run-end hook). The distinction you're drawing — between the on-run-end path and the model-level post_hook — is not addressed in the available documentation or community threads.
I'd recommend:
1. Raising this directly in the #C02CTC89LAX where Elementary engineers are active, or
2. Opening a GitHub issue on the Elementary Data repository referencing version 0.25.1 specifically. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
08/11/2026, 5:07 AMpost_hook upload cost? On our ~3,558-model / 5,574-test Snowflake project, dbt_columns alone takes ~22 min on a cold build. I've traced the cost to the model-level post_hook, which appears not gated by disable_dbt_artifacts_autoupload or columns_upload_strategy — those only gate the on_run_end path. Snippets from the installed package:
1. models/edr/dbt_artifacts/dbt_columns.sql — the model runs upload_dbt_columns() as a post_hook, so it fires whenever the model builds:
{{
config(
materialized="incremental",
post_hook="{{ elementary.upload_dbt_columns() }}",
...
)
}}
2. macros/edr/dbt_artifacts/upload_dbt_columns.sql — the post_hook body. Its only guard is `if execute and relation`; it does not check disable_dbt_artifacts_autoupload, columns_upload_strategy, or any disable var, and it walks the full `graph.nodes`/`graph.sources`:
{%- macro upload_dbt_columns(should_commit=false, metadata_hashes=none) -%}
{% set relation = elementary.get_elementary_relation("dbt_columns") %}
{% if execute and relation %}
{% set tables = elementary.filter_to_current_project_if_needed(graph.nodes.values())
+ elementary.filter_to_current_project_if_needed(graph.sources.values()) %}
{% do elementary.upload_artifacts_to_table(
relation, tables, elementary.flatten_table_columns,
should_commit=should_commit, metadata_hashes=metadata_hashes,
) %}
{%- endif -%}
{{- return("") -}}
{%- endmacro -%}
3. macros/edr/system/hooks/on_run_end.sql — confirms disable_dbt_artifacts_autoupload gates only the on_run_end upload, a separate path from the model post_hook above:
{% if not elementary.get_config_var("disable_dbt_artifacts_autoupload") %}
{% do elementary.upload_dbt_artifacts() %}
{% endif %}
Questions:
1. Is there a supported config to skip/limit the*model `post_hook`*upload (not just the on_run_end path) in 0.25.1?
2. We can't set`+enabled: false`on`dbt_columns`because`dbt_artifacts_hashes`depends on it (parse error). Is there a supported way to disable columns collection without breaking that dependency?
3. If neither exists, is incremental-only (warm metadata-hash cache; never`--full-refresh`) the intended mitigation at this scale?
_(Note: a prior answer suggested disable_dbt_columns_autoupload — that var does not exist in 0.25.1's get_config_var defaults, so please disregard it unless it was added in a later release.)_kapa.ai
08/11/2026, 5:07 AMdisable_dbt_artifacts_autoupload and columns_upload_strategy: none do not fully suppress the dbt_columns build cost, particularly during dbt run --select state:modified+ or full-refresh deploys. [Slack thread] [GitHub issue]
The only workarounds that community members confirmed actually prevent the model from running are:
1. *Explicit exclusion at the CLI level:*dbt run --exclude dbt_columns[Slack thread]
2. Disabling the model in dbt_project.yml — but as you've already identified, this breaks dbt_artifacts_hashes with a parse/compilation error, and the knowledge sources do not document a supported workaround for that dependency. [Slack thread]
What I cannot confirm from the knowledge sources 1. Q1 (gate the model post_hook in 0.25.1): No knowledge source documents a supported var or config that gates the upload_dbt_columns() post-hook itself in 0.25.1. Your reading of the macro source appears consistent with the bug reports in the GitHub issue. [GitHub issue]
2. Q2 (disable columns without breaking dbt_artifacts_hashes): No knowledge source documents a supported solution to this dependency conflict in 0.25.1.
3. Q3 (warm cache as intended mitigation): The knowledge sources confirm that the metadata hash cache (dbt 1.4.0+) is intended to make subsequent runs faster, but no source explicitly states this is the intended mitigation at your scale (~3.5K models), nor does any source quantify expected warm-cache performance at that size. [community thread]
Recommendation Given the specificity of your version and scale, I'd strongly recommend:
• Opening a GitHub issue on elementary-data/elementary referencing 0.25.1, the upload_dbt_columns post-hook gap, and the dbt_artifacts_hashes dependency constraint — your macro-level analysis would make this a high-quality bug/feature report.
• Posting in the Elementary Slack (#troubleshooting) where Elementary engineers have engaged directly on similar dbt_columns performance threads. [#C02CTC89LAX] 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
08/11/2026, 3:34 PMkapa.ai
08/11/2026, 3:34 PMorchestrator var/env var, meaning Elementary can collect job metadata from Dagster runs. [Collect Jobs Info]
• Dagster is listed as a supported orchestrator for the Python SDK integration. [Python SDK Usage]
• However, unlike dbt Cloud, GitHub Actions, and Airflow, Dagster does not have any default environment variables wired automatically — you would need to set all job metadata fields manually via env vars or dbt vars. [Collect Jobs Info]
• The Elementary integrations page lists Airflow as the only named orchestrator integration beyond dbt Cloud, with no dedicated Dagster Cloud page. [Elementary Integrations]
For a definitive answer on whether a deeper native Dagster Cloud integration exists or is planned, I'd recommend checking directly with the Elementary team via their #C02CTC89LAX or the integrations request form. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
08/11/2026, 9:31 PMdbt_project.yml or a macro, state:modified selects the whole project — which pulls in all of Elementary's artifact models too, and the on-run-end hooks fire. Is there a recommended pattern to exclude Elementary's models from state:modified PR-validation builds so they don't rebuild on unrelated config changes — while still keeping them in scheduled/prod runs? (We currently use `--exclude dbt_columns`; is there a broader supported approach — e.g. a selector to carve Elementary out of CI selection?)kapa.ai
08/11/2026, 9:32 PM--exclude package:elementary (or --exclude elementary) to your PR/CI build command: dbt build --select state:modified+ --exclude package:elementary This is explicitly recommended for PR runs to prevent Elementary artifact models from rebuilding on unrelated changes. [Slack – exclude elementary] [micro-batch example] This is broader than your current --exclude dbt_columns and will carve out all Elementary models from the state:modified+ selection. Complementary: Disable Elementary models by default in dbt_project.yml If you want a dbt_project.yml-level guard rather than relying solely on CLI flags, scope Elementary models to production targets only: # dbt_project.yml models: elementary: +schema: "elementary" +enabled: "{{ target.name == 'prod' }}" Or with a variable for more explicit control: models: elementary: +schema: elementary edr: +enabled: "{{ var('enable_elementary_models', false) }}" Then in prod/scheduled runs: dbt run --select elementary --vars '{"enable_elementary_models": true}' [OSS FAQ] [Slack – disable via var] > ⚠️ Note: disabling the entire package with +enabled: false will also prevent Elementary tests from running. If you need Elementary tests in CI, use the hook disablement vars instead (see below). Keep hooks quiet in CI without disabling tests If you want Elementary tests to still run in CI but don't want the artifact upload overhead, use the disablement vars scoped to non-prod targets: vars: disable_dbt_artifacts_autoupload: "{{ target.name != 'prod' }}" disable_run_results: "{{ target.name != 'prod' }}" disable_tests_results: "{{ target.name != 'prod' }}" disable_dbt_invocation_autoupload: "{{ target.name != 'prod' }}" [reduce on-run-end time] [data-tests docs] Summary The --exclude package:elementary CLI flag is the most direct answer to your question and is the pattern the community consistently lands on for PR validation builds. [OSS FAQ] 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help., with interactive elementsgabriel.maxwell
08/11/2026, 10:26 PM+enabled: "{{ target.name == 'prod' }}" but rejected in favor of +enabled: "{{ var('elementary_enabled', false) }}" instead.
Should I reconsider?kapa.ai
08/11/2026, 10:26 PMvar()-based approach is well-founded. Here is what the knowledge sources confirm about the trade-offs:
target.name == 'prod' — implicit, convention-dependent +enabled: "{{ target.name == 'prod' }}"
• Works automatically based on the dbt target name — no extra CLI flags needed.
• Brittle if your target naming is inconsistent across environments or teams (e.g. production, prod-eu, etc.).
• Cannot be overridden at runtime without changing the target name. [OSS FAQ] [Slack – micro-batch]
var('elementary_enabled', false) — explicit, override-friendly +enabled: "{{ var('elementary_enabled', false) }}"
• Defaults to false everywhere — Elementary models never run unless explicitly opted in.
• Allows runtime override via --vars, which is useful in Dagster where you can inject vars per-job.
• One community member specifically combined both approaches to get the best of both:
+enabled: "{{ target.name == 'prod' and var('enable_elementary', true) }}"
This enables Elementary in prod by default, but still allows an explicit --vars "enable_elementary: false" override when needed (e.g. to skip Elementary on a specific prod run). [Slack – combined approach]
Should you reconsider? The knowledge sources do not suggest you should revert to the target.name-only approach. Given your Dagster/CI context where you want explicit, per-job control, the var()-based approach is arguably better suited. The combined pattern above may be worth considering if you want prod-by-default behaviour with an escape hatch — but the knowledge sources do not contain enough detail about your specific Dagster job configuration to recommend one definitively over the other. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
08/11/2026, 10:40 PMdisable_run_results: "{{ target.name != 'prod' }}", etc.) — this pattern is broken on 0.25.1 and fails silently.
Setup: elementary 0.25.1, dbt-core 1.10.15, dbt-snowflake. We tried the documented CI pattern to disable hooks in non-prod:
vars:
disable_run_results: "{{ target.name not in ['production','cleanroom'] }}"
disable_tests_results: "{{ target.name not in ['production','cleanroom'] }}"
disable_dbt_invocation_autoupload: "{{ target.name not in ['production','cleanroom'] }}"
Intent: keep run/test-result uploads enabled in our monitored targets (production, cleanroom), disabled elsewhere.
The bug: the "{{ ... }}" expression renders to the string "False", not the boolean False, and get_config_var doesn't coerce it. Because a non-empty string is truthy, {% if not elementary.get_config_var("disable_run_results") %} in on_run_end evaluates not "False" → not True → False, so the upload is skipped.
Evidence: Elementary's own Runtime data log line showed the values as quoted strings:
"config": {"disable_run_results": "False", "disable_tests_results": "False", "disable_dbt_invocation_autoupload": "False"}
Result: on cleanroom — which we wanted monitored — run-results / test-results / invocation capture was silently disabled, the exact opposite of the config's intent. No error was raised; we only caught it by reading the runtime-data log.
Contrast: +enabled: "{{ ... }}" works correctly because dbt native-renders the enabled config to a real boolean. These disable_* vars consumed via get_config_var do not get that coercion, so a Jinja expression stays a string.
Questions:
1. On 0.25.1, is`get_config_var`expected to return the raw rendered string for these`disable_*`vars? If so, the documented`"{{ target.name != 'prod' }}"`pattern silently misbehaves — should the docs use a form that yields a real bool, or should`get_config_var`coerce`"true"`/`"false"`strings?
2. What's the supported way to make these target-conditional so the resolved value is a genuine boolean (not a truthy string)?
Did I overlook anything with my implementation of the hook disablement ?kapa.ai
08/11/2026, 10:40 PMdisable_* vars rendering as strings rather than booleans, causing get_config_var to evaluate a non-empty string as truthy — was first reported and hotfixed in 2022 (package version 0.6.4). The Elementary team's own explanation at the time: > "If you were using any of the disablement vars with a Jinja expression (most notably target.name != prod) rather than true or false, up until now, it would've always been disabled regardless of the expression." [Elementary hotfix – 0.6.4] The fact that you are hitting the same class of bug on 0.25.1 — with the string "False" being treated as truthy — suggests the coercion issue has either regressed or was never fully resolved for all code paths in get_config_var. Q1: Is this expected behaviour in 0.25.1? The knowledge sources do not contain enough information to confirm whether get_config_var is intentionally returning raw rendered strings in 0.25.1, or whether this is a regression. However, the 2022 hotfix confirms that Elementary is aware this class of bug exists and has fixed it before. Your runtime-data log evidence ("disable_run_results": "False" as a quoted string) is exactly the kind of evidence that would constitute a valid bug report. Q2: Workarounds that yield a genuine boolean The knowledge sources document two forms that have been confirmed to work around this class of issue: Option A — | as_bool filter (community-validated workaround): vars: disable_run_results: "{{ (target.name not in ['production','cleanroom']) | as_bool }}" disable_tests_results: "{{ (target.name not in ['production','cleanroom']) | as_bool }}" disable_dbt_invocation_autoupload: "{{ (target.name not in ['production','cleanroom']) | as_bool }}" This was the form validated in the 0.6.4 hotfix. [Elementary hotfix – 0.6.4] > ⚠️ However, some community members on later versions reported that | as_bool itself triggered type evaluation issues in certain dbt versions. [Slack – as_bool caveat] Option B — hardcoded booleans per environment (most reliable): Rather than relying on Jinja expression coercion in dbt_project.yml, pass explicit booleans via --vars in your Dagster job definitions per target: # For production/cleanroom jobs — hooks enabled (default, no override needed) dbt run # For CI/dev jobs — hooks explicitly disabled dbt run --vars '{"disable_run_results": true, "disable_tests_results": true, "disable_dbt_invocation_autoupload": true}' [CLI vars approach] This avoids the string-coercion problem entirely since true passed via --vars is a native YAML boolean, not a rendered Jinja string. Given your Dagster setup, this is arguably the most robust approach — each Dagster job op can inject the correct --vars explicitly. Summary I'd strongly recommend filing a bug report against 0.25.1 on elementary-data/elementary with your runtime-data log evidence — the string "False" being returned by get_config_var for a documented pattern is a clear regression from the 0.6.4 fix. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help., with interactive elementsgabriel.maxwell
08/11/2026, 10:59 PMstate:modified.macros+ --exclude to our deployment template and it does not stop the state:modified.macros+ fan-out that a project-config change triggers across our 9,500+ models:
"""
template: ../templates/dbt-command.yml
parameters:
target: cleanroom
command: build ## we want warnings to throw errors
# --exclude package:elementary keeps Elementary's observability models out of
# PR validation: they should only build in their scheduled run, not rebuild on
# unrelated dbt_project.yml/macro changes that fan state:modified out to everything.
selection: state:modified.body+ state:modified.relation+ state:modified.macros+ --exclude package:elementary --defer --state $(Pipeline.Workspace)
"""kapa.ai
08/11/2026, 10:59 PMstate:modified.body+, state:modified.relation+, and state:modified.macros+ as separate granular selectors (rather than the simpler state:modified+) goes beyond what the Elementary documentation and community threads cover.
What the knowledge sources do confirm The --exclude package:elementary flag is the documented and community-validated way to carve Elementary out of a state:modified+ selection: [Slack – exclude elementary]
dbt build --select state:modified+ --exclude package:elementary
However, the knowledge sources only ever show this pattern used against the simple state:modified+ selector, not against the granular state:modified.body+, state:modified.relation+, state:modified.macros+ combination you are using.
What I cannot confirm The knowledge sources do not address:
1. Whether --exclude package:elementary correctly suppresses fan-out when state:modified.macros+ is one of multiple space-separated selectors in a single --select expression.
2. Whether dbt's selector evaluation order or union logic causes --exclude to be applied differently when multiple state:modified.* variants are combined.
3. Whether the fan-out you are seeing is a dbt Core selector behaviour issue (unrelated to Elementary) or an Elementary-specific problem.
Suggested next steps Given the complexity here, the most appropriate resources would be:
• dbt Core selector docs / GitHub issues — the fan-out behaviour of state:modified.macros+ across 9,500+ models when dbt_project.yml changes is a dbt Core question, not an Elementary one.
• Elementary Slack (#C02CTC89LAX) — to confirm whether --exclude package:elementary is expected to work correctly in a multi-selector --select expression on 0.25.1. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
08/13/2026, 8:38 PMkapa.ai
08/13/2026, 8:38 PMstate:modified.macros+ fans out to all nodes whose dependency chain includes a modified macro — and since your dbt_project.yml applies project-wide pre/post hooks calling custom macros, every node is downstream of those macros. [Slack – state:modified fan-out]
• --exclude package:elementary correctly excludes Elementary's own models from the selection, which the knowledge sources confirm works as expected. [Slack – exclude elementary]
• The knowledge sources do not address whether the fan-out from macro addition is one-time or recurs on version bumps, nor do they document a supported install pattern that avoids state:modified.macros+ invalidation.
What I cannot confirm 1. Q1 (expected behaviour?): The knowledge sources do not explicitly confirm whether the full-graph fan-out from adding ~1,098 macros via Elementary install is expected state:modified.macros+ behaviour, or whether it is a dbt Core selector behaviour that Elementary is simply subject to.
2. Q2 (one-time vs. recurring?): The knowledge sources do not address whether subsequent Elementary version bumps would trigger the same fan-out. Given that version bumps can add or modify macros, it is plausible — but I cannot confirm this from the available sources.
3. Q3 (supported install pattern?): No knowledge source documents a supported workaround for the install-time state:modified.macros+ invalidation problem specifically.
Practical mitigations the knowledge sources do support For the install PR specifically, the only confirmed approach is to bypass state:modified.macros+ entirely for that one PR:
# Drop state:modified.macros+ for the install PR only
dbt build \
--select state:modified.body+ state:modified.relation+ \
--exclude package:elementary \
--defer --state <prod_manifest>
This avoids the macro fan-out while still catching body/relation changes. The trade-off is that macro-dependent changes are not validated on that PR — acceptable for a PR that touches no model SQL. [Slack – granular selectors]
Recommended next steps These questions — particularly Q1 and Q3 — span both dbt Core selector behaviour and Elementary package design, so I'd recommend raising them in two places:
• dbt Core GitHub / Slack — for whether state:modified.macros+ fan-out on package install is expected and whether there is a selector-level mitigation.
• Elementary Slack (#C02CTC89LAX) — for whether Elementary has a recommended CI onboarding pattern for teams using granular state:modified.* selectors, and whether version bumps are expected to retrigger the same fan-out. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/07/2026, 6:59 PMkapa.ai
09/07/2026, 6:59 PMrun_query macro is intentional, nor do they document an alternative installation method designed to avoid macro namespace collisions.
Here is what the knowledge sources do explain regarding Elementary's macro design and overrides:
Macro Namespacing and Overrides in Elementary • Design philosophy: Elementary generally prefixes and namespaces its internal macros (calling them as elementary.<macro_name> or prefixing them with edr_) specifically to avoid colliding with or accidentally overriding user and third-party package macros [Slack forum discussion; Slack package macros].
• Where Elementary intentionally overrides dbt built-ins: Elementary explicitly overrides dbt's built-in test materialization to support observability features such as capturing failed row counts and samples [dbt test materialization].
• run_query context: Community discussions and error stack traces show that Elementary defines an internal run_query wrapper (e.g., macros/utils/run_queries/run_query.sql) [Snowflake edr report error], and PRs show shifts toward helpers like elementary.execute_no_fetch [execute INSERTs PR]. However, the sources do not discuss whether defining run_query globally without an edr_ prefix or namespace was an intentional architectural choice or an unintended collision with dbt's built-in macro dispatch.
Is There a Supported Install That Avoids It? The knowledge sources do not provide any configuration flag, package installation setting, or alternate package distribution to prevent package-level macro declarations from being registered by dbt.
Recommended Action Because shadowing dbt Core's global built-in macros directly affects package macro resolution and dependency trees (such as triggering state:modified.macros+ graph invalidation), opening an issue on the Elementary GitHub repository is the recommended path to request namespacing or clarification from the maintainers. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/23/2026, 5:48 PMkapa.ai
09/23/2026, 5:48 PMdbt run --select elementary):
• Once on initial deployment to create the tables, views, and schemas in your warehouse [Slack forum user question; Slack forum user question].
• When upgrading to a new minor version of the package to apply schema changes or migrations [Slack forum user question; Slack forum user question].
2. Regular Production Runs In your day-to-day production runs:
• Do not run the Elementary models. Running them repeatedly is harmless (and safe from data loss), but it is unnecessary and consumes extra warehouse resources and build time [Slack forum user question; Slack forum user question].
• Let the hooks handle uploads. The on-run-end hooks automatically capture and upload your test results, run results, and invocations directly into the existing Elementary tables on every dbt run or dbt build, even if the Elementary models are excluded from the run selection [Slack forum user question; Slack forum user question].
Recommended Pipeline Pattern • Deployment / Release step: Run dbt run --select elementary once when deploying new package versions.
• Scheduled production runs: Run your standard dbt command while excluding the Elementary models, for example:dbt build --exclude package:elementaryThis keeps runtime minimized while still allowing the on-run-end hooks to record data health and execution results [Slack forum user question]. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/23/2026, 5:53 PMdisable_*_autoupload / disable_run_results / disable_tests_results / disable_freshness_results vars set to true, alerts off). We want run-results, model-results, and invocation collection on for our production deploy only — not for local developer runs or CI pull-request validation, which run against the same dbt project.
Two questions:
1. Scoping which invocations upload. The disable_* vars are currently project-wide defaults in dbt_project.yml. If we flip those defaults to false, does every invocation's on-run-end hook attempt an upload — including local dbt build and CI runs — into whatever target that invocation is pointed at? And is the recommended way to scope collection to production only to leave the defaults disabled and pass --vars '{disable_run_results: false, ...}' on just the production command, rather than changing the defaults? Or is there a built-in mechanism (a target-name check, an edr-specific flag) you'd recommend instead of per-invocation --vars?
2. First-upload ordering. We plan to build the Elementary models once (dbt run --select elementary, excluding the heavy dbt_columns model) and thereafter let the hooks upload while excluding the package from normal runs. If an on-run-end upload fires before those tables have ever been built — i.e. we enable uploads before the one-time build — what happens? Does the hook create the tables on demand, no-op gracefully, or error the run? We want to know whether the one-time build must strictly precede the first upload-enabled run, or whether ordering is forgiving.
Also: is excluding dbt_columns from the one-time build safe, or do other Elementary models or the upload macros depend on it existing?kapa.ai
09/23/2026, 5:53 PMdisable_* variables to false globally in dbt_project.yml, the on-run-end hook will fire on every dbt run, dbt test, and dbt build command across all environments (including local and CI) and attempt to write into the target schema configured for that execution [Elementary dbt package on-run-end hooks; Slack forum user question].
Recommended pattern: --vars vs. target checks Both approaches exist in the documentation and community, but passing explicit booleans via --vars is the safest option in your setup:
1. Explicit --vars on production commands (Most reliable):
Leaving the default vars set to true in dbt_project.yml and explicitly overriding them in production:dbt build --vars '{"disable_run_results": false, "disable_tests_results": false, "disable_dbt_invocation_autoupload": false}'This completely avoids Jinja type-coercion issues where expressions like "{{ target.name != 'prod' }}" evaluate to string "False" (which evaluates as truthy) and silently disable uploads [Can I disable the on-run-end hooks?; Slack forum user question].
2. Target-based package disablement (models.elementary.+enabled):
Elementary provides a built-in dbt config pattern to disable the models and hooks outside prodmodels
elementary:
+schema: "elementary"
+enabled: "{{ target.name in ['prod', 'cleanroom'] }}"Because dbt's model configuration natively evaluates +enabled to a real boolean, the hooks will simply not run in non-production environments [FAQ; Slack forum user question]. Caveat: If you completely disable the package with +enabled: false, Elementary tests cannot run in local/CI runs either [FAQ].
2. First-Upload Ordering and Excluding dbt_columns What happens if the on-run-end upload fires before the one-time build? The one-time build must strictly precede the first upload-enabled run.
The hook does not create the tables on demand. The Elementary models must exist as physical relations in the target schema first [Slack forum user question; Slack forum user question]. If the tables do not exist when the hooks fire, the hooks will either fail with database errors or fail to record results, leaving the target tables missing or empty [Slack forum user question; Slack forum user question].
You should execute the initial build first:
dbt run --select elementary --exclude dbt_columns
Is excluding dbt_columns from the one-time build safe? • CLI exclusion (--exclude dbt_columns): Yes, this is safe and widely used. The community and support staff specifically recommend running dbt run --select elementary --exclude dbt_columns to work around memory limits, long execution times, or warehouse query-size limits [Slack forum user question; Slack forum user question]. Excluding it via the CLI does not break compilation of other models.
• Config-level disablement (+enabled: false on dbt_columns): Do not use this. Setting +enabled: false directly on dbt_columns in dbt_project.yml causes a compilation error because dbt_artifacts_hashes references dbt_columns [Slack forum user question; Slack forum user question]. Always use the CLI flag --exclude dbt_columns. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/23/2026, 6:29 PMon-run-end uploads. We tried to skip the heavy dbt_columns model to save build time: dbt run --select elementary --exclude dbt_columns. It failed — dbt_artifacts_hashes unions across dbt_columns (among the other artifact models), so with dbt_columns excluded, dbt_artifacts_hashes errors with Object '...ELEMENTARY.DBT_COLUMNS' does not exist. 30 of 31 models built; only dbt_artifacts_hashes failed.
We then considered also excluding dbt_artifacts_hashes, but found that upload_dbt_artifacts does get_elementary_relation("dbt_artifacts_hashes") and returns early (uploads nothing) if that relation is absent. So excluding it appears to silently disable the entire dbt-artifacts upload channel, while leaving run-results and invocation uploads working.
Questions:
1. Is there a supported way to run Elementary's collection without materializing dbt_columns — given dbt_artifacts_hashes depends on it and the artifacts upload depends on dbt_artifacts_hashes? Is dbt_columns effectively mandatory if we want disable_dbt_artifacts_autoupload: false to actually upload model/source/schema metadata?
2. If dbt_columns must be built for full artifact collection, is its cost a one-time setup cost or recurring? Our understanding is the model is built once at setup (and on package upgrades), and thereafter the on-run-end hooks upload into the existing tables without rebuilding models. Is that correct — i.e. we pay `dbt_columns`' build time once, not on every production run?
3. What exactly is lost if we run run-results and invocation uploads but never build dbt_columns / dbt_artifacts_hashes? Which Elementary features or tables (schema-change detection, `dbt_models`/`dbt_sources` metadata, the report/UI) stop working, versus which keep working on run-results alone?
4. Is dbt_columns itself an incremental model that only processes new/changed columns after its first full build, so its recurring cost (if any) is small even when it is included in periodic rebuilds?kapa.ai
09/23/2026, 6:29 PMdbt_columns is effectively mandatory if you want disable_dbt_artifacts_autoupload: false to work.
Because dbt_artifacts_hashes is a view that directly unions metadata across the artifact models (including dbt_columns), dbt_columns must physically exist in the warehouse for dbt_artifacts_hashes to compile and query successfully [does anyone know whether it s possible to disable dbt column; Slack forum user question].
Furthermore, upload_dbt_artifacts relies on dbt_artifacts_hashes to check hashes and determine what has changed [artifacts hashes are used for what]. If dbt_artifacts_hashes does not exist or fails to query, the artifacts upload logic cannot execute [Slack forum user question]. There is currently no supported configuration or flag that decouples dbt_artifacts_hashes from dbt_columns while still keeping metadata artifact uploads active [Slack forum user question].
To avoid statement size and memory limits during that initial creation, configure chunking in `dbt_project.yml`:
vars:
insert_rows_method: chunk
dbt_artifacts_chunk_size: 5000
[hello i m getting this error when elementary s p]
2. Is dbt_columns' build cost one-time or recurring? It is primarily a one-time setup cost (and on package upgrades), provided you follow recommended practices.
• You only need to run the model directly (dbt run --select elementary) once on initial deployment or when upgrading package versions [Elementary dbt Artifacts].
• In routine production runs, your dbt command should exclude Elementary models entirely (e.g., dbt build --exclude package:elementary) [can you list me all flags and vars you know of a].
• During normal runs, models are not rebuilt. Instead, the on-run-end hooks handle uploading execution details. If you also set columns_upload_strategy: none or manage metadata uploads separately, you avoid repeating heavy column processing on routine pipeline runs [reduce on-run-end time; planning to implement Elementary in our d].
3. What is lost if you run run-results/invocations without dbt_columns and dbt_artifacts_hashes? If dbt_artifacts_hashes is missing and metadata artifact uploads fail, your project metadata tables will not be populated [when the disable artifact autoupload is paused what tables views don t get updated; what happens if I don t update the artifacts]:
• What continues to work:
◦ elementary_test_results (test passes/failures and metrics)
◦ dbt_run_results (model execution durations, statuses)
◦ dbt_invocations (run times, environment, command-line arguments)
These tables are independent append-only result tables populated by separate hook operations [when the disable artifact autoupload is paused what tables views don t get updated; integrating the Elementary dbt package into our Airflow-orchestrated dbt project].
• What stops working or breaks:
◦ Metadata tables will be empty or outdated: dbt_models, dbt_tests, dbt_sources, dbt_exposures, dbt_metrics, and dbt_columns [when the disable artifact autoupload is paused what tables views don t get updated].
◦ Reports and UI Context: The Elementary UI and reports join execution results (elementary_test_results, dbt_run_results) with metadata tables (dbt_models, dbt_tests) to display model descriptions, owners, tags, and lineage. Without metadata tables, reports and alerts may be incomplete or fail to associate tests with their parent models [what happens if I don t update the artifacts].
◦ Schema change monitors: Alerts or tests that rely on column metadata or schema tracking across runs will lack underlying column reference data [dbt_columns; what happens if I don t update the artifacts].
4. Is dbt_columns incremental and fast on subsequent builds? Yes, dbt_columns is configured as an incremental model and uses hash caching.
• The model definition is materialized as incremental [cannot insert multiple commands into a prepared statement; Slack forum user question].
• It uses a metadata_hash column to detect state changes. On warm, subsequent runs where the project schema has not changed, Elementary skips unchanged artifacts, reducing execution time significantly compared to a cold/full-refresh build [planning to implement Elementary in our d; anyone having issues in CI after upgrading to the latest ver].
• Note: If you run with --full-refresh or use dynamic Jinja expressions (such as now()) in model configurations, the hash cache is invalidated, causing it to re-upload everything from scratch [planning to implement Elementary in our d]. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/23/2026, 6:32 PM@kapa.ai We're about to do the one-time cold build of Elementary's models on a large dbt-Snowflake project (thousands of models and sources), and expectto hit statement-size/memory limits without chunking. We plan to set:dbt_columns
vars:
insert_rows_method: chunk
dbt_artifacts_chunk_size: 5000
Our routine production runs exclude the Elementary package () and rely on the--exclude package:elementaryhooks to upload; we only build the models on initial setup and on package upgrades. Question: should these two chunking vars live permanently inon-run-end, or be passed as one-timedbt_project.ymlonly on the setup/upgrade build?--vars
Specifically:
Doandinsert_rows_methodaffect anything on routine runs where Elementary models are excluded from the selection but the upload hooks still fire? I.e. do the hooks' own inserts (dbt_artifacts_chunk_size,dbt_run_results) also honor these vars, such that setting them permanently changes routine-run behavior — for better or worse?dbt_invocations
Is there any downside to leaving them permanently set — performance, correctness, or upload behavior?
Isa reasonable chunk size for a project of this scale, or is there a recommended value / way to tune it?5000
If we don't set them permanently, does a package upgrade's model rebuild reliably need them again — i.e. is the statement-size problem intrinsic toat this scale, so the failure would recur on every upgrade without them?dbt_columns
kapa.ai
09/23/2026, 6:32 PMdbt_project.yml under the top-level vars: block. [is there a way to chunk the metrics uploading to]
According to Elementary support, setting chunking configurations via CLI flags (--vars) is unreliable because some sample and artifact collection occurs as part of test executions and internal package hooks rather than top-level CLI processing [is there a way to chunk the metrics uploading to]. Placing them under vars: in dbt_project.yml ensures that whenever inserts are executed, the package consistently reads and honors them [is there a way to chunk the metrics uploading to].
2. Do they affect routine runs where models are excluded but upload hooks fire? Yes, the on-run-end upload hooks also honor these variables. [please answer u08s0dle0kt s question i ve added some element; if i have the default vars in my dbt project yml]
insert_rows_method: chunk and dbt_artifacts_chunk_size control the internal insert query generators that Elementary uses across both its model hooks and on-run-end hooks (such as inserting test results and run artifacts) [please answer u08s0dle0kt s question i ve added some element; if i have the default vars in my dbt project yml]. They only affect Elementary's own insertion logic into its observability tables—they do not alter normal dbt models or non-Elementary tests [if i have the default vars in my dbt project yml].
3. Is there any downside to leaving them permanently set? • Correctness: There is no downside; the data written to the warehouse is identical [hi team looks like there is a miss in version 12 1 when the].
• Runtime/Overhead: Splitting a large upload into multiple separate INSERT statements introduces slight network and query-planning overhead compared to a single bulk insert [hello all are there any further details on the causes or fix; hi team looks like there is a miss in version 12 1 when the]. However, in routine runs with thousands of models or tests, attempting unchunked inserts often triggers warehouse expression limits, memory exhaustion, or compilation errors [hello all are there any further details on the causes or fix; hi team looks like there is a miss in version 12 1 when the]. Chunking keeps the memory footprint bounded and avoids hard query failures [hello all are there any further details on the causes or fix].
4. Is 5000 a reasonable chunk size, or how should it be tuned? • Snowflake expression limit: Snowflake has a strict hard limit of at most 16,384 expressions in a single list or query [hi team looks like there is a miss in version 12 1 when the]. Because Elementary metadata inserts (especially column rows) contain multiple values per row, an unchunked batch of tens of thousands of rows reliably throws maximum number of expressions in a list exceeded [hi team looks like there is a miss in version 12 1 when the].
• Is 5,000 appropriate? Elementary maintainers explicitly recommend 5000 as a solid starting point for Snowflake to prevent hitting expression and statement limits [hi team looks like there is a miss in version 12 1 when the].
• Tuning: If you still observe SQL compilation errors, query size errors, or warehouse memory pressure during large test suites or cold builds, lower the size incrementally (e.g., to 1000 or 500) [hi elementary support team we use the dbt cloud and found th; is there a way to chunk the metrics uploading to].
5. If not set permanently, will package upgrades reliably fail? Yes, the statement-size problem is intrinsic to your project scale. [hi team looks like there is a miss in version 12 1 when the]
Whenever Elementary models are rebuilt (during initial setup or package version upgrades), dbt_columns attempts to generate records across all models and sources in your graph [upload dbt columns post hook macro]. In a project with thousands of models and sources, this represents tens of thousands of column rows [hi team looks like there is a miss in version 12 1 when the]. Without chunking configured, Elementary defaults to inserting too many expressions in a single statement, re-triggering the failure on subsequent rebuilds [hi team looks like there is a miss in version 12 1 when the]. Keeping the configuration permanently in dbt_project.yml avoids recurring failures [hi team looks like there is a miss in version 12 1 when the]. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/23/2026, 9:43 PMtest_results table?kapa.ai
09/23/2026, 9:43 PMelementary_test_results (which primarily contains test metadata, run status, and error counts); instead, raw failing row samples are stored in the dedicated test_result_rows table [test_result_rows docs; Linen thread].
Elementary manages and protects PII in test samples through several configuration options:
1. Automatic PII Protection via Tags You can instruct Elementary to automatically disable sample collection when a PII tag is detected by configuring dbt_project.yml [Test Result Samples]:
vars:
disable_samples_on_pii_tags: true # Enable PII protection (default: false)
pii_tags: ['pii', 'sensitive'] # Tags to treat as PII (default: ['pii'])
Tag evaluation is case-insensitive and can be applied at three levels [Test Result Samples]:
• Model level: Tags on a model disable sample collection for all tests on that model.
• Column level: Tags on a column disable samples for tests that reference that column.
• Test level: Tags directly on a test disable sample collection for that specific test.
• Directory level: Entire directories can be tagged in dbt_project.yml (e.g., +tags: ['pii']).
2. Selective Sample Collection (show_sample_rows) As an alternative, you can invert the behavior so all test samples are hidden by default and only collected for explicitly tagged resources [Selective Samples]:
vars:
enable_samples_on_show_sample_rows_tags: true
show_sample_rows_tags: ['show_sample_rows']
3. Disabling Sample Collection Globally or Per-Test • Globally: Set the sample count to 0 in dbt_project.yml to prevent collecting any raw row samples across the entire project [Test Result Samples]vars
test_sample_row_count: 0
• Per-test: Disable sample collection for a specific test using the disable_test_samples: true or test_sample_row_count: 0 meta configuration [Test Result Samples]models
- name: user_profiles
data_tests:
- elementary.volume_anomalies:
config:
meta:
disable_test_samples: true
4. Elementary Cloud Controls and Storage Isolation For Elementary Cloud users:
• Environment-level disablement: The Elementary team can disable test sample syncing entirely for specific environments, ensuring no sample rows leave your data warehouse [Elementary Cloud Controls].
• Skip database storage: Samples can be stored only in your data lake (S3) and not loaded into the Elementary application database [Elementary Cloud Controls].
• US Storage: Customers can opt to store failed row sample S3 buckets in the US (us-east-1) rather than the default EU (eu-central-1) region [Samples storage in the US]. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/23/2026, 10:31 PMkapa.ai
09/23/2026, 10:31 PMon-run-end upload hooks during local development and enabling them only for production/monitored environments to speed up workflows and prevent unwanted uploads [Dev/Prod Configuration].
• Control On-Run-End Hooks Guide: Explains how to limit hooks to production or specific targets (target.name != 'prod') to avoid overhead, speed up local development, and reduce costs in non-production environments [Cloud Control Hooks; Data-tests Control Hooks].
• Reduce On-Run-End Hooks Time Guide (OSS): Details the available configuration variables (disable_run_results, disable_tests_results, disable_dbt_artifacts_autoupload, disable_dbt_invocation_autoupload) and cautions to only disable hooks for runs you do not want to monitor, such as local development [Reduce On-Run-End Time].
• Elementary on-run-end hooks documentation: Outlines disabling result and artifact model updates and confirms you can pass --vars '{"disable_dbt_artifacts_autoupload": true}' conditionally or via the command line for specific invocations [On-Run-End Hooks].
• Community Discussions:
◦ Discusses using target.name conditions or environment variables (ENABLE_ELEMENTARY) to disable models and hook uploads during local or non-production execution [Disable with Env Var; Toggle Elementary per Env].
◦ Explains setting upload variables globally or per-target to prevent non-production runs from populating artifact and test tables [Dev/Prod Artifact Control; Global vs Target Upload Control]. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/25/2026, 5:04 AMkapa.ai
09/25/2026, 5:05 AMdbt_snapshots specifically for projects that don't use snapshots. However, based on what the knowledge sources do confirm about disabling individual Elementary models, here is what applies:
You can disable it via +enabled: false The knowledge sources confirm that individual Elementary artifact models can be disabled in dbt_project.yml using the standard dbt +enabled config [How to disable metadata tables]:
models:
elementary:
edr:
dbt_artifacts:
dbt_snapshots:
+enabled: false
Important caveats to check before doing so Before disabling dbt_snapshots, the knowledge sources highlight two risks that apply to any individual artifact model disablement:
1. Dependency on `dbt_artifacts_hashes`: dbt_artifacts_hashes unions across the artifact models. Disabling dbt_columns was confirmed to break dbt_artifacts_hashes with a compilation error because of this union dependency [Slack forum user question]. Whether dbt_snapshots is also referenced in that union is not confirmed in the knowledge sources — you should inspect your installed dbt_artifacts_hashes view definition before disabling it.
2. Hook behavior if the table is absent: If dbt_snapshots is referenced by any upload macro and the table does not exist, the hook may either error or silently skip uploads [difference between disable_dbt_artifacts_autoupload and edr enabled].
Safer alternative Rather than disabling the model entirely, the safer and more commonly recommended approach is to exclude it from builds via CLI while leaving it enabled in `dbt_project.yml`:
dbt run --select elementary --exclude dbt_snapshots
This avoids any compilation or dependency issues while still preventing the model from being built unnecessarily. [How to disable metadata tables]
I'd recommend verifying the dbt_artifacts_hashes dependency question directly with the Elementary team in their #C02CTC89LAX before committing to +enabled: false on dbt_snapshots. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/25/2026, 11:59 PMkapa.ai
09/25/2026, 11:59 PMon-run-end deployment duration.
1. Disable Metadata Artifact Auto-Uploads Metadata artifacts (dbt_models, dbt_tests, dbt_sources, etc.) only need to be uploaded when your project structure changes—not on every execution [Reduce On-Run-End Time; Control On-Run-End Hooks]. To prevent them from running on every deploy, set:
# dbt_project.yml
vars:
disable_dbt_artifacts_autoupload: true
[Reduce On-Run-End Time; Troubleshooting]
This leaves your run results, test results, and invocations active on routine runs, which upload significantly faster [Reduce On-Run-End Time; Linen thread].
2. Upload Artifacts Only When the Graph Changes After disabling auto-upload, refresh project metadata only when your project definition changes (e.g., during image build/deploy, after merging schema changes, or via a scheduled daily/hourly job) using:
dbt run --select elementary.edr.dbt_artifacts
or:
dbt run --select elementary --vars '{"enable_elementary_models": true}'
[Linen thread; Reduce On-Run-End Time]
Running elementary.edr.dbt_artifacts explicitly updates only the metadata tables (like dbt_models, dbt_tests, dbt_sources) without re-running other package models [Linen thread].
Additional Official Strategies to Reduce Run Duration • Disable column auto-upload (often the biggest win): If you are not using Elementary Cloud's column-level features, the dbt_columns table can add substantial overhead to on-run-end. You can disable it withvars
columns_upload_strategy: none[Troubleshooting; Planning stack thread]
• Offload test table cleanup: If you run many tests, cleaning up temporary test tables during on_run_end can add notable time. You can disable it during runs and offload it to a scheduled operationvars
clean_elementary_temp_tables: falseThen run the cleanup in a dedicated off-peak job:dbt run-operation elementary.cleanup_stale_test_tables[Disable test table cleanup]
• Avoid dynamic expressions in model configs: Dynamic Jinja expressions like now() or CURRENT_TIMESTAMP invalidate the metadata hash cache on every run, forcing complete re-uploads [Planning stack thread]. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/26/2026, 12:23 AMdbt_columns run that that costs the most.
*`dbt_columns`191 s*86,994 columns processed and compared, then 8 rows written.
Any strategies for reducing or offsetting the deployment costs? If so, what are the trade-offs?kapa.ai
09/26/2026, 12:23 AMdbt_columns, along with the associated trade-offs:
Strategy 1: Disable Column Metadata Collection Entirely (Recommended) The most effective and widely recommended strategy to cut dbt_columns runtime is to disable column metadata uploads [Linen thread; Planning stack thread].
Add the following to your `dbt_project.yml`:
vars:
columns_upload_strategy: none
[Linen thread; Linen thread]
• How it helps: Stops Elementary from collecting and uploading column metadata to dbt_columns, eliminating the processing and comparison of your ~87,000 columns during on-run-end [Linen thread].
• Trade-offs:
◦ The dbt_columns table will not be populated or updated [Linen thread].
◦ Features or tests that rely specifically on column-level catalog metadata (such as column metadata exploration in Elementary Cloud or automated schema change tests tracking column additions/removals) will not function or will show stale information [Linen thread; Linen thread].
◦ Standard test results, model execution results, run durations, alerts, and the OSS UI/report will continue working as normal [Linen thread; Linen thread].
Strategy 2: Exclude dbt_columns from Builds and Decouple Deployments If you must retain column metadata in Elementary, do not run the model during normal deployment runs.
1. *Exclude it from routine CI/CD commands:*dbt build --exclude dbt_columns(or --exclude package:elementary so no Elementary models build during standard deploys) [Slack thread; Linen thread].
2. Relegate execution to a separate, scheduled job:
Run dbt run --select dbt_columns (or dbt run --select elementary.edr.dbt_artifacts) asynchronously during off-peak hours (e.g., once daily or after major schema merges) [Control On-Run-End Hooks].
• How it helps: Removes the 190+ second overhead completely from the critical deployment path.
• Trade-offs:
◦ Column metadata will be slightly out-of-sync with production models until the asynchronous job runs.
◦ Important caveat: If disable_dbt_artifacts_autoupload is not set, on-run-end may still trigger column metadata extraction. Combining this with columns_upload_strategy: none or disabling metadata artifacts auto-upload is necessary to avoid the hook evaluating it [Planning stack thread; Slack thread].
Strategy 3: Check for Cache Invalidation Triggers Elementary relies on a metadata hash cache to compare columns and only write differences [Planning stack thread]. Even when only 8 rows are written, iterating through 87,000 column nodes in the dbt manifest in Python/Jinja consumes considerable time [Slack thread].
• Avoid dynamic Jinja expressions: Ensure no model or column configurations include dynamic Jinja functions like now(), current_timestamp(), or dynamic tags. These expressions invalidate the cache on every run, forcing complete re-hashing and full metadata re-uploads [Planning stack thread].
• Trade-offs: May require refactoring dynamic model configs to static properties or passing timestamps at run-time rather than embedding them in config blocks. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
09/26/2026, 12:33 AMdbt_columns introduce risk?kapa.ai
09/26/2026, 12:33 AMcolumns_upload_strategy: none stops the collection and upload of column metadata to dbt_columns [if i have the default vars in my dbt project yml]. The staleness of dbt_columns introduces limited, specific risks depending on which features you use:
What Is at Risk • Schema Change Monitors / Column-Level Tracking: Any tests or monitors that rely specifically on column-level catalog metadata or tracking schema changes (such as column additions, removals, or type changes) across runs will lack updated reference data or show stale information [what happens if I don t update the artifacts; if i have the default vars in my dbt project yml].
• Elementary Cloud Column Context: In Elementary Cloud or UI views that offer column metadata exploration, the displayed column definitions and schemas will become stale [Slack forum user question; what happens if I don t update the artifacts].
What Is Not at Risk • Standard Tests and Alerts: Your routine test results, model run results, execution durations, run logs, and general alerts are populated into separate tables (such as elementary_test_results, dbt_run_results, and dbt_invocations) and continue to function normally without updated column metadata [if i have the default vars in my dbt project yml; when the disable artifact autoupload is paused what tables views don t get updated].
• Model/Test/Source Metadata: Other project artifacts (dbt_models, dbt_tests, dbt_sources, etc.) are tracked in separate tables and are not impacted by disabling the column strategy [when the disable artifact autoupload is paused what tables views don t get updated].
Note on Hash Comparisons The knowledge sources do not explicitly detail whether leaving a stale, populated dbt_columns table causes performance or memory issues when dbt_artifacts_hashes queries existing column hashes. However, community discussions confirm that if you are not using Elementary Cloud features that depend on dbt_columns, running a full refresh (dbt run -s dbt_columns --full-refresh) or truncating the table is safe and prevents dbt from pulling massive amounts of existing metadata hashes into memory [Slack forum user question]. 👍 0 button 👎 0 button ℹ️ Tip: Mention @elementary.ai in the thread for follow-ups or DM the app for 1-to-1 help.gabriel.maxwell
10/09/2026, 5:54 PMkapa.ai
10/09/2026, 5:54 PMgabriel.maxwell
10/09/2026, 5:54 PMkapa.ai
10/09/2026, 5:54 PM