If you report to many audiences, you have probably built the same report more than once. Agencies build one report per client, consultancies per engagement, and internal teams per business unit. Each copy becomes a place for a definition to live.
The standard answer is a metrics layer: define each metric once and make every dashboard read that definition. A hundred unrelated clients sharing one model is a different problem. Each calls the metrics by its own names, sends its own data and keeps its own calendar, and none may have the shared model changed on its behalf.
I designed a system for that case on an analytics team of an agency that bought media for clients. About ten analysts each carried between eight and twenty accounts, every account had its own report, and the only plan for growth was another analyst for every ten new clients. What replaced that was one data model, one metric catalog, one report template, and a short settings record per client.
The same template ended up serving more than a hundred clients. This article builds the design up one complication at a time. Everything in it runs in a small companion repository with synthetic data and three fictional clients.
The fixed model starts with ten clients watching cost per acquisition (CPA), spend divided by conversions. Ten reports with ten CPA formulas work until the definition changes and one copy is missed. The alternative is one table.
Every client's data lands in it with the same columns at the same level of detail: date, client, campaign, channel, spend, impressions, sessions, conversions, revenue. That fixed level of detail is the grain. Per-client settings live outside the model, in configuration.
CPA is now defined exactly once: The client is a filter. Same math, different names: one client's CPA is another's CPO. Traffic sessions for one are visits for another.
Revenue divided by spend is ROAS for one and ROI for another. Acquisition meant a completed order for one, a checkout started for another, and a site visit for a third. If the name lives inside the formula, errors spread quickly.
The solution separates the metric definition from the client-specific naming convention, allowing the same underlying calculation to serve diverse audiences without confusion.
Source: Towards Data Science · Summarized by HeadlinesBriefing