Tableau Number Formatting: One Token to Scale Them All (Guest Blog Post from Roxanne Agerone)
This is a guest blog post from Roxanne Agerone. Roxanne has been a software engineer at Tableau for 8 years. She is passionate about delivering the stuff that matters to customers and solving real-world problems. If you were at the 2026 Tableau Conference, you'll recognize her from her Dev' on Stage presentation and most certainly gave her more than one standing ovation.
A note from Ken and Kevin: Before we press forward, we want to note that this is a bit different than most of our blog posts or guest blog posts. Recently, Roxanne posted this exact content on LinkedIn and the content was so incredible, we wanted to do everything we could to share and amplify it. Seriously, you need to read this blog post. So that's what we are doing. This content is 100% from Roxanne. Make sure to follow her on LinkedIn. Okay, we will now pass it onto Roxanne.
You know the column. The one where 1,000 sits three rows above 2,300,000,000, and both are politely trying to occupy the same 60 pixels of width. One of them looks like pocket change. The other looks like a typo. Neither is readable at a glance, which is the entire job of a number in a dashboard.
So you do what we all do. You crack your knuckles and write The Calc:
IF [Value] >= 1000000000 THEN STR(ROUND([Value]/1000000000, 1)) + "B"
ELSEIF [Value] >= 1000000 THEN STR(ROUND([Value]/1000000, 1)) + "M"
ELSEIF [Value] >= 1000 THEN STR(ROUND([Value]/1000, 1)) + "K"
ELSE STR([Value])
END
It works. It's also a string now and it evaluates on every single row of your data. You've traded a formatting problem for a data-modeling problem, and you did it in a text editor the size of a business card.
There's a better way!!!!!
Meet [scale]
[scale] is a token you drop into a Tableau custom number-format string. That's it. That's the feature. You type it into the format pane and it changes everything about how the column behaves.

0.0[scale]
With that format applied, here's what your field does:

Look closely at that table, because something remarkable is happening. The same field is rendering different suffixes on different rows. 1,000 becomes 1.0k. A million and a half becomes 1.5M. Two point three billion becomes 2.3G.
No calc. No IF ladder. No string. Still a real number underneath.
"Adaptive" is the whole point
Tableau already has Display Units: Thousands (K) / Millions (M) / Billions (B) dropdown in the number format pane. It's genuinely useful, but using display units shows one divisor and applies it to every value in the field.
Set a column to "Millions" and every value gets divided by a million and stamped with an M. Great for 47.2M and 1,203.9M. Less great for the row that's actually worth 900. It renders as 0.0M, which is a very fancy way of writing "nothing."
That's the difference in one sentence:
Display Units = one rule for the whole column.
[scale] = one rule per value.
[scale] doesn't ask "what units suit this field?" It asks, for every single value, "what units suit you?" and answers differently for the 900, 900 thousand, and 900 billion in the same column. That's what adaptive means here, and it's why a single mixed-magnitude column can finally look sane. (Here it is in action).

Why a billion is a G
You may have noticed a billion rendered as 2.3G, not 2.3B. [scale] uses SI prefixes, the same ones physicists and engineers use:
Big (value ≥ 1) 10³ all the way to 10²⁴: k, M, G, T, P, E, Z, Y
Small (value < 1) 10⁻³ down to 10⁻²⁴: m, µ, n, p, f, a, z, y
So a billion is G (giga), a trillion is T (tera), and 0.004 becomes 4.0m, a lowercase milli. That means [scale] handles the small direction too. Nanoseconds, milligrams, microvolts: all first-class citizens.
Two things worth filing away:
1) Capitalization carries meaning. M is mega (millions); m is milli (thousandths). They are not the same letter wearing different hats.
2) Go past 10²⁴ and the desktop formatter gracefully falls back to a bracketed numeric exponent like [9] instead of inventing a letter nobody would recognize. It knows when it's run out of Greek.
The part where it's also faster
Here's the argument that wins over the engineers in the room.
The calc-field approach does work per row, in your data. Every IF/STR() is an expression Tableau has to evaluate for every mark in the view. It bloats the query, it produces a string and it only fixes one place. You wrote that calc for a text table? Congratulations, your axis labels and tooltips still say 2300000000. Time to write it again, slightly different, somewhere else.
[scale] does its work in the formatting path, not the data path. It's not a value your query computes; The number stays a number all the way through: it sorts correctly, it drives a continuous axis correctly, it aggregates correctly. Only its appearance adapts.
And because it lives in the standard formatter, it shows up everywhere a number gets drawn, for free:
axis tick labels
tooltips
text / label marks
table and crosstab cells
One token. Every surface. No per-view re-wiring, no six copies of the same fragile calc drifting out of sync. You format the field once and the whole workbook agrees.
Intriguing places to actually use it
The fundraising thermometer that spans five orders of magnitude. A campaign dashboard where individual gifts ($50), major donors ($2.5M), and the grand total ($1.4G) all live in the same table. With Display Units you'd have to pick a loser. With [scale], every gift is legible at its own scale, and the total still towers appropriately.
IoT and sensor telemetry that crosses zero-point-something. Real sensor data doesn't respect your unit dropdown. A power dashboard might swing from 4.0m watts on to 2.3G watts across rows. [scale] is the rare formatter that handles both ends without you touching a thing.
Cloud cost and byte-counting tables. Storage in bytes, spend in dollars, request counts in the billions, the classic FinOps trio, all different magnitudes, all in one crosstab. [scale] turns 1073741824 into a calm 1.1G.
The one KPI tile that fits every tenant. Building a template dashboard shipped to customers of wildly different sizes? A startup's "monthly active users" might be 4.2k; an enterprise's might be 88.0M. Hard-code Display Units and you're right for exactly one segment. [scale] renders each tenant correctly from the same tile, so you build it once and it flatters everyone.
Scientific and lab data, unapologetically. Wavelengths in nanometers, concentrations in micromolar, sample masses in milligrams. This is literally what SI prefixes were invented for. [scale] speaks the native language.
The fine print (because we're honest here)
[scale] is powerful, a little bit magic, and a little bit hidden. Before you evangelize it to your whole team:
It's undiscoverable. There's no checkbox, no dropdown entry. You have to know the token exists and type [scale] into the custom-format field by hand.
SI letters, not Tableau's letters. A billion is G, not B. If your audience expects B, set expectations or a legend.
Edges behave slightly differently across platforms. At the extreme ends of the scale, desktop and browser rendering can diverge on how they handle values past the suffix table. For the everyday range thousands to trillions, and down into the millis; They agree, which covers approximately every dashboard you'll ever build.
The one-line takeaway
If your column contains numbers that live at different scales, stop making them share one set of units and stop hand-rolling a string calc to fake it. Add seven characters to your format string:
0.0[scale]
One token to scale them all. Let every number pick its own units.
Thanks for reading!
Roxanne!
───────────────────────











No comments: