Measures vs dimensions: the distinction behind every chart
Max Musing
Max MusingFounder and CEO of Basedash
· August 27, 2026

Max Musing
Max MusingFounder and CEO of Basedash
· August 27, 2026

Dimensions are the categorical fields you slice and group by, like country, plan, signup_month, or product_name. Measures are the numeric fields you aggregate, like revenue, order count, active users, or average deal size. The short version: a dimension answers “by what?” and a measure answers “how much?” Almost every chart you build is one or more measures broken down across one or more dimensions, so getting this distinction right is the difference between a report that reads cleanly and one that returns nonsense.
This guide is for analysts, operators, and anyone building dashboards who keeps hitting the “why is this chart wrong?” wall. It defines both terms, gives you a quick test to classify any column, explains why the split drives every chart and query, walks through the tricky cases (numbers that are really dimensions, dates, IDs), and shows how the major BI tools model the concept.
A dimension is a field you use to group, filter, or label data. Dimensions describe the context of an event or record: who, what, where, when, which. They are usually text or categories, and their values repeat across many rows. In a table of orders, region, payment_method, customer_segment, and order_date are all dimensions. None of them is a quantity you would add up; each one is a way to split the data into buckets.
The defining property of a dimension is that it makes sense as a label on an axis, a color in a legend, or an option in a filter. “Show me revenue by region” uses region as a dimension. You would never sum region values together, because the sum of “North America” and “EMEA” is meaningless.
A measure is a numeric field you aggregate: sum, count, average, min, max, or a more complex calculation built on those. Measures are the quantities a business actually cares about. order_total, quantity, session_duration, and mrr are measures. On their own they are just numbers in rows; they become useful when you roll them up (total revenue) or roll them up per dimension (revenue by month).
The defining property of a measure is that aggregating it produces something meaningful. Summing order_total gives total revenue. Averaging session_duration gives a real metric. If adding or averaging the column produces a number a stakeholder would ask about, it is almost certainly a measure.
Most confusion disappears if you run each column through one question:
Would you aggregate this field, or group by it?
If you would sum, average, or count it to get an answer, it is a measure. If you would use it to split, filter, or label those numbers, it is a dimension. Apply this test and the edge cases mostly sort themselves out:
revenue is meaningful. Summing zip_code is nonsense. Revenue is a measure; zip code is a dimension, even though both are numbers.plan_name describes a record. seats quantifies it. Description is a dimension; quantity is a measure.status, channel) is almost always a dimension. A continuous or near-unique numeric field (amount, duration) is usually a measure.The test is not perfect, but it resolves the large majority of real columns and gives you a default answer for the rest.
Charts are built by assigning fields to roles, and those roles map directly onto measures and dimensions. Once you see the pattern, chart building stops being guesswork:
| Chart element | Usually filled by | Example |
|---|---|---|
| Value axis (Y on a bar/line) | A measure | Sum of revenue |
| Category axis (X on a bar) | A dimension | Region |
| Line series / trend | A measure over a time dimension | MRR by month |
| Color / legend | A dimension | Plan tier |
| Size of a point | A measure | Deal size |
| Filters and slicers | Dimensions | Country, segment |
| Single big number (KPI tile) | A measure with no dimension | Total active users |
A bar chart is a measure (bar height) split by a dimension (each bar). A time series is a measure aggregated over a date dimension. A KPI tile is a measure with every dimension collapsed. When a chart looks wrong, the cause is often a role mismatch: a dimension where a measure belongs, or a measure being grouped instead of aggregated. If you want a deeper walkthrough of which chart fits which question, see how to choose the right chart for a dashboard.
Here is how common fields from a SaaS orders-and-users schema break down:
| Column | Type | Measure or dimension | Why |
|---|---|---|---|
order_total |
numeric | Measure | You sum it to get revenue |
quantity |
integer | Measure | You sum it to get units sold |
customer_id |
integer | Dimension | An identifier; you group by it, never sum it |
signup_date |
date | Dimension | You group and trend by it |
plan |
text | Dimension | A category you split by |
country |
text | Dimension | A filter and breakdown |
nps_score |
integer 0-10 | Dimension or measure | Average it (measure) or bucket it (dimension) |
discount_pct |
numeric | Measure | You average it across orders |
is_active |
boolean | Dimension | A flag you filter and segment by |
Notice that nps_score can go either way. That is normal, and the next section covers why.
Most disputes are about numbers that do not behave like measures, and a few fields that can play both roles.
Numeric IDs are dimensions. user_id, order_id, and product_id are stored as integers but they are labels, not quantities. Summing them is meaningless. Treat every ID as a dimension. (Counting distinct IDs is a legitimate measure, but that is counting, not summing the IDs themselves.)
Codes and postal fields are dimensions. zip_code, area_code, and sku look numeric but identify a place or item. Group by them; never aggregate them.
Dates are dimensions you can bin. A date is a dimension: you trend and group by it. What varies is the grain. order_date truncated to month, week, or quarter is still a dimension, just at a coarser bucket. Some tools also expose a measure like “days since signup,” which is a real measure derived from a date.
Some numbers are both, depending on intent. A rating, an age, or an NPS score can be averaged (a measure) or grouped into ranges (a dimension). When you bin a continuous measure into buckets like “0-30, 31-60, 61-90,” you are turning a measure into a dimension. This is deliberate and common; the same column just plays a different role in different charts.
Aggregations of dimensions are measures. “Number of distinct countries a customer bought from” starts as a dimension (country) but becomes a measure once you count distinct values. The count is the measure; the underlying field stays a dimension.
The measure/dimension split is the same distinction a GROUP BY query makes. Dimensions go in the SELECT and GROUP BY; measures go inside aggregate functions:
select
region, -- dimension: group by
date_trunc('month', order_date) as month, -- dimension: group by
sum(order_total) as revenue, -- measure: aggregate
count(distinct customer_id) as customers -- measure: aggregate
from orders
group by 1, 2;
Every non-aggregated column has to appear in the GROUP BY, and those are your dimensions. Everything wrapped in sum, count, avg, or similar is a measure. If you have ever seen the error “column must appear in the GROUP BY clause,” that is the database telling you it cannot tell whether a field is a dimension or a measure, and you have to decide.
Every mature analytics tool encodes this distinction, though the vocabulary differs slightly.
dimension and measure as explicit field types in LookML, where a measure is an aggregation of dimension values, as described in the Looker measure types reference.If your organization defines measures once and reuses them everywhere, that shared set of definitions is a semantic layer, which exists largely to make measures consistent across every chart and user.
customer_id onto a value axis. Treat IDs and codes as dimensions.order_total with thousands of distinct values produces an unreadable chart with one bar per amount. Bin it into ranges first, or aggregate it instead.You do not need to think about measures and dimensions for a single number on a tile. It matters most when you are:
GROUP BY query and deciding what belongs in the grouping,For the reverse problem, where a metric is defined but you are deciding how it connects to inputs and other metrics, a metric tree is the companion framework.
Is a date a measure or a dimension? A date is a dimension. You group and trend by it, and you can change its grain (day, week, month, quarter). A value derived from a date, like “days since signup,” is a measure because you would average or sum it.
Can the same field be both a measure and a dimension? Yes. Continuous numbers like ratings, ages, or scores can be aggregated (measure) or bucketed into ranges (dimension) depending on the chart. The column does not change; its role does.
Why is a numeric ID a dimension and not a measure?
Because summing or averaging an identifier is meaningless. customer_id labels a record; it is not a quantity. You group by it or count distinct values of it, but you never add IDs together.
What is the difference between a measure and a metric? A measure is a single aggregatable field or calculation. A metric is usually a named, business-meaningful measure, often with defined filters and grain (for example “monthly active users” or “net revenue retention”). Every metric is a measure, but not every raw measure is a metric people track.
How do dimensions and measures relate to a semantic layer? A semantic layer stores the agreed definitions of both, so “revenue” or “active users” is calculated the same way in every chart. Centralizing measures is the main reason teams adopt one.
Dimensions are the categorical fields you group, filter, and label by; measures are the numeric fields you aggregate. Run every column through one test, “would you aggregate it or group by it?”, and you can classify almost anything, resolve the tricky numeric cases, and predict what any chart will do before you build it. The whole of dashboarding is measures broken down by dimensions, so this one distinction pays off on every report you touch.
Written by

Founder and CEO of Basedash
Max Musing is the founder and CEO of Basedash, an AI-native business intelligence platform designed to help teams explore analytics and build dashboards without writing SQL. His work focuses on applying large language models to structured data systems, improving query reliability, and building governed analytics workflows for production environments.
Basedash lets you build charts, dashboards, and reports in seconds using all your data.