Best Practices¶
Dashboard design and development best practices for dbt Charts.
Naming Conventions¶
Dashboard Names¶
- Use lowercase with underscores:
sales_overview, notSales Overview - Be descriptive:
monthly_sales_dashboardis better thandashboard1 - Avoid spaces and special characters
Query Names¶
- Use descriptive names that indicate what data the query fetches:
sales,products,customers - Keep names concise but clear
- Use explicit namespacing (
queries.sales) when needed to avoid collisions
Chart IDs¶
- Use descriptive names:
revenue_by_month, notchart1 - Indicate chart purpose:
sales_trend,kpi_revenue - Be consistent with naming patterns
Variable Names¶
- Use clear, descriptive names:
region,date_range,min_revenue - Avoid abbreviations unless widely understood
- Use snake_case consistently
Organization Strategies¶
Group Related Queries¶
Keep queries for the same domain together:
queries: # Sales queries sales: ... sales_by_region: ... # Product queries products: ... product_categories: ...
Use Tabs for Logical Grouping¶
Break dashboards into logical groups with tabs (or details for collapsible groups):
tabs: items: - title: "Overview" rows: [kpi_row] # High-level KPIs - title: "Trends" rows: [trend_chart] # Time series charts - title: "Details" rows: [detail_table] # Detailed tables
Add Notes¶
notes: is available on every object, boards, charts, queries, variables, and
layout items, and it's metadata for AI search and maintainer context, not
end-user copy. It never appears in the rendered board, except at the board
level, where Cloud surfaces it in the dashboard-card hover overlay on the
project/home listing. The rule: if something displays, it has a display name
(title, subtitle, label, text); if it doesn't display, it's notes.
title: "Sales Dashboard" notes: "Monthly sales metrics and trends by region"
Performance Optimization¶
Limit Query Results¶
Add a LIMIT clause when you don't need all rows:
queries: sales: sql: | SELECT month, SUM(revenue) AS total_revenue FROM dundersign.orders GROUP BY month LIMIT 100 -- Only fetch 100 rows
Reuse Queries¶
Multiple charts can reference the same query (more efficient):
queries: sales: sql: | SELECT month, region, SUM(revenue) AS total_revenue FROM dundersign.orders GROUP BY month, region charts: chart1: type: bar x: month y: total_revenue query: sales # Same query chart2: type: line x: month y: total_revenue query: sales # Same query rows: [chart1, chart2]
Use Time Grain¶
Bucket timestamps to the grain you need directly in SQL:
queries: monthly: sql: | SELECT DATE_TRUNC('month', order_date) AS month, SUM(revenue) AS total_revenue FROM dundersign.orders GROUP BY 1
Filter Early¶
Filter in the query, not the chart:
queries: filtered: sql: | SELECT status, COUNT(*) AS ticket_count FROM dundersign.tickets WHERE {{ filter('status', status) }} AND {{ filter_date_range('created_at', date_range) }} GROUP BY status source: warehouse
User Experience¶
Provide Defaults¶
Set sensible default values for variables:
variables: region: default: "North" # Show useful data by default date_range: input: daterange default: ["2024-01-01", "2024-01-31"] # a daterange default is a [start, end] list
Use Appropriate Input Types¶
Match input types to use cases:
- Select: Single choice from predefined list
- Slider: Numeric ranges
- Date range: Time period selection
- Checkbox: Simple on/off flags
Add Notes¶
A chart-level notes: documents intent for AI search and tooling; it never renders:
charts: revenue_chart: title: "Revenue by Month" notes: "Monthly revenue trends over the past 12 months" query: sales type: bar
Test Interactions¶
Verify click actions and filters work as expected:
- Test all variable combinations
- Verify chart interactions
- Check filter behavior
- Test on different screen sizes
Common Patterns¶
Summary + Detail¶
Show high-level summary with drill-down detail using tabs:
tabs: items: - title: "Summary" rows: [summary_kpi] - title: "Details" rows: [detail_table]
For click-through drill-down instead of tabs, use chart-level link:; see Interactions.
Time Series with Filters¶
Combine time series with filters:
variables: date_range: ... queries: trends: sql: | SELECT month, tickets_created FROM dundersign_serving.monthly_metrics WHERE {{ filter_date_range('month', date_range) }} ORDER BY month source: warehouse charts: trend_chart: query: trends type: line x: month y: tickets_created
Comparison Views¶
Compare metrics side by side:
charts: comparison: query: sales type: bar x: month y: total_revenue color: region # Compare regions
Anti-Patterns to Avoid¶
❌ Missing Query References¶
charts: chart1: type: bar x: month y: revenue query: nonexistent # Error: query doesn't exist
❌ Missing Source¶
queries: sales: sql: SELECT * FROM orders # Error: no source configured for this query
❌ Circular Dependencies¶
variables: var1: default: "{{ var2 }}" # var2 depends on var1 - circular! var2: default: "{{ var1 }}"
❌ Missing Required Fields¶
charts: chart1: # Missing: query, type x: month
❌ YAML Syntax Errors¶
Common mistakes: - Wrong indentation (use spaces, not tabs) - Missing colons - Unquoted special characters
Version Control Best Practices¶
Commit Dashboard Files¶
Dashboard YAML files are version-controlled: - Commit dashboard changes with model changes - Use descriptive commit messages - Review dashboard changes in PRs
Organize by Feature¶
Group related dashboards:
Document Changes¶
Add comments for complex logic:
queries: complex: sql: | SELECT COUNT(*) AS ticket_count FROM dundersign.tickets WHERE status = 'new' -- open tickets only AND ticket_type = 'incident' source: warehouse
Development Workflow¶
Validate Before Committing¶
Always validate your dashboards before committing:
See the CLI Reference for validation options.
Inspect Resolved Output for Debugging¶
When troubleshooting, render the dashboard to JSON to see the resolved layout, charts, and executed query data:
See the CLI Reference for rendering options.
Preview While Developing¶
Use the serve command for fast iteration:
dct serve auto-discovers the project and prints the URL on startup. See the CLI Reference for server options.
Related¶
- CLI Reference - Complete CLI command reference
- Troubleshooting Guide - Common issues and solutions
- YAML Style Guide - YAML formatting best practices
- Queries Guide - Query best practices
- Charts Guide - Chart best practices
- Examples - Example dashboards