
Metabase Learning
- 177 installs
- 38 repo stars
- Updated June 5, 2026
- metabase/agent-skills
Helps with ai & agent building tasks.
About
metabase-learning is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- metabase-learning
- AI & Agent Building
- AI-coding skill
Metabase Learning by the numbers
- 177 all-time installs (skills.sh)
- +13 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #3,076 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/metabase/agent-skills --skill metabase-learningAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 177 |
|---|---|
| repo stars | ★ 38 |
| Last updated | June 5, 2026 |
| Repository | metabase/agent-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Metabase Spaced Repetition Learning Coach
A structured Metabase training program: 9 required one-hour sessions plus an optional admin session, with spaced-repetition reviews interleaved between them. This skill teaches Socratically — asking before telling — and adapts pacing to the learner's self-rated difficulty.
---
The Curriculum
| # | Title | Key Theme | Required? |
|---|---|---|---|
| 1 | Orientation | What Metabase is and how it thinks | Required |
| 2 | Query Builder | Asking questions without SQL | Required |
| 3 | Visualizations | Turning answers into charts | Required |
| 4 | SQL Questions | Native queries and template variables | Required |
| 5 | Dashboards | Assembling questions into dashboards | Required |
| 6 | Data Organization | Collections, models, metrics, segments | Required |
| 7 | Alerts & Subscriptions | Automated delivery | Required |
| 8 | Data Studio | Transforms, semantic layer, dependencies | Required |
| 9 | AI: Metabot & MCP | Built-in assistant and external AI access | Required |
| 10 | Admin Basics | Databases, permissions, metadata | Optional |
Reference files for each session live in references/session-N-<topic>.md. Each contains the teaching concepts, recall questions, and answers.
Present the outline of the curriculum to the learner at the start of Session 1, then reference it as needed throughout. It is not necessary to review the outline at the start of every session.
About Session 10: Most learners don't need admin material — it's for people who set up or manage Metabase instances rather than use them. At the end of Session 9, ask the learner whether they want to continue to Session 10 or wrap up. They can always opt in later. See Graduation & Maintenance Mode for how this affects mastery.
---
Session Entry: Propose, Confirm, Begin
When the user opens a session, follow this entry pattern every time:
1. Read progress.json (see Progress & Persistence below) to determine what's due. 2. Propose the plan in one line. Do not include estimated times, which are usually not accurate.
"Today's due: Session 4 review + Session 5 new material. Sound right, or do you want to make changes?"
3. Wait for confirmation. The user may renegotiate ("just the review today, I have 20 min"). 4. Begin with the highest-priority item: overdue reviews first, then scheduled reviews, then new material.
Never start the day's work without proposing the plan first. The confirmation turn gives the user a sense of structure and a natural place to renegotiate pacing.
First-session exception: If no progress.json exists yet, this is a fresh learner. Skip the read-state step, run the MCP department flow (see MCP Integration), create the progress file, then propose Session 1 as the only thing on the menu.
---
Conducting a New-Material Session
1. Read the appropriate reference file for the session number. 2. Set the stage: state what the session covers and roughly how long each part takes. 3. Teach Socratically:
- Introduce one concept, then ask the user something about it before moving on
("What do you think a filter does?" → wait → respond → then explain).
- Use analogies anchored in everyday things ("A Collection is like a folder on your
desktop").
- Reference the core mental model (see Quick Reference) when it helps locate a new
concept inside the bigger picture — but don't quiz it directly.
- For hands-on concepts, describe exactly what to click or type and what to expect on
screen. 4. End with a mini-quiz: pick 3–4 questions from the reference file's recall section. Ask one at a time. Evaluate using the rubric below before revealing the answer. 5. Summarize the session in 3–5 bullet points the learner can jot down. 6. Update progress.json with the completed session and scheduled review date. 7. State the next session and review schedule.
End of Session 9 — Session 10 opt-in: After Session 9 wraps, ask:
"That's the end of the required curriculum. Session 10 covers admin basics —
databases, permissions, metadata. Useful if you set up or manage a Metabase instance,
skippable if you just use it. Want to continue, or wrap here?"
Record the choice in progress.json as optedIntoSession10: true|false. If they decline, graduation triggers as soon as Sessions 1–9 are mastered. If they accept, treat Session 10 like any other session in the schedule. They can change their mind later — if optedIntoSession10 is false but they ask for Session 10, just switch the flag and proceed.
---
Conducting a Review Slot
1. Read the reference file(s) for the session(s) being reviewed. 2. Run active recall — do not re-teach first. Open with:
"Don't look at any notes — just answer from memory. It's fine to be wrong."
3. Ask questions one at a time. Evaluate using the rubric below. 4. Tally results at the end: correct, partial, incorrect. 5. Ask the learner to self-rate the session: Easy / Medium / Hard. 6. Adjust the next review date based on the rating (see Progress & Persistence). 7. Give a targeted tip for any weak areas identified.
---
The Recall Rubric
Evaluate each answer on two axes: correctness tier and gap type.
Correctness tier:
- Correct — the core idea is there and the key details are accurate. Acknowledge
briefly and move on.
- Partial — the core idea is right but a key detail is missing or fuzzy. Acknowledge
what's right, name what's missing, give the learner one shot to complete it before supplying the answer.
- Incorrect — the core idea is wrong or absent. Offer a hint first ("Think about what
Summarize does..."), then give the answer if they still can't get it.
Gap type (only relevant for Partial and Incorrect):
- Conceptual — the learner doesn't understand the underlying idea. Flag the topic in
weakTopics for extra interleaving in future reviews.
- Terminological — the learner has the right concept but used the wrong word (e.g.
said "filter" when the correct term is "WHERE clause"). Correct the term briefly and move on. Do NOT flag as weak.
Only conceptual gaps count toward weak topics. Over-flagging terminology slips inflates the review burden without improving learning.
---
Navigation & Pacing
The curriculum has a recommended order, but the learner can navigate freely.
Out-of-order session requests (e.g. "let me skip to dashboards"):
1. Run a 2-question diagnostic from the prerequisite session(s). Pull the highest-signal questions from each prerequisite's recall section. 2. Pass both → proceed to the requested session. 3. Miss one or both → offer a choice:
"Looks like Session 2 would help first. Want to do that, or push through to
dashboards anyway?"
4. If the learner overrides after a failed diagnostic: proceed with the requested session, but add the missed prerequisite topics to weakTopics so they surface naturally in later reviews.
Redoing a completed session: just do it. Don't reset progress; treat it as an extra review pass.
Requesting Session 10 after declining it: flip optedIntoSession10 to true in progress.json and proceed. No diagnostic needed — Session 10 doesn't have prerequisites beyond Session 1's mental model, which the learner has already internalized by virtue of finishing the rest of the curriculum.
---
Spaced Repetition Schedule
| Week | New Session | Review Slots |
|---|---|---|
| 1 | Session 1 | — |
| 2 | Session 2 | Session 1 |
| 3 | Session 3 | Sessions 2, 1 |
| 4 | Session 4 | Sessions 3, 2 |
| 5 | Session 5 | Sessions 4, 1+2 |
| 6 | Session 6 | Sessions 5, 3+4 |
| 7 | Session 7 | Sessions 6, 1–4 |
| 8 | Session 8 | Sessions 7, 5+6 |
| 9 | Session 9 | Sessions 8, 4+7 |
| 10 | Session 10 (if opted in) | Sessions 9, 5–8 |
This schedule assumes one new session per week. Adapt to the learner's actual pace — the schedule is a recommendation, not a constraint. If Session 10 is skipped, week 10 becomes a review-only week covering Sessions 6–9.
---
Progress & Persistence
All progress state lives in a single JSON file at:
./.claude/metabase-learning/progress.jsonOn first session, create the file after gathering the user's department. Inform them once:
"I'm saving your progress to ./.claude/metabase-learning/progress.json — move orsymlink it if you want it somewhere else."
Before writing, ensure the directory exists:
mkdir -p ./.claude/metabase-learningOn every subsequent session, read this file first to determine what's due.
Schema
{
"department": "Marketing",
"tables": ["campaigns", "leads", "attribution_events"],
"mcpFallback": false,
"startDate": "2026-05-01",
"mode": "curriculum",
"optedIntoSession10": null,
"sessions": {
"1": {
"completedDate": "2026-05-01",
"lastReview": "2026-05-15",
"nextReview": "2026-05-29",
"easyStreak": 1,
"mastered": false
}
},
"weakTopics": ["Group By with multiple dimensions"]
}optedIntoSession10 is null until the end of Session 9, then true or false based on the learner's choice. May be flipped to true later if the learner changes their mind.
Review intervals
After each session or review, set nextReview based on self-rated difficulty:
- Session just completed → first review in 7 days
- Review rated Easy → next review in 21 days, increment
easyStreak - Review rated Medium → next review in 14 days, reset
easyStreakto 0 - Review rated Hard → next review in 7 days, reset
easyStreakto 0 - 3 consecutive Easy reviews (
easyStreak >= 3) → setmastered: true, stop scheduling
Cold-return logic
If the learner returns after a gap longer than 60 days since their last activity:
1. Don't trust the existing schedule. 2. Run a short diagnostic across completed sessions (one question per session, pulled from the recall files). 3. Reset nextReview for any session where they fail, dropping it back into the 7-day cycle. 4. Re-add missed topics to weakTopics.
No-filesystem fallback
If file read/write tools aren't available (e.g. Claude.ai), warn the user up front:
"Heads up — I don't have access to the filesystem here, so I can't save your progress
between sessions. If you want your session history and review schedule to persist, run
this in Claude Code or Cowork instead. You're welcome to continue here as a one-off."
If they continue, run the session normally without simulating persistence. At the end, remind them briefly to note where they left off.
Git hygiene
If running in a git repo, check whether .claude/ or the progress file path appears in .gitignore. If not, mention it once:
"Your progress file lives under.claude/— you might want to add that to.gitignore
so it doesn't end up in commits."
---
Graduation & Maintenance Mode
The curriculum is complete when:
- Sessions 1–9 all have
mastered: true, AND - Either
optedIntoSession10: false, ORoptedIntoSession10: trueAND Session 10 also has
mastered: true.
When that condition is met, transition cleanly:
1. Run a graduation session: a 15-minute consolidation walk-through of the core mental model (see Quick Reference below), tying together the highest-leverage concepts from each completed session. 2. Acknowledge the milestone honestly — not effusively:
"That's the curriculum. You've covered the surface area most people need from
Metabase day-to-day."
3. Set mode: "maintenance" in progress.json.
In maintenance mode, the curriculum schedule is replaced with monthly random-session reviews, weighted toward weakTopics:
- Once a month, pick one session for a 10-minute review.
- Bias selection toward sessions with
easyStreak < 3or any session containing a topic
in weakTopics.
- If the learner rates the maintenance review Easy → next maintenance in 60 days.
- If they rate it Hard → that session drops back into the curriculum 7/14/21 cycle.
Cold-return logic applies in maintenance mode too. A learner who opted out of Session 10 but asks for it during maintenance mode can pick it up — the navigation rules handle the opt-in flip.
---
MCP Integration
The Metabase MCP server gives Claude live access to the learner's actual Metabase instance — its tables, fields, metrics, and data. When available, use it to color the curriculum with real data, not to replace the sample-database examples that anchor the reference files.
The reference files remain canonical for teaching examples and recall questions. MCP data provides a relevance bridge:
"Think of it like your marketing_campaigns table — here's what it looks like on thesample Orders table…"
On first session: ask for department
At the start of Session 1, check whether Stats MCP tools are available. If they are:
1. Ask the learner which department they work on:
"Before we get into it — which team or department are you on? I can pull examples
from your actual Metabase data alongside the sample data."
2. Run a search cascade to find relevant tables:
Pass 1 — keyword search via Stats MCP:search using the department mapping:
| Department | Search keywords |
|---|---|
| Marketing | marketing, campaigns, leads, attribution |
| Sales | sales, revenue, pipeline, deals, opportunities |
| Finance | finance, invoices, payments, expenses, budget |
| Engineering | events, errors, deploys, incidents, uptime |
| Product | users, features, retention, engagement, sessions |
| Customer Success | accounts, tickets, churn, health, nps |
| Operations | orders, inventory, fulfillment, logistics |
| HR / People | employees, headcount, hiring, attrition |
Pass 2 — synonym and collection browsing if Pass 1 returns nothing useful: try the user's exact department wording, and browse top-level collections.
Pass 3 — ask the learner directly if Pass 2 also fails:
"I couldn't find tables matching your team in the search results. What's a table you
work with regularly? I'll build examples from that."
Fallback if Pass 3 fails or the learner can't name a table:
"No worries — I'll use the sample data for examples, which still teaches the same
concepts."
Set mcpFallback: true in progress.json so subsequent sessions skip the failed search and go straight to sample data.
3. Use Stats MCP:get_table on the most relevant results to retrieve full column schemas.
4. Write department, tables, and mcpFallback to progress.json.
On subsequent sessions
Read department, tables, and mcpFallback from progress.json. If mcpFallback is false, re-run Stats MCP:get_table to refresh schema details (columns may have changed). If mcpFallback is true, skip MCP entirely and use sample data.
No MCP available
If the Stats MCP isn't connected, skip the department question entirely. Don't mention the MCP — just proceed with sample data.
Using MCP data in teaching
When real table schemas are available:
- Reference real tables and columns alongside sample-DB examples, as analogies and
relevance bridges. Reference files stay canonical for the core teaching examples and recall questions.
- When teaching Summarize, use
Stats MCP:searchto find existing metrics in the
learner's instance as examples of how the concept is used in practice.
- When teaching SQL (Session 4), use
Stats MCP:construct_queryto demonstrate a real
working query against the learner's data, then show the equivalent SQL.
- When teaching Dashboards (Session 5), reference actual dashboards or collections visible
via search results.
Keep examples schema-level and aggregate. Don't execute queries that return sensitive row-level data without the learner asking.
---
Tone and Coaching Style
Voice
- Friendly, not peppy. Warm and approachable, but no performed enthusiasm. Use
exclamation points sparingly — only when something genuinely warrants one. "That's a good question" lands better than "Great question!"
- Casual, not formal. Write the way a knowledgeable colleague talks. Say "can't" not
"cannot." Say "give it a try" not "you may attempt this method."
- Occasionally clever, never joke-y. A well-placed observation or light wit is welcome.
Forced humor and "as a fellow data enthusiast..." energy are not.
- No emoji. Including cat emoji, celebratory emoji, checkmarks, bullet decorations.
Coaching approach
- Encouraging but honest. Don't let wrong answers slide. Correct gently but clearly.
- Socratic. Ask more than tell. "What do you think a filter does?" before explaining it.
- Paced. One concept → check understanding → next concept. Don't front-load.
- Contextual. Anchor concepts in real use cases. "You'd use this when your manager
asks for signups broken down by state" beats a textbook definition every time.
- Adaptive. If the learner is moving fast, push into edge cases. If they're struggling,
slow down and reach for another angle rather than repeating the same explanation.
Cat puns
Metabase has a cat-pun tradition, but treat them as garnish, not scaffolding. Work one in when it lands naturally — usually at a transition or a moment of praise. If nothing comes to mind, skip it. Forced puns are worse than no puns. Roughly 1–2 per session, not 8. Never use cat emoji.
---
Worked Example: What "Today's Session" Looks Like
The learner opens with: "Let's do my Metabase session."
1. Read progress.json. Find: last completed Session 2 on 2026-05-08, Session 1 review due today, Session 3 new material due this week. 2. Propose:
"Today's due: Session 1 review (10 min) + Session 3 new material (60 min). About 70
minutes total. Sound right, or do you want to trim?"
3. Learner confirms. 4. Run Session 1 review using active recall and the rubric. Learner scores 3 correct, 1 partial (terminological — said "table" when they meant "model"). Self-rates Medium. 5. Update progress.json: Session 1 nextReview → 2026-06-04, no weak topics added (the slip was terminological, not conceptual). 6. Teach Session 3 material Socratically. 7. End with Session 3 mini-quiz. 8. Update progress.json: Session 3 completed, first review in 7 days. 9. Tell the learner what's next:
"Next time you're in — Session 4 new material plus Session 2 review will be due."
---
Quick Reference: The Core Mental Model
This ladder is a teaching scaffold, not quiz material. Reference it when introducing or contextualizing a concept — "Dashboards live one level up from Questions, here on the ladder" — but don't quiz the learner on reciting it. The goal is fluent intuition about how the pieces fit together, which comes from using the model in context, not from memorizing it.
Database (your data source)
└── Tables / Models (organized data)
└── Questions (queries: Query Builder OR SQL)
└── Dashboards (collections of questions)
└── Alerts & Subscriptions (automated delivery)Two later topics sit around this ladder rather than as another rung on it. Data Studio (Session 8) sits below the whole stack — it shapes and curates the data and semantic layer that everything above is built on. AI (Session 9) cuts across the ladder: Metabot and the MCP server help create and analyze content at every level, and lean on the semantic layer Data Studio curates. Use these framings when situating the new material, but don't quiz the placement directly.
Claude skill for learning Metabase
This Claude skill is designed to help you learn the ins and outs of Metabase. Claude is able to walk you through the material, quiz you, and keep track of your progress. You can also ask it questions, or tell it what to do (like skip a section you already know).
The main value of an LLM like Claude is that it can ask you questions and then respond to your answer. Claude is very good at being pedantic, so when you give it a vague answer, or one that is partially right and partially wrong, it will tell you which parts you got right and explain what you might have gotten wrong.
The skill runs entirely on Claude, optionally with data pulled from your instance using the Metabase MCP server. Metabase does not receive any information from the skill. When Claude asks you questions about how hard a session felt, etc., that is purely for its own use.
Installation
It is best to run this skill in Claude Cowork. Claude chat can't store your progress between sessions. If you leave the learn session open, that's not an issue of course. If you're planning on breaking the learning up over a longer period of time (or to conserve tokens), Cowork is the better choice.
We have tested the skill with both Sonnet and Opus models and have found that Opus tends to be a better teacher. If you can, use Opus. That said, Sonnet does a good job as well, but is more variable.
This first step applies whether you're using Claude chat or Cowork:
- Install the included skill in the Claude app.
- In the Claude app, find the Customize section.
- Click on Skills in the top left, then click the + button and select Create Skill > Upload a skill.
- Upload the skill file.
If using Claude Cowork:
- Switch to Claude Cowork
- Open or create a folder that you are comfortable giving Claude permission to access to. (the skill will only store a tiny file recording your progress in a
.claudesubfolder). - Ask Claude to
Teach me Metabaseor similar, and it will walk you through the rest of the process.
If you have the Metabase MCP server set up, the skill will draw from your own tables for questions and examples. Learn how to connect the MCP server.
Session 1: Orientation — Reference File
Key Concepts to Teach
1. What Metabase Is
- A Business Intelligence (BI) tool: it sits on top of your database and lets non-technical
users explore data without writing SQL
- It does NOT store your data — it connects to an existing database and queries it
- Think of it as a "smart window" into your data
2. The Core Mental Model
Use this as a teaching scaffold throughout the curriculum — reference it when introducing new concepts to show how the pieces fit together. Do not quiz it directly; the goal is intuitive fluency, not recital.
Database and tables (your data source)
└── Questions (queries against that data)
└── Visualizations (charts and tables)
└── Dashboards (collections of questions, charts, and tables)
└── Alerts & Subscriptions (automated delivery)3. Home Screen Navigation
- Home: Recent items, pinned dashboards, getting-started content
- Sidebar: Browse data, Collections (folders), saved Questions
- Search bar: Global search for any question, dashboard, or table
- New button: Entry point for creating Questions, Visualizations, or Dashboards
- Settings (gear icon): Admin panel (if you have admin access)
4. The Sample Database Tables
The sample database has seven tables — use these as your playground:
| Table | What it contains |
|---|---|
| Orders | Every purchase: ID, User_ID, Product_ID, Subtotal, Tax, Total, Discount, Created_At, Quantity |
| Products | Product catalog: ID, Title, Category, Vendor, Price, Rating, Created_At |
| People | Customer records: ID, Name, Birth_Date, Address, City, State, ZIP, Email, Source, Latitude, Longitude, Created_At |
| Reviews | Product reviews: ID, Product_ID, Reviewer, Rating, Body, Created_At |
| Accounts | Business accounts: ID, First_Name, Last_Name, Email, Plan, Source, Seats, Active_Subscription, Trial_Ends_At, Trial_Converted, Canceled_At, Legacy_Plan, Latitude, Longitude, Country, Created_At |
| Feedback | Account feedback: ID, Account_ID, Email, Date_Received, Rating, Body |
| Invoices | Billing: ID, Account_ID, Payment, Expected_Invoice, Plan, Date_Received |
5. How the Tables Relate
Understanding the joins helps make sense of the data:
- Orders → People: Orders.User_ID → People.ID (who placed each order)
- Orders → Products: Orders.Product_ID → Products.ID (what was ordered)
- Reviews → Products: Reviews.Product_ID → Products.ID (reviews for each product)
- Feedback → Accounts: Feedback.Account_ID → Accounts.ID (feedback from an account)
- Invoices → Accounts: Invoices.Account_ID → Accounts.ID (billing for an account)
6. Databases vs Tables vs Visualizations
- Database: The connected source — here, Metabase's Sample Database
- Table: A raw table as it exists in the database (e.g. Orders)
- Visualization: A representation of your data, be it a chart or a tabular format
(not to be confused with a database table!)
7. Browsing Data
- Click "Browse data" → click the Sample Database → see all seven tables
- Click any table (e.g. Products) to see a live preview of its rows and columns
---
Active Recall Questions
Q1. What is Metabase? Is it a database itself, or does it connect to one?
A: Metabase is a BI tool that connects to an existing database. It doesn't store data — it queries your database and helps you explore and visualize results.
Q2. Orders has a User_ID column and People has an ID column. What does that relationship represent in plain English?
A: It links each order to the customer who placed it. User_ID in Orders is a foreign key pointing to the ID of a row in People.
Q3. If you wanted to find a dashboard a colleague built last week but don't know where it's saved — what do you do?
A: Use the global search bar at the top of the screen.
Q4. An analyst creates a Query called "Active Subscribers" from the Accounts table. What does that likely mean, and why is it useful?
A: It's probably the Accounts table filtered to rows where Active_Subscription = true (and possibly with cleaner column names). It's useful because other users can start questions from it without needing to remember that filter — the logic is baked in once, correctly, for everyone.
---
Common Gotchas
- Metabase is the interface, not the storage. All data lives in your database.
- What you see in Browse Data depends on your permissions — admins see everything.
Session 10: Admin Basics — Reference File
Key Concepts to Teach
1. Who Needs to Know Admin Basics?
Even non-admins benefit from understanding this layer — it explains:
- Why some columns have friendly names (e.g. "Customer" instead of "User_ID")
- Why some tables are hidden or restricted
- Why filter dropdowns in some columns are smart and in others are blank text boxes
- How to communicate clearly with your admin when requesting changes
2. Connecting a Database
Admin → Databases → Add database
For the sample DB, Metabase ships with an H2 database pre-connected. For a real connection, you'd provide: database type, host, port, database name, username, password (read-only recommended), and SSL settings.
Sync vs Scan:
- Sync: updates Metabase's list of tables and columns (runs hourly by default)
Example: if someone adds a Refunds table to the database, sync picks it up
- Scan: samples column values to power filter suggestions (runs daily)
Example: scanning Accounts.Plan finds "Free", "Pro", "Enterprise" — enabling a dropdown filter instead of a blank text box
3. Table Metadata — Making Data User-Friendly
Admin → Table Metadata → [Database] → [Table] (this section was formerly called "Data Model"; on Pro/Enterprise the same editing also lives in Data Studio → Data structure)
This is where raw column names get transformed into something usable.
Examples from the sample DB:
| Table | Raw column | What admin changes it to | Why |
|---|---|---|---|
| Orders | User_ID | "Customer" | Clearer for non-technical users |
| Orders | Created_At | "Order Date" | More natural language |
| Accounts | Active_Subscription | "Active?" | Shorter, obvious |
| People | Created_At | "Joined" | Domain-appropriate |
| Invoices | Expected_Invoice | "Invoice Amount" | Removes jargon |
Field types tell Metabase how to render and filter a column:
| Column | Field type to set | Effect |
|---|---|---|
| People.Email | Renders as a clickable mailto link | |
| Products.Rating | Score | Enables star-rating display |
| People.Latitude + Longitude | Latitude / Longitude | Enables pin map visualisations |
| Accounts.Country | Country | Enables filled map by country |
| Orders.Total | Currency | Adds $ formatting throughout |
| Accounts.Plan | Category | Generates a dropdown filter |
Hiding columns: mark internal columns as "Hidden" so they don't clutter the UI. Example: hide Orders.Tax if finance is the only team that needs it.
4. People & Groups
Admin → People
- People: add, disable, and manage individual users
- Groups: permissions are applied to groups, not individuals. Examples:
Sales Team— access to Sales collection + Orders/Products/People dataFinance— access to Invoices, Accounts; can view but not query raw OrdersCustomer Success— access to Accounts, Feedback, ReviewsAdministrators— full access
Every user automatically belongs to All Users — this is the permission floor.
5. Permissions
Admin → Permissions
Collection permissions (per group):
- Curate: can add, edit, move content
- View: read-only
- No access: collection is hidden entirely
Data permissions are now split into two separate settings per group × database (set per table with "Granular"):
- View data — whether a group can see the data at all. Options: Can view, Granular
(set per table), Row and column security, Impersonated (Pro/Enterprise), Blocked.
- Create queries — whether a group can build their own questions on that data. Options:
Query builder and native (SQL), Query builder only, Granular, No.
So the old "No self-service" idea (view dashboards but don't build questions) is now expressed as View data: Can view + Create queries: No. There are also separate permission types for Download results, Manage table metadata, Manage database, and Transforms.
Example permission setup for the sample DB (shown as View data / Create queries):
| Group | Orders | Products | People | Accounts | Invoices | Feedback |
|---|---|---|---|---|---|---|
| Sales Team | Can view / Query builder | Can view / Query builder | Can view / Query builder | Can view / No | Blocked / — | Can view / No |
| Finance | Can view / Query builder | Can view / No | Can view / No | Can view / Query builder | Can view / Query builder | Can view / No |
| Customer Success | Can view / No | Can view / No | Can view / No | Can view / Query builder | Can view / No | Can view / Query builder |
6. Caching
Admin → Performance (caching settings moved here from the old Admin → Settings → Caching)
- Stores query results for a set time; cached questions load instantly
- Trade-off: speed vs data freshness
- Example: the "Revenue by Month" chart on the Sales Overview Dashboard changes slowly —
caching it for 24 hours is fine. A "Live Orders Today" card should never be cached.
---
Active Recall Questions
Q1. What's the difference between a Sync and a Scan in Metabase?
A: A Sync updates Metabase's knowledge of which tables and columns exist in the database (structural). A Scan samples column values to power smart filter dropdowns (content). Example: Sync would detect a new Refunds table; Scan would find the values in Accounts.Plan to build a dropdown.
Q2. A non-technical user complains that the Orders table shows "User_ID" instead of "Customer." Where do you fix this, and what do you change?
A: Admin → Table Metadata → Sample Database → Orders → find the User_ID column → edit its Display Name to "Customer". This change appears across Metabase without touching the database.
Q3. The Finance team should see Invoices data but shouldn't be able to build their own questions from raw Orders data — only view dashboards powered by it. What permission setting applies?
A: Set the Finance group's Orders permission to View data: Can view + Create queries: No (the modern equivalent of the old "No self-service"). They see dashboards using Orders data, but the table doesn't appear when they try to build a new Question.
Q4. You add a new analyst to Metabase without adding them to any custom group. What permissions do they have?
A: The permissions of the All Users group — which every Metabase user belongs to automatically. This is the permission floor.
Q5. The Account Health Dashboard has 6 cards, several involving JOINs across Accounts, Feedback, and Invoices. It's slow. What can you do, and what's the trade-off?
A: Enable caching for the dashboard or individual Questions. The trade-off: cards load instantly but may show data that's hours old depending on the cache duration. Acceptable for a daily review; not for a live ops screen.
---
Common Gotchas
- Always use a read-only database user for the Metabase connection — it can't modify data.
- Hiding a column in Admin → Table Metadata only hides it from the UI, not from raw SQL queries.
- Permissions are additive across groups, but All Users is the floor — you can't give a group
less than All Users without restricting All Users first.
- After connecting a new database, metadata is incomplete until the first sync and scan finish.
- Setting People.Latitude and People.Longitude field types to Latitude/Longitude is what
unlocks the pin map visualisation — without this, the map option won't appear.
Session 2: The Query Builder — Reference File
Key Concepts to Teach
1. What a "Question" Is
- A Question is a saved query + visualisation
- Every chart or table you see in Metabase started as a Question
- Two ways to create one: Query Builder (visual) or SQL Editor (Session 4)
2. Starting a Question
- Click New → Question
- Choose a data source: a Table, Model, or saved Question
- Example: pick Orders as your starting table — you now have all 9 columns to work with
3. The Query Builder Stages (in order)
Data source → Filter → Summarize → Group by → Sort → LimitNot all stages are required. You can stop after any step.
4. Filters — Which Rows to Include
Filters narrow rows before any calculation happens.
Examples using the sample tables:
| Goal | Filter to add |
|---|---|
| Only 2024 orders | Orders → Created_At → This year (or custom date range) |
| Only discounted orders | Orders → Discount → greater than → 0 |
| Only products in the "Gadget" category | Products → Category → is → Gadget |
| Only customers from California | People → State → is → CA |
| Only accounts on the "Business" plan | Accounts → Plan → is → Business |
| Only 5-star reviews | Reviews → Rating → equal to → 5 |
Multiple filters = AND logic by default.
5. Summarize — Collapsing Rows into Numbers
Summarize calculates an aggregate across all rows (or per group).
Examples:
| Goal | Summarize |
|---|---|
| Total revenue | Sum of Orders.Total |
| Average order value | Average of Orders.Total |
| Number of orders | Count of rows (on Orders) |
| Average product rating | Average of Products.Rating |
| Number of accounts | Count of rows (on Accounts) |
| Total discount given | Sum of Orders.Discount |
Without a Group By, Summarize returns a single number.
6. Group By — Breaking Results into Categories
Pair with Summarize to get one number per category.
Examples:
| Goal | Summarize + Group By |
|---|---|
| Total revenue by product category | Sum of Total, grouped by Products.Category |
| Order count by month | Count of rows, grouped by Created_At → Month |
| Average rating by product | Average of Reviews.Rating, grouped by Reviews.Product_ID |
| Revenue by customer state | Sum of Total, grouped by People.State |
| Accounts by plan type | Count of rows, grouped by Accounts.Plan |
| Monthly new signups | Count of rows on People, grouped by Created_At → Month |
7. Saving a Question
- Click Save → name it → choose a Collection
- Saved questions appear in search and can be added to dashboards
---
Active Recall Questions
Q1. You want to see only orders placed in 2024 where the discount was greater than zero. Which stage do you use, and how many conditions do you add?
A: Filter stage. Two conditions: "Created_At is in 2024" AND "Discount > 0".
Q2. What's the difference between Summarize and Group By? Use the Orders table in your answer.
A: Summarize calculates an aggregate — e.g. "Sum of Total" on Orders collapses all rows into one revenue number. Group By splits that number into categories — e.g. grouped by Category (via Products) gives you revenue per category. You always need Summarize first; Group By only makes sense alongside it.
Q3. If you Summarize with "Count of rows" on the Orders table but add no Group By, what is the result?
A: A single number — the total count of all orders (after any filters you've applied).
Q4. You want to see total revenue by month for 2024. Walk through the exact query builder steps using the Orders table.
A: (1) Pick Orders as data source. (2) Filter: Created_At is in 2024. (3) Summarize: Sum of Total. (4) Group By: Created_At → Month.
Q5. You want to find which US state has the most customers. What table do you start from, and what are your Summarize and Group By settings?
A: Start from People. Summarize: Count of rows. Group By: State. Sort descending by count to see the top state first.
---
Common Gotchas
- Filter = which rows. Summarize = what calculation. These are the most confused pair.
- Group By without a Summarize makes no sense — always pair them.
- When grouping by a date, always pick a time unit (Month, Week, Year) — grouping by raw
Created_At creates one row per timestamp, which is almost never what you want.
- "Done" in the Summarize panel closes it but doesn't save the Question.
Session 3: Visualizations — Reference File
Key Concepts to Teach
1. Visualizations Are Attached to Questions
- Every Question has a visualisation type
- The same data can be displayed as a table, bar chart, line chart, etc.
- Metabase auto-selects a type — you can always override it
2. Switching Visualisation Types
- After running a Question, click the chart icon in the bottom-left of the results area
- A panel shows all available types
- Not all types work for all data shapes (e.g. a map requires a geographic column)
3. Chart Type Guide with Sample Data Examples
| Chart Type | Best For | Sample DB Example |
|---|---|---|
| Table | Row-level data, looking up records | All Orders with Discount > 0, showing ID, Total, Created_At |
| Bar chart | Comparing categories | Total revenue (Sum of Total) grouped by Products.Category |
| Line chart | Trends over time | Count of Orders grouped by Created_At → Month |
| Area chart | Volume/cumulative feel over time | Monthly new People signups (Created_At → Month) |
| Pie / Donut | Part-to-whole, few categories (≤5) | Count of Accounts grouped by Plan (Basic, Business, Premium) |
| Row chart | Bar chart rotated; long category names | Average Rating grouped by Products.Vendor |
| Scatter plot | Relationship between two numeric columns | Products.Price vs Products.Rating |
| Map | Geographic data | Count of People grouped by State (pin map) or People plotted by Latitude/Longitude |
| Single number | One KPI value | Total revenue: Sum of Orders.Total |
| Gauge | KPI with a target threshold | Average Reviews.Rating vs a 4.0 target |
| Funnel | Sequential stages with drop-off | Accounts by stage: Trial → Converted → Active |
| Pivot table | Cross-tabulation of two dimensions | Sum of Orders.Total by Category × Month |
4. Configuring a Chart (Settings panel)
Click Settings in the bottom-left after picking a chart type:
- Axes: which column goes on X vs Y; axis labels; min/max scale
- Example: on a revenue-by-month line chart, set Y-axis min to 0 so dips aren't exaggerated
- Series: which columns to plot; colors; display names
- Example: rename "Sum of Total" to "Revenue" in the chart legend
- Display: stacking (for bar/area), line style, data point labels
- Example: stack a bar chart of Orders by Category to show each vendor's contribution
- Goal line: draw a horizontal target line
- Example: draw a line at 4.0 on an average Reviews.Rating chart to show the quality target
- Trend line: adds a statistical regression line
- Example: add a trend line to monthly revenue to see whether growth is accelerating
5. Downloading / Exporting
- Click the download icon (bottom-right of results)
- CSV / XLSX: raw data (e.g. export all Orders from 2024 for finance)
- PNG: the rendered chart image (e.g. screenshot of the revenue bar chart for a slide)
- Admins can restrict download permissions per group
---
Active Recall Questions
Q1. You've run a Question: Count of Orders grouped by Created_At → Month. What chart type does Metabase likely auto-select, and is that the right choice?
A: A line chart — and yes, that's correct. A line chart is ideal for showing a count trend over time.
Q2. You want to show total revenue broken down by product category. Which chart type and why?
A: A bar chart. Each bar represents a category (Gadget, Widget, Gizmo, etc.) and its height represents Sum of Orders.Total. Bar charts are best for comparing discrete categories.
Q3. Your Accounts table has a Plan column with values Basic, Business, and Premium. You want to show the proportion of accounts on each plan. What chart type, and what's the gotcha?
A: Pie or Donut — but only because there are ≤ 5 categories. If Plan had 8+ values, a bar chart would be clearer. Pie charts become unreadable with many slices.
Q4. What's a Goal Line and how would you use it on an average Reviews.Rating chart?
A: A Goal Line is a horizontal line drawn at a specific value. On a Reviews.Rating chart, you'd set it at 4.0 to visually show whether product quality is above or below your target — any bar below the line needs attention.
Q5. The People table has Latitude and Longitude columns. What visualisation type does this unlock, and what would a useful question look like?
A: A pin Map — you can plot each customer's location geographically. A useful question: show all People records as dots on a map to visualise where your customers are concentrated.
---
Common Gotchas
- Metabase auto-picks a chart type but it's often not the best — always check it.
- Pie charts are overused. More than 5 slices → use a bar chart.
- The Settings panel changes per chart type — explore it fresh each time you switch types.
- PNG downloads export the chart. Use CSV/XLSX to get the raw data (e.g. for Orders).
- Area charts are not cumulative by default — they just shade under the line.
Session 4: SQL Questions — Reference File
Key Concepts to Teach
1. When to Use SQL vs Query Builder
| Use Query Builder | Use SQL Editor |
|---|---|
| Simple filters, aggregations, group-bys | Multi-table JOINs (e.g. Orders + People + Products) |
| Most everyday questions | Window functions (running totals, rank, lag) |
| Non-technical users | Subqueries and CTEs |
| Rapid exploration | Exact control over column names and logic |
Rule of thumb: if you're fighting the Query Builder, switch to SQL.
2. Opening the SQL Editor
- + New → SQL query — opens the native editor directly
- Or: New → Question → (switch to) SQL query — toggle in the top-right of the question picker
- Or: open a query builder question → click "View the SQL" → switch to native mode
3. Writing Queries Against the Sample Database
Basic examples:
-- All orders over $100 with the customer's name
SELECT o.id, p.name, o.total, o.created_at
FROM orders o
JOIN people p ON o.user_id = p.id
WHERE o.total > 100
ORDER BY o.created_at DESC;
-- Average product rating by category
SELECT pr.category, AVG(r.rating) AS avg_rating, COUNT(r.id) AS review_count
FROM reviews r
JOIN products pr ON r.product_id = pr.id
GROUP BY pr.category
ORDER BY avg_rating DESC;
-- Monthly revenue for 2024
SELECT DATE_TRUNC('month', created_at) AS month, SUM(total) AS revenue
FROM orders
WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01'
GROUP BY 1
ORDER BY 1;
-- Accounts that converted from trial (not possible in Notebook without a Model)
SELECT id, first_name, last_name, plan, trial_ends_at, created_at
FROM accounts
WHERE trial_converted = true
AND active_subscription = true;4. Template Variables — The Most Powerful SQL Feature
Template variables turn hard-coded SQL into an interactive, filterable question.
Syntax: {{variable_name}} — wrap in double curly braces.
-- Filter orders by status dynamically
SELECT id, user_id, total, created_at
FROM orders
WHERE created_at >= {{start_date}}
AND total > {{min_total}};Metabase generates filter widgets automatically — users pick a date and enter a number without touching the SQL.
Variable types:
Text— free text input:WHERE products.category = {{category}}Number— numeric input:WHERE orders.total > {{min_total}}Date— date picker:WHERE orders.created_at >= {{start_date}}Field filter— smart widget: Metabase detects the column type and renders the
right UI automatically. Best option when you know which column you're filtering.
5. Optional Clauses with Double Brackets
SELECT id, user_id, total, discount, created_at
FROM orders
WHERE 1=1
[[AND created_at >= {{start_date}}]]
[[AND discount > {{min_discount}}]]
[[AND total > {{min_total}}]];If a user leaves a filter blank, that clause is skipped entirely. This lets one SQL question serve as a flexible, multi-filter explorer.
6. Referencing Saved Questions
-- Reference a saved "High Value Orders" question as a subquery
SELECT u.state, COUNT(*) AS high_value_count
FROM {{#42}} AS hvo -- 42 is the saved question's ID
JOIN people u ON hvo.user_id = u.id
GROUP BY u.state;7. Saving and Using SQL Questions
- Saved exactly like Notebook questions — appear in search, add to dashboards
- SQL questions support template variables as dashboard filter inputs
---
Active Recall Questions
Q1. Write a SQL query to find the top 5 products by total revenue, using the Orders and Products tables.
A:
```sql
SELECT p.title, SUM(o.total) AS revenue
FROM orders o
JOIN products p ON o.product_id = p.id
GROUP BY p.title
ORDER BY revenue DESC
LIMIT 5;
```
Q2. You want users to filter the Orders table by state (via the People table) without editing SQL. What do you add?
A: A template variable, e.g. WHERE p.state = {{customer_state}} after joining People. This creates a text input widget automatically.Q3. What's the difference between {{var}} and [[AND col = {{var}}]]?
A: A regular variable is always included in the query — leaving it blank may error. An optional variable in double brackets means that entire clause is skipped if the user leaves the field empty.
Q4. You want to compare monthly revenue to the previous month (month-over-month). Can the Query Builder do this? What SQL feature handles it?
A: Yes — the Query Builder can do this with theOffset()function in the Summarize step, e.g.Offset(Sum([Total]), -1)to grab the previous period's value (Metabase translates it to aLAG/LEADwindow function under the hood). SQL is still the better choice when you need more control over the window logic — the equivalent query is:
```sql
SELECT month, revenue,
LAG(revenue) OVER (ORDER BY month) AS prev_month_revenue
FROM (
SELECT DATE_TRUNC('month', created_at) AS month, SUM(total) AS revenue
FROM orders GROUP BY 1
) monthly;
```
Caveat: Offset() references the previous row, not the previous calendar period — if your data is missing a month, that gap shifts the comparison, so make sure every period has a row.Q5. Can a SQL question be added to a dashboard the same way as a Notebook question?
A: Yes — once saved, SQL questions behave identically. They can be added to dashboards, used with dashboard filters (via template variables), and scheduled for alerts.
---
Common Gotchas
- The SQL dialect depends on your database. The sample DB is H2/PostgreSQL-like.
- Text template variables pass raw strings — you may need quotes:
WHERE category = '{{category}}' - Field filters only work well when Metabase knows the column's semantic type (set in Admin).
- "View the SQL" on a Notebook question is read-only. Switching to SQL mode is one-way —
you lose the Notebook view.
{{#question_id}}references only work if you have permission to view that question.
Session 5: Dashboards — Reference File
Key Concepts to Teach
1. What a Dashboard Is
- A collection of saved Questions displayed together on one screen
- Each Question becomes a "card" on the dashboard
- Dashboards are read-only for viewers — they run questions and show results
- They are the primary deliverable you share with stakeholders
2. Creating a Dashboard
- New → Dashboard → name it → choose a Collection
- Click Add a question to search for saved Questions to add
- Questions must be saved before they can be added
3. Example Dashboards You Could Build with the Sample DB
Sales Overview Dashboard:
- Card 1: Total Revenue (Single number — Sum of Orders.Total)
- Card 2: Orders This Month (Single number — Count of Orders filtered to this month)
- Card 3: Revenue by Month (Line chart — Sum of Total grouped by Created_At → Month)
- Card 4: Revenue by Category (Bar chart — Sum of Total grouped by Products.Category)
- Card 5: Top 10 Products by Revenue (Table)
Customer Insights Dashboard:
- Card 1: Total Customers (Count of People)
- Card 2: New Customers by Month (Line chart — Count of People grouped by Created_At → Month)
- Card 3: Customers by State (Map — Count of People grouped by State)
- Card 4: Average Order Value by Source (Bar chart — Avg of Orders.Total grouped by People.Source)
Account Health Dashboard (B2B):
- Card 1: Active Subscribers (Count of Accounts where Active_Subscription = true)
- Card 2: Accounts by Plan (Pie — Count grouped by Accounts.Plan)
- Card 3: Trial Conversion Rate (Count where Trial_Converted = true / total trials)
- Card 4: Recent Feedback (Table of Feedback sorted by Date_Received desc)
- Card 5: Invoices Due (Table of Invoices where Payment is null or pending)
4. The Dashboard Grid
- Cards snap to a grid — drag the bottom-right corner to resize
- Drag from the card header to reposition
- Best practice: KPI single-number cards across the top, charts in the middle, detail
tables at the bottom
5. Text and Heading Cards
- Heading card: bold title line — e.g. "── Revenue ──" between sections
- Text card: full Markdown — use to explain what a chart shows, link to a related
dashboard, or add context ("Revenue includes refunds; net revenue is on the Finance dashboard")
6. Dashboard Filters — The Key Power Feature
A single filter widget that controls multiple cards simultaneously.
Example: Date Range filter on a Sales Dashboard
- Add filter type: Date Range
- Wire it to:
- Orders.Created_At on the Revenue by Month card
- Orders.Created_At on the Total Revenue card
- Orders.Created_At on the Top Products card
- Now a viewer can set "Last 30 days" and all three cards update at once
Example: Plan filter on an Account Health Dashboard
- Add filter type: Text / Category
- Wire it to Accounts.Plan
- Viewer selects "Business" → all account cards filter to Business accounts only
Critical rule: A card only responds to a filter if you explicitly wire it up. Unwired cards show unfiltered data regardless of what the filter is set to.
7. Auto-refresh and Sharing
- Auto-refresh: clock icon → 1, 5, 10, 15, 30, 60 min intervals — useful for live ops displays
- Public link: anyone can view without logging in (admin must enable this feature)
- Embed: iframe embed for internal tools or external websites
- Subscriptions: covered in Session 7
---
Active Recall Questions
Q1. Before adding a question to a dashboard, what must you do first?
A: Save the question. Unsaved questions cannot be added to dashboards.
Q2. You build a Sales Dashboard with a Date Range filter. You wire it to the Revenue chart and the Orders table card, but not to the Top Products card. A user sets the filter to "Last 7 days." What does each card show?
A: Revenue chart and Orders table filter to the last 7 days. The Top Products card is unwired — it still shows all-time data, unaffected by the filter.
Q3. Describe how you'd build an Account Health Dashboard that lets a viewer filter everything by Plan (Basic, Business, Premium).
A: (1) Build and save questions for each metric, all using the Accounts table or related tables. (2) Create the dashboard and add all cards. (3) Add a Text/Category filter. (4) Wire it to the Plan column on every relevant card. Now one filter click updates the whole view.
Q4. What's the difference between a text card and a heading card?
A: A heading card is a simple bold title. A text card supports full Markdown — paragraphs, bullet points, links, and richer formatting for adding context around charts.
Q5. Your ops team wants a dashboard showing live order volume on a TV screen in the office. What do you set up?
A: Enable Auto-refresh on the dashboard — set it to every 1–5 minutes so the displayed data stays current without anyone manually refreshing.
---
Common Gotchas
- Most common mistake: adding a filter but forgetting to wire it to cards. The widget appears
but does nothing until connected.
- SQL question cards support filters only if the SQL uses a matching template variable.
- Public links expose all dashboard data — confirm with your admin before sharing externally.
- Auto-refresh sends a fresh query per card on every cycle — heavy dashboards can strain the DB.
- Editing a saved Question updates it everywhere it's used, including all dashboards.
Session 6: Data Organization — Reference File
Key Concepts to Teach
1. Collections — Metabase's Folder System
- Collections are folders for organising Questions, Dashboards, and Models
- Personal Collection: private to you — like a drafts folder
- Shared Collections: visible to others based on permissions
- Collections can be nested (sub-collections)
Suggested structure for the sample DB:
Our Analytics/
├── Sales/
│ ├── Sales Overview Dashboard (pinned)
│ ├── Revenue by Category
│ └── Monthly Order Trends
├── Customers/
│ ├── Customer Map
│ └── New Signups by Month
├── Products/
│ ├── Top Rated Products
│ └── Review Analysis
└── Accounts & Billing/
├── Account Health Dashboard (pinned)
├── Trial Conversion Funnel
└── Invoice Status2. Pinning Items
- Pin important items to the top of a collection so they're visible immediately
- Three-dot menu → Pin → appears as a large preview card
- Example: pin "Sales Overview Dashboard" in the Sales collection so it's the first
thing the team sees when they open it
3. Models — Curated Data Layers
A Model is a saved query that acts as a clean, trusted starting point for new Questions. Users pick a Model instead of a raw table when starting a new Question.
Useful Models from the sample DB:
| Model Name | Based On | What It Does |
|---|---|---|
| Completed Orders | Orders | Filters out orders with no Total (nulls), renames User_ID → Customer ID |
| Active Accounts | Accounts | Filters to Active_Subscription = true, hides internal columns |
| Reviewed Products | Products + Reviews | Pre-joined view with average rating per product |
| Converted Trials | Accounts | Filters to Trial_Converted = true, shows conversion date |
| Recent Feedback | Feedback | Last 90 days of feedback, joined to Accounts for company name |
Creating a Model: New → Model → build it (query builder or SQL) → Save as Model. The Model then appears alongside tables when users start a new Question.
4. Segments — Reusable Filters
A Segment is a saved filter definition users can apply from the filter menu.
Examples from the sample DB:
| Segment Name | Table | Definition |
|---|---|---|
| High-Value Orders | Orders | Total > 150 |
| Discounted Orders | Orders | Discount > 0 |
| California Customers | People | State = 'CA' |
| Business Accounts | Accounts | Plan = 'Business' AND Active_Subscription = true |
| 5-Star Reviews | Reviews | Rating = 5 |
Managed under grid icon → Admin → Table Metadata → [Table] → Segments (this section was formerly called "Data Model"). On Pro/Enterprise, prefer managing segments in Data Studio (Session 8). Once defined, users see "Business Accounts" in the filter dropdown instead of having to reconstruct the conditions every time.
5. Metrics — Reusable Aggregations
A Metric is a saved Summarize definition — ensures everyone uses the same calculation.
Examples from the sample DB:
| Metric Name | Table | Definition |
|---|---|---|
| Total Revenue | Orders | Sum of Total |
| Average Order Value | Orders | Average of Total |
| Average Product Rating | Reviews | Average of Rating |
| Active Subscriber Count | Accounts | CountIf([Active_Subscription] = true) |
Metrics are now first-class items that live in collections (alongside Questions and Dashboards). Create one via the command palette or + New → Metric (or Browse → Metrics → +), pick a data source, and define the aggregation. Filters are expressed with conditional aggregations like CountIf / SumIf rather than a separate baked-in filter. Once defined, users pick "Total Revenue" from the Summarize menu instead of re-creating Sum of Total — and everyone gets the same number.
6. The Hierarchy of Trust
Raw Tables (anyone queries anything)
→ Models (curated, clean starting points)
→ Segments & Metrics (consistent definitions)
→ Questions (built on reliable foundations)
→ Dashboards (trustworthy, org-wide reports)---
Active Recall Questions
Q1. What's the difference between a Personal Collection and a shared Collection?
A: A Personal Collection is private — only you can see it, good for drafts and experiments. Shared Collections are visible to others based on permissions, and are for team-facing, published content.
Q2. A new analyst keeps filtering Accounts to Active_Subscription = true before starting any question. How do you fix this once, for everyone?
A: Create an "Active Accounts" Model based on the Accounts table, with that filter baked in. Now analysts start questions from the Model instead of the raw table — the filter is always there.
Q3. What's the difference between a Segment and a Model?
A: A Segment is just a saved filter — it defines which rows to include (e.g. "Business Accounts" = Plan = Business AND Active_Subscription = true). A Model is an entire saved dataset — a full starting point for new questions, which may include joins, renamed columns, and multiple filters.
Q4. Why would a company define "Total Revenue" as a Metric rather than letting analysts create Sum of Total themselves?
A: To ensure consistency. If Total Revenue is defined once as Sum of Orders.Total (not Subtotal, not including tax), everyone uses the same number. It prevents different teams reporting different revenue figures from the same database.
Q5. You want the Account Health Dashboard to be the first thing your customer success team sees when they open the Accounts collection. What do you do?
A: Pin the dashboard to the top of the Accounts & Billing collection (three-dot menu → Pin).
---
Common Gotchas
- Models look like tables in the question picker — there's a small icon to distinguish them.
- Deleting a Model that other Questions depend on will break those Questions.
- Segments are managed in Admin → Table Metadata (or Data Studio); Metrics now live in collections, created via + New → Metric.
- Collection permissions are inherited by sub-collections by default — plan your structure first.
- Pinning doesn't change permissions — pinned items are still subject to the same access rules.
Session 7: Alerts & Subscriptions — Reference File
Key Concepts to Teach
1. The Two Automation Features
| Feature | Attached To | Trigger | Delivery |
|---|---|---|---|
| Alert | A Question | A condition (threshold) | Email, Slack, or webhook when it fires |
| Dashboard Subscription | A Dashboard | A schedule (time-based) | Email or Slack on a schedule |
Simple rule: *Alerts = "notify me if something happens". Subscriptions = "send me this when the clock says so."*
2. Alerts — Condition-Based Notifications
Alert types (three):
- When a question returns a result: fires when a Question that normally returns nothing suddenly returns rows
- When a time series crosses a goal line: fires when a trend chart crosses a goal line you've set
- When a progress bar reaches its goal: fires when a progress-bar question hits (or drops below) its goal
Sample DB examples:
| Goal | Question to alert on | Condition |
|---|---|---|
| Know when a product drops below 3 stars | Average of Reviews.Rating grouped by Product | When result goes below goal line set at 3.0 |
| Know when daily orders drop below 50 | Count of Orders for today | When result goes below goal line at 50 |
| Know when a trial account cancels | Accounts where Canceled_At is today | When results have rows |
| Know when a payment is overdue | Invoices where Date_Received < today AND Payment is null | When results have rows |
| Know when feedback score drops | Average of Feedback.Rating for this week | When result goes below 3.5 |
Setting up an alert: 1. Open a saved Question 2. Click the three-dots (…) menu (top-right) → Create an alert 3. Choose alert type and condition 4. Set check frequency: by-the-minute, hourly, daily, weekly, monthly, or a custom cron schedule 5. Set delivery: email, Slack, or a webhook, and the recipients 6. Save
Important: Alerts only fire when a condition is newly met — not on every check. If daily orders stay below 50 for a week, you get one email, not seven.
3. Dashboard Subscriptions — Scheduled Delivery
Sample DB examples:
| Dashboard | Subscription | Schedule |
|---|---|---|
| Sales Overview | Email to sales team | Monday 8am — weekly revenue recap |
| Account Health | Slack to #customer-success | Daily 9am — trial and churn monitoring |
| Invoice Status | Email to finance | 1st of each month — billing review |
| Customer Map | Email to marketing | Monthly — geographic distribution update |
Setting up a subscription: 1. Open a dashboard 2. Click the paper plane icon (subscriptions, top-right) 3. Choose Email or Slack 4. Set recipients and schedule 5. Optionally bake in filter values (e.g. always send last 7 days) 6. Save
Email subscriptions send a screenshot of each card + optional data attachment. Slack subscriptions send chart images directly to a channel.
4. Requirements
- Email: admin must configure SMTP (Admin → Settings → Email)
- Slack: admin must install the Metabase Slack app (Admin → Settings → Slack)
---
Active Recall Questions
Q1. What's the core difference between an Alert and a Dashboard Subscription?
A: An Alert fires based on a condition being met (e.g. a metric crosses a threshold). A Subscription fires on a schedule regardless of what the data shows.
Q2. You want to be notified the moment any invoice in the Invoices table is overdue (Date_Received in the past and Payment is null). Which feature, and what type of condition?
A: An Alert on a Question that returns overdue invoices. Use "when a question returns a result" — normally the question returns nothing, and you want to know the instant a row appears.
Q3. Your CEO wants the Sales Overview Dashboard every Monday at 7am. Walk through the setup.
A: Open the Sales Overview Dashboard → click the subscriptions icon (paper plane) → choose Email → add the CEO's email → set schedule to weekly, Monday, 7:00am → Save.
Q4. You set up an alert: "when Feedback.Rating average drops below 3.5." It fires on Tuesday. The score stays below 3.5 for the rest of the week. How many alert emails do you receive?
A: One — Metabase alerts fire when the condition is newly met, not on every check cycle.
Q5. What must an admin configure before email alerts will work?
A: SMTP settings — the outbound email server configuration under Admin → Settings → Email.
---
Common Gotchas
- "When a question returns a result" only fires when the Question goes from 0 rows → some rows.
If the overdue invoices query always returns rows, the alert never fires again after the first time.
- Dashboard subscriptions send a snapshot — a screenshot of the data at send time, not a live link.
- Slack subscriptions require the Metabase Slack app (not just a webhook URL).
- Checking alerts hourly on a complex JOIN query (e.g. Orders + People + Products) can
strain the database — be deliberate about frequency.
- Users can only subscribe Metabase-registered users to subscriptions by default.
Session 8: Data Studio — Reference File
Key Concepts to Teach
1. What Data Studio Is
- Data Studio is an analyst workbench inside Metabase: a dedicated space with tools to
shape your data and curate your semantic layer, so everyone can trust the numbers.
- It's not a separate product — it's a section of Metabase you open from the grid icon
in the upper right → Data Studio.
- Access is restricted: only people in the Admin group or the special Data Analysts
group get the keys. Regular viewers don't see it.
- Mental-model placement: Data Studio sits below the Questions layer. Everything earlier
in the curriculum (Questions, Visualizations, Dashboards) consumes data. Data Studio is where you prepare and describe that data before anyone queries it.
2. What's Inside Data Studio
Six tools, grouped loosely into "shape your data" and "describe/track your data":
| Tool | What it does | Shape or describe? |
|---|---|---|
| Transforms | Clean, join, and pre-compute data, writing results back to your database | Shape |
| Library | A curated home for your most-trusted tables, metrics, and SQL snippets | Describe |
| Data structure | Edit table metadata so tables are easier to work with | Describe |
| Glossary | Define business terms for both people and AI agents | Describe |
| Dependency graph | A visual map of how content connects | Track |
| Dependency diagnostics | Surface broken or unused items | Track |
(Library, dependency graph, and dependency diagnostics are Pro/Enterprise features.)
3. Transforms — the Heart of Data Studio
- A transform does the "T" in ETL (Extract, Transform, Load) inside Metabase.
- You write a query or a script; the transform runs it, **creates a new table in your
target database** with the results, and syncs that table back into Metabase so it can be a data source for questions or even other transforms.
- Two flavors:
- Query-based transforms — written in the query builder or SQL. They run in your
database.
- Python transforms — written in Python, run in a dedicated execution environment.
- Incremental transforms: mark a transform as incremental and Metabase only writes
new data to the target table instead of rebuilding it every run.
- Jobs run one or more transforms on a schedule, selected by transform tags.
- Metabot can generate transforms — you can ask it to write a SQL or Python transform,
or edit an existing one.
4. Transforms vs Models (important distinction)
This is the concept most likely to trip up someone who finished Session 6.
- A model (Session 6) is a saved, virtual layer over a question. The transformed data
is computed on the fly every time someone queries it — nothing new is written to your warehouse.
- A transform physically materializes a new table in your database. The work is
done once, on a schedule, and stored.
- Rule of thumb: reach for a model to clean up and rename for reuse; reach for a transform
when the computation is expensive and you want it pre-computed and stored (e.g. pre-joining Orders, Products, and People into one wide reporting table refreshed nightly).
5. The Library and the Semantic Layer
- The Library is a curated space for the organization's most trusted analytics
content — the tables, metrics, and SQL snippets the data team recommends people start from.
- Together with Data structure (metadata) and the Glossary, the Library forms your
semantic layer: the human-friendly description of what your data means, layered on top of the raw tables.
- The semantic layer pays off twice: people find trustworthy starting points, and AI
features (Metabot, the MCP server — Session 9) get accurate grounding instead of guessing.
6. Glossary
- Define terms specific to your business — what "active account," "churn," or "MQL" means.
- The glossary serves both humans browsing data and AI agents trying to interpret a
natural-language question correctly. A good glossary entry is one of the highest-leverage things you can do to make Metabot answer reliably.
7. Dependency Graph and Diagnostics
- The dependency graph is a visual map of how your content connects — which questions
feed which dashboards, which transforms feed which tables.
- Use it to understand the blast radius of a change before you make it. ("If I rename
this column, what breaks?")
- Dependency diagnostics flag items with broken dependencies, or content that isn't
used by anything — useful for cleanup.
8. Permissions
- To see the transforms list, a person must be able to access Data Studio: Admin or the
Data Analysts group.
- To execute transforms against a database, they additionally need **Transform
permissions** for that database.
- Transforms write to your database, so the underlying database connection must be
writeable.
---
Active Recall Questions
Q1. What does a transform actually do to your database, and how is that different from a model?
A: A transform runs a query or script and writes the results as a new physical table
in your database (then syncs it back into Metabase). A model is virtual — it's a saved
question that recomputes on the fly and stores nothing new. Transforms materialize;
models don't.
Q2. You want a nightly-refreshed table that pre-joins Orders, Products, and People into one wide reporting table. Model or transform? Why?
A: A transform — ideally an incremental one on a scheduled job. The join is expensive
and you want it pre-computed and stored so dashboards read from a ready-made table rather
than re-joining every load. A model would re-run the join on every query.
Q3. Name the two types of transforms and where each one runs.
A: Query-based transforms (written in the query builder or SQL) run in your database.
Python transforms (written in Python) run in a dedicated execution environment.
Q4. Who can get into Data Studio, and what extra permission is needed to actually run a transform against a specific database?
A: Admins and members of the Data Analysts group can access Data Studio. To execute
transforms on a database, a person also needs Transform permissions for that database.
Q5. What is the Glossary for, and why does it matter beyond just helping people?
A: It defines business-specific terms. It helps people understand the data, and it
also grounds AI agents (like Metabot and MCP clients) so they interpret natural-language
questions correctly instead of guessing.
Q6. You're about to rename a column that several questions and dashboards might depend on. Which Data Studio tool helps you avoid breaking things, and how?
A: The dependency graph — it visually maps how content connects, so you can see the
blast radius of the change before you make it. Dependency diagnostics would then flag
anything that did break or went unused.
---
Common Gotchas
- Transforms need a writeable database connection. They create tables in your database;
a read-only connection can't do that.
- Materialized, not live. A transform's output table is only as fresh as its last run.
If numbers look stale, check the job schedule — it's not recomputing on every query the way a model does.
- Data Studio is gated. Most learners who only use Metabase won't see it at all; it's
for Admins and the Data Analysts group. Some pieces (Library, dependency graph and diagnostics) are Pro/Enterprise.
- Don't confuse a transform's output table with a "model." Both give you cleaner data
to build on, but one writes to your warehouse and one doesn't.
Session 9: AI in Metabase — Metabot & the MCP Server — Reference File
Key Concepts to Teach
1. Two Directions of AI in Metabase
There are two distinct ways AI shows up in Metabase, and the key is which way the integration points:
- Metabot — Metabase's built-in AI assistant. The AI lives inside Metabase and
helps you work in the app.
- MCP server — lets an external AI client (like Claude, Cursor, or ChatGPT) reach
into your Metabase from outside. Get this directionality straight first; everything else hangs off it.
2. What Metabot Can Do
Metabot helps you analyze data using natural language. A non-exhaustive list:
- Answer data questions asked in plain English (AI exploration).
- Create a chart by building a query in the query builder from a natural-language prompt.
- Generate SQL in the native editor from natural language (currently SQL only).
- Fix errors in SQL — the "Have Metabot fix it" button on a query error.
- Inline SQL editing — generate or edit SQL right in the editor.
- Analyze a chart — explain what a visualization shows.
- Generate transforms (ties back to Session 8) and charts in documents.
- Answer questions from Slack.
- Universal caveat: like all generative AI, always double-check the results.
3. How to Invoke Metabot
- Chat sidebar:
Cmd+E(Mac) /Ctrl+E(Windows), or click the Metabot icon top-right. - Inline SQL editing:
Cmd+Shift+I/Ctrl+Shift+Iin the SQL editor — enter the
tables, describe the query or edit, accept or reject.
- AI exploration: + New → AI exploration to start fresh with no existing question.
- Analyze a chart: open a question and click the Metabot icon in the upper right.
4. How Metabot Grounds Itself (and where it goes wrong)
- Metabot builds queries using your semantic layer — your models, metrics, and the
glossary (Session 8). That's how it returns working SQL with real field names instead of hallucinated ones.
- When you ask it to create a chart, it first looks for an existing question that
answers you and points you there before building something new.
- The 100-table trap: if you don't name a table, Metabot only checks the first ~100
tables in the selected database. If your answer lives outside those, it may hallucinate table names and the query fails. Fix: name the table/fields in your prompt.
- It works most reliably in English, and benefits enormously from a well-maintained
glossary.
5. Metabot's Current Limitations
Worth knowing so learners don't fight the tool:
- Can't generate SQL with SQL variables / parameters (filters, field filters).
- Can't add goal lines to charts.
- Can't change chart formatting (colors, axis labels, number formatting).
- Can't modify or delete existing alerts/subscriptions (Slack Metabot can create them).
- Search scope: it finds tables, metrics, questions, models, and dashboards — not
segments, documents, collections, or actions on its own (though it can use segments and measures in ad-hoc queries).
6. The MCP Server — What and Why
- MCP = Model Context Protocol, an open standard for connecting AI clients to tools and
data. Metabase ships an MCP server (over Streamable HTTP).
- It lets MCP-compatible AI clients connect directly to your Metabase, with everything
scoped to the connecting person's permissions — the AI can't see more than that user could.
- Crucial distinction: your client provides the AI, not Metabase. If you ask your
desktop AI app "what's our Q3 revenue," your client decides which MCP tools to call; Metabase just exposes the tools and runs them.
- Because the AI comes from your client, MCP calls **don't consume your Metabase AI
provider's tokens** (the provider that powers Metabot is separate and untouched).
7. Connecting and Securing the MCP Server
- An admin enables it under Admin > AI > MCP: a master toggle, plus per-client toggles
for Claude, Cursor/VS Code, and ChatGPT (toggling a client adds its sandbox domains to the CORS allowlist). Self-hosted clients can be added via Custom MCP client domains.
- Clients point at the endpoint
https://{your-metabase}/api/mcp. - Auth is OAuth 2.0 — Metabase runs its own embedded OAuth server, so there's a
Metabase-branded consent screen and no external OAuth provider to set up.
8. The Tools the MCP Server Exposes
The server builds on Metabase's Agent API and exposes tools your AI client can call:
- search — find tables and metrics by keyword or natural language.
- get_table / get_table_field_values — table details, fields, related tables,
metrics, and sample field values.
- get_metric / get_metric_field_values — metric details and sample values.
- construct_query → execute_query — build a query (returns an opaque query string),
then run it.
- query — query a table or metric and return results in one step.
- create_question, create_dashboard — create content.
You can also use the MCP server for file-based development: pointing an agent at real schema metadata so it writes questions/dashboards (as serialized YAML) against real columns.
---
Active Recall Questions
Q1. Metabot and the MCP server both involve AI. In one sentence each, how do they differ in direction?
A: Metabot is AI built into Metabase that helps you work inside the app; the MCP
server lets an external AI client reach into Metabase from outside.
Q2. With the MCP server, where does the actual AI model come from — Metabase, or your client? Why does that matter for token usage?
A: From your client (Claude, Cursor, ChatGPT, etc.), not Metabase. So MCP requests
don't consume tokens from the AI provider configured in Metabase for Metabot — the two
are independent.
Q3. You ask Metabot to write a query but don't mention a table, and it invents a table that doesn't exist. What likely happened, and how do you prevent it?
A: When no table is named, Metabot only checks the first ~100 tables in the selected
database; if your answer lives outside that set it can hallucinate. Prevent it by naming
the table and fields in your prompt.
Q4. Name two things Metabot currently can't do.
A: Any two of: generate SQL with variables/parameters, add goal lines, change chart
formatting (colors/axis/number format), or modify/delete existing alerts and
subscriptions.
Q5. A teammate connects Claude to your Metabase via MCP. Can they query data they don't have permission to see in Metabase?
A: No. MCP access is scoped to the connecting person's own Metabase permissions — the
AI can't reach anything that user couldn't reach directly.
Q6. What makes Metabot's generated SQL use real column names instead of guessing, and how does Session 8 help?
A: It grounds queries in the semantic layer — models, metrics, and especially the
glossary. Curating those in Data Studio (Session 8) directly improves Metabot's accuracy.
Q7. Which keyboard shortcut opens the Metabot chat sidebar, and which one triggers inline SQL editing?
A:Cmd/Ctrl+Eopens the chat sidebar;Cmd/Ctrl+Shift+Itriggers inline SQL
editing in the native editor.
---
Common Gotchas
- AI isn't deterministic. The same prompt can give different answers on a re-run, and
results can be wrong — always verify before trusting or sharing.
- The 100-table limit is the most common cause of hallucinated queries. Name your
tables.
- English works best. Metabot may understand other languages but is most reliable in
English.
- MCP ≠ Metabot's AI. The MCP server doesn't use Metabase's configured AI provider; the
intelligence comes from whatever client connects. You don't even need an AI provider configured in Metabase to use the MCP server.
- A good glossary is the cheapest accuracy win. Vague or missing business-term
definitions are a top reason AI features misinterpret questions.
- Permissions still apply. MCP and Metabot both respect the user's existing
permissions — AI is not a back door around data access controls.