Lina runs operations for a furniture manufacturer in Foshan. Two years ago she sent me a screenshot at 7:40 in the morning: two dashboards, side by side, both titled "August Revenue." One said 41.2 million. The other said 36.9 million. Same company, same month, same platform.
"Which one is right?" she asked.
Both of them were right. That was the problem.
I have spent a lot of time thinking about the exact moment a low-code platform stops being a builder and starts being a source of truth. It always happens at the dashboard. Forms and workflows are forgiving: if a field is ugly, one person suffers. A dashboard is where an entire company agrees, at once, on a number that will drive a decision — and in most low-code platforms, including the one I work on, the dashboard is the least governed, least versioned, least owned part of the system.
That is backwards.
The number is not the problem
Nobody argues about the arithmetic. The argument is always about the verb.
For Lina, "revenue" meant money we have invoiced. For the finance lead, it meant money we have collected. For the sales director, it meant orders we have booked, including the ones not yet shipped. Three definitions, three legitimate business concepts, one word, and one chart title.
Every extra dashboard multiplies the disagreement, because each chart carries a definition that lives only in the head of whoever dragged it together. When that person leaves, the definition leaves with them, and the chart keeps rendering. A number with no author is the most dangerous artifact a business system can produce.
In a mature data stack, this is the metric layer's job: a named, owned, versioned definition of "revenue," consumed by every chart in the company. In a typical low-code platform, there is no metric layer. There is a chart component, a data table, and a person with an opinion. That is not a bug in the product. It is a design choice dressed up as flexibility.
Where the definitions actually live
When I look at how our customers build dashboards, the logic is never in a metric. It is scattered across four places at once: the filter panel, the aggregation setting on the chart, a computed column in the data table, and — almost always — a script someone wrote two years ago and nobody has read since.
That last one is where I lose sleep. A script is the most powerful answer to a business question and also the most invisible one. It runs, it produces a number, and it has no name. If it is wrong, it is wrong quietly, for everyone, forever. A filter that should have excluded cancelled orders is still syntactically correct; it just adds three million to the total.
The honest fix is unglamorous: give metrics names, give them owners, give them a place to live that is not a chart's config panel. But the pitch for a low-code platform is speed, and a metric registry is friction. Every time we consider making it mandatory, someone points out — correctly — that the whole point is that a business analyst can answer a question without filing a ticket.
The tension is real, and I have stopped pretending it resolves itself. Speed and correctness are not opposites. Unowned metrics are just debt, and low-code platforms are unusually good at letting you borrow.
The total will never equal the sum of the rows you can see
Here is a small, specific thing that quietly destroys trust in more dashboards than any modeling mistake.
A user sees a card: 41.2 million. They click it. The platform shows them a list of the underlying records, capped at 500 rows for performance. They add up the visible rows, get a different number, and conclude the dashboard is lying.
It is not lying. The list was paginated and truncated; the total was computed in the database over the full set. But the user cannot see that. The same trap appears in top-N charts, where everything outside the top ten collapses into "Others," and in any chart that groups by a nullable field, because null silently becomes its own bucket with no label.
None of these are hard problems. All of them are decisions someone has to make on purpose, and in a drag-and-drop builder the default is to make them by accident.
"Real-time" is a promise the architecture has to keep
The documentation says the dashboard supports real-time data updates. It usually does — while the table is small.
Then the table grows. A customer in manufacturing imports three years of work orders: four million rows. The dashboard that felt instant at fifty thousand rows now takes eleven seconds, and it takes those eleven seconds on every page load, for every user, against the primary database.
Real-time is not a refresh interval. It is an architectural commitment: either you precompute aggregates and accept that they lag, or you compute live and accept that the database will eventually pay the bill. Most platforms quietly choose the second option and keep calling the result "real-time." The bill arrives later, as a slow platform, and it gets blamed on the platform's performance rather than on the dashboard's design.
I have started telling customers the truth: a dashboard is a query. If the query is expensive, no amount of drag-and-drop will make it cheap.
Permissions turn one chart into many
Here is the part that surprises people. Two executives open the same chart and see different totals — and both are correct, because their data scopes differ. A regional manager should not see the national number. So the aggregate must be computed after permission filtering, not before.
That single requirement destroys the naive version of pre-aggregation. You cannot sum all orders into one row and then apply permissions; permissions have to be applied to the rows before they are summed. The moment you accept that, you have a choice: precompute per scope, which explodes combinatorially, or compute live per user, which is expensive on large tables.
I do not think there is a clean answer. I think there is only an honest one: decide which dashboards need to reconcile perfectly with row-level security and which ones are allowed to be approximate — and label the second kind out loud. Companies are far more tolerant of "this number is a snapshot from this morning" than of a number they cannot trust and cannot explain.
The dashboard is where your data model is judged
By the time a form is submitted, a shortcut in the data model is invisible. A dashboard exposes it.
Currency stored as a string. Timestamps with no timezone. A status field that grew from five values to nineteen over two years. A denormalized total that was correct when it was written and has drifted ever since. None of this hurts while people fill in forms one record at a time. All of it hurts the moment someone asks for the sum of a column across four million rows, or needs two charts to agree on the same boundary condition.
Dashboards do not create these problems. They are simply where the problems become visible, and then where they get blamed on the reporting layer.
The uncomfortable conclusion
A dashboard is not a report. A report ends. A dashboard sits on a wall and becomes the number everyone uses, and the moment it does, it stops being a visualization and becomes a shared definition — which is to say, software.
Every metric is a small program with an owner, a version, and a changelog. Most low-code platforms, including mine, let you create one in ninety seconds with no owner, no version, and no test. We call that empowerment.
Lina's two dashboards are both still live. We did not delete either one. We gave each a name, a sentence of description, and a person who owns it — and then we watched the arguments change. Nobody asks which number is right anymore.
They ask who decided, and whether that decision has changed.
That is a better question. It is also, quietly, an admission that a metric is a piece of software — and that the most popular feature of a low-code platform may be the one that lets you ship software nobody has to maintain.
Until Monday morning.
Top comments (1)
the invoiced vs collected story is a perfect example, because both numbers are correct and both dashboards are wrong. i've seen the same fight with "active users" where three teams had three definitions and nobody found out until a board slide.
the paginated card detail is the one i'd steal for my own writing. 41.2 million on the card, a truncated list underneath, and suddenly nobody trusts either. the total was computed in the database, the list was truncated in the client, and the trust dies in the gap.
one place i'd push back slightly: naming metrics with owners and changelogs works when the org is big enough to have a data team. for a two-person shop the same problem exists, but the fix is just writing the definition in the dashboard subtitle. less governance, same honesty.