All posts
Building something data-heavy

Customer-facing analytics
is a different problem

By Woodfrog · 6 min read · Accurate as of

Teams often assume the analytics they show customers can come from the same place as internal reporting. The constraints are different enough that the assumption is usually discovered to be wrong late.

Three constraints that do not apply internally

Isolation is absolute. An internal report showing a row it should not is a governance incident. A customer seeing another customer's data is a breach, a disclosure obligation and possibly the end of the relationship.

Latency is a product feature. Internal users tolerate a report that takes twenty seconds. A customer clicking a tab in your application does not, and the budget is closer to one second than twenty.

Definitions become contractual. Once a customer has seen a number in your product and made a decision on it, quietly correcting the calculation is a support conversation rather than a fix.

The pattern that does not scale

The common first version is a query per tenant, filtered by tenant id, hitting the warehouse directly. It works at ten customers. At two hundred it becomes a cost problem, a latency problem, and a correctness risk if any query is ever written without the filter.

The filter being a matter of developer discipline is the part that should worry you. It is one forgotten clause away from being the incident.

Making isolation structural

The filter should not be in the query. It should be in the platform, applied to every request based on who is asking, so that a query without a tenant clause returns that tenant's rows rather than everyone's.

This is the same mechanism as row-level access for employees, pointed at customers instead. Having it in one place means it is enforced for the application, the export, the API and anything else that appears later.

Precompute what customers actually look at

Customer-facing views are usually narrow and repetitive: the same handful of figures, per tenant, per period. That profile precomputes well, which is what gets you to a latency budget you can defend.

The gold layer is where this belongs, refreshed on a schedule the product can state honestly. Telling a customer the figure updates hourly and having it be true is worth more than real time that is occasionally not.

On these comparisons. Billing models are stable and publicly documented, and that is what is described here. Specific list prices are not, because they move and because real contracts are commonly well below list at volume, so ask any vendor what they would actually quote you. Reviewed August 2026, next review February 2027.
Next step

See it on your own data.

Thirty minutes on the half you came for. Bring the report that breaks every month, or the decision you never settled.