all insights

Calculated vs. streaming insights in Data 360: the engine choice that sets your credit bill

Both compute a metric from your data; they are not interchangeable. One batches the whole history on a schedule, the other aggregates a live event stream inside a time window — and picking the wrong one is how a metric nobody reads by morning ends up costing many times what it should. Here's the SQL, the window clause, and the decision rule.

Calculated vs. streaming insights in Data 360: the engine choice that sets your credit bill — article illustration

You need “average order value per customer over the last 90 days” as a governed number your segments, activations, and agents can all read. Data 360 gives you two ways to compute it, they look almost identical in the SQL editor, and the one you pick decides both how fresh the number is and how much it costs to keep alive. Choose wrong in the direction most teams do — reach for the real-time engine because real-time sounds better — and you’ve built a metric that refreshes continuously, bills continuously, and is consumed exactly once a day when a segment runs. The number is right. The invoice is not.

This is the calculated-insight-versus-streaming-insight decision, and it’s one of the quietest expensive mistakes in Salesforce Data 360 (the platform formerly known as Data Cloud, renamed at Dreamforce in October 2025). Both are SQL-defined metrics. Both materialize their output as a data model object other things can query. The difference is when they compute and what they can see — and once you understand that, the choice stops being a coin flip and becomes a property of the question you’re asking. This post is what each engine actually is, the SQL that separates them, and the rule that keeps you on the cheap side of the meter.

Two engines, one deceptive resemblance

A calculated insight is a batch job. It runs a SQL query across your stored data — unified profiles, data model objects, historical engagement — computes an aggregate, and materializes the result as a new DMO. It runs on a schedule (daily by default, adjustable), and it can look across the entire history of your estate because it’s reading data at rest. “Lifetime value,” “cases opened in the last year,” “NPS by segment” — durable metrics that don’t change minute to minute — are calculated insights.

A streaming insight is a different animal. It runs over streaming engagement data — the web and mobile events flowing in through the SDKs and the Ingestion API — and it aggregates those events inside a time window as they arrive. It does not scan your full history; its visibility is deliberately narrow, focused on what’s happening right now. “Products viewed three or more times in the last fifteen minutes,” “cart value accumulated this session” — signals that are only interesting while they’re fresh — are streaming insights.

Salesforce’s own framing is the cleanest one-liner you’ll find: calculated insights focus on data as a whole; streaming insights focus on data at a specific time. One aggregates history on a schedule. The other aggregates a live stream inside a window. They resemble each other because you build both in the same SQL editor (or the same visual builder), and that resemblance is exactly what lures teams into using the expensive one for a job the cheap one does identically.

The metric is the same shape either way. What differs is whether you’re paying to compute it once a day over data at rest, or continuously over a stream you only read from at 6 a.m. Real-time is a capability, not an upgrade — and you pay for it whether or not anyone consumes the freshness.

The SQL: measures, dimensions, and the one clause that changes everything

Both engines speak SQL, and both force the same core distinction: every column you output is either a measure or a dimension. A measure is a quantitative value you aggregate — a COUNT, a SUM, an average. A dimension is a qualitative grouping — an id, a name, a product, a date bucket. They aren’t interchangeable, and getting a column on the wrong side is one of the first errors the editor will reject. Measures further split into aggregatable (a total spend you can roll up further) and non-aggregatable (a ratio like NPS that you can’t just sum), and that distinction matters downstream when something tries to re-aggregate your metric.

A calculated insight is ordinary aggregate SQL. Count email opens per unified individual, say — join the engagement object to the unified individual, filter to opens, group by the person:

SELECT
  Individual__dlm.ssot__Id__c            AS individual_id__c,   -- dimension (grouping key)
  COUNT(EmailEngagement__dlm.ssot__Id__c) AS email_opens__c     -- measure (aggregatable)
FROM EmailEngagement__dlm
JOIN Individual__dlm
  ON Individual__dlm.ssot__Id__c = EmailEngagement__dlm.IndividualId__c
WHERE EmailEngagement__dlm.EngagementType__c = 'Open'
GROUP BY Individual__dlm.ssot__Id__c

(Object and field names above are illustrative — yours depend on how your model is mapped.) Nothing here is time-aware. It runs, it aggregates everything that matches, it writes a DMO. Tomorrow’s run does it again.

A streaming insight is where the syntax diverges, and it diverges in one specific, load-bearing place: the window() function inside the GROUP BY, with WINDOW.START and WINDOW.END exposing the window boundaries as columns. Count page views per product per customer in five-minute windows:

SELECT
  COUNT(MobileEvents__dlm.pageviews__c) AS page_views__c,   -- measure
  Individual__dlm.ssot__Id__c           AS customer_id__c,  -- dimension
  MobileEvents__dlm.product__c          AS product__c,      -- dimension
  WINDOW.START                          AS window_start__c,
  WINDOW.END                            AS window_end__c
FROM MobileEvents__dlm
JOIN Individual__dlm
  ON Individual__dlm.ssot__Id__c = MobileEvents__dlm.deviceId__c
GROUP BY window(MobileEvents__dlm.dateTime__c, '5 MINUTE'),
         customer_id__c, product__c

That window(<timestamp>, '5 MINUTE') is the whole difference. It tells the engine to bucket incoming events into fixed, non-overlapping windows and aggregate within each. The window can run from a minimum of 5 minutes to a maximum of 24 hours — that range is your entire freshness dial on the streaming side. Below five minutes isn’t offered; above a day, you’re describing a batch job that should be a calculated insight instead.

Where the output goes

Computing the metric is half the point; the other half is that everything downstream reads the same governed number instead of each team inventing its own. Once a calculated insight materializes its DMO, that DMO is a first-class citizen:

  • Segmentation — use the metric as segment criteria (customers whose LTV crossed a threshold).
  • Activation and personalization — push the metric to the channels that act on it.
  • Data actions — a streaming insight’s real purpose: fire an event to Marketing Cloud or another target the moment a windowed threshold is crossed, driving near-real-time orchestration. This is why streaming insights feed actions, not dashboards.
  • Grounding agents — an Agentforce agent can read the metric as governed logic rather than trying to compute “revenue” from raw tables, which it will cheerfully get wrong. That’s the same failure we cover in grounding agents on a semantic layer.
  • The Calculated Insights query API — pull the metric programmatically with your chosen dimensions, measures, and filters.

The consumption pattern is the tell for which engine you need. If the only thing that reads your metric is a segment that runs overnight, the metric does not need to be fresher than overnight — full stop. If a customer’s next click depends on it, it does.

The decision rule (and the credit math behind it)

Here’s the heuristic practitioners keep landing on, and it’s the one worth taping to the wall: use a streaming insight only when the business value of the number degrades within about fifteen minutes. If the output isn’t consumed until the next batch job, the next journey send, or the next morning’s report, a daily calculated insight produces the identical result for a fraction of the cost.

The cost gap is not small. Data 360 bills by consumption, and continuous streaming aggregation is dramatically more expensive per unit of work than a scheduled batch pass — practitioners estimate the multiple in the tens, not the low single digits. The mechanism is obvious once you see it: a streaming insight is a standing process, always on, always metering; a daily calculated insight does its work once and stops. Move a non-time-sensitive metric from an aggressive refresh to a daily one and the insight-related spend can collapse by the vast majority — it’s routinely the single highest-leverage optimization on a Data 360 bill. This is exactly the class of setting our credit optimization playbook exists to catch: the streaming that didn’t need to stream, the hourly refresh nobody asked for. If you’re still sizing your first commitment, the mechanics of how credits accrue are in the pricing and credits guide.

The reason the mistake is so common is that “real-time” is an easy yes in a requirements meeting. Nobody argues for staler data. But freshness you don’t consume is pure cost, and the discipline is to make the freshness match the use, not the aspiration. A metric read once a day should compute once a day.

Limits and the edges that bite

A few constraints shape the design before you hit the credit question:

  • A calculated insight caps at 50 measures and 10 dimensions. That’s generous for a focused metric and a hard stop if you’re trying to make one insight do the job of ten. Model narrow, purpose-built insights rather than one sprawling mega-query.
  • Editing is restricted after creation. You generally can’t change a measure’s API name, data type, or rollup behavior in place, and you can’t freely add or remove measures and dimensions on an existing insight. Like a data graph’s cardinality, this is a design-once surface — spend the time on the model before you publish, because the fix for a wrong choice is a rebuild.
  • Streaming insights can’t see history. By design. If your “real-time” metric secretly needs a 90-day baseline to be meaningful, it’s not a streaming insight — it’s a calculated insight, possibly feeding a streaming one, not the streaming one alone.
  • Refresh no faster than the data changes. A calculated insight over a population that changes daily gains nothing from an hourly schedule except a bigger bill.

Where this sits in the stack

It’s easy to conflate these engines with the two other Data 360 features that also make agents smarter, so the boundaries are worth drawing:

  • A calculated insight computes a metric — it does the aggregation math.
  • The semantic layer (Tableau Semantics) governs and names metrics so humans and agents query them in business language; a calculated insight is often one of the governed metrics a semantic model references. Define the metric once, and both a person asking in natural language and an agent triggering a workflow read the same logic.
  • A data graph reshapes and pre-joins records for millisecond lookups; it does not compute aggregates. When an agent needs “everything about this customer, joined, now,” that’s a data graph, not an insight.
  • Intelligent Context handles the unstructured half — grounding on documents, not metrics — covered in its own guide.

A serious Data 360 implementation uses all of them, each for the question shape it fits. Insights are the layer that answers “what is the number,” and calculated versus streaming is the sub-decision of “how fresh does the number need to be, and what will that freshness cost.”

What to actually do

Start from the consumer, not the metric. Ask what reads this number and how stale it’s allowed to be when they read it. If the honest answer is “a segment overnight” or “a report in the morning,” it’s a calculated insight on a daily schedule, and you should feel no guilt about that — it’s not the lesser option, it’s the correct one for data at rest. If the answer is “the customer’s very next interaction, and the value is gone in minutes,” it’s a streaming insight with a window sized to the decision, feeding a data action. Model each insight narrow and purposeful inside the 50-measure, 10-dimension envelope, get the measures and dimensions right the first time because editing is restricted, and refresh no faster than the underlying data actually moves.

Do that and your metrics are governed, consistent across segmentation, activation, and agent grounding, and priced to match their use. Get the engine choice backwards and you’ll ship a perfectly correct number attached to a standing meter that nobody’s freshness ever justified. The SQL is the easy part. The engine is the decision. If you’re building the metric layer under an agent or a segment and want the freshness-versus-cost calls made deliberately, talk to us — getting the Data 360 foundation right so it grounds AI without bill shock is exactly the work we do.

Understanding the basics

What is the difference between a calculated insight and a streaming insight in Data 360?

A calculated insight is a batch-computed metric: it runs a SQL aggregation across your stored, historical data on a schedule (daily by default, adjustable) and materializes the result as a data model object. A streaming insight computes over live engagement data as events arrive, aggregating them inside a time window — from 5 minutes to 24 hours — and is designed to fire data actions in near real time rather than feed overnight reporting. Salesforce frames it as calculated insights focusing on data as a whole and streaming insights focusing on data at a specific time. The practical rule: use streaming only when the value of the number degrades within roughly fifteen minutes; otherwise a daily calculated insight produces the same result far more cheaply.

How do you write a streaming insight in SQL?

A streaming insight is aggregate SQL with a window function in the GROUP BY: window(<timestamp_column>, '5 MINUTE'), with WINDOW.START and WINDOW.END available as output columns to expose the window boundaries. That window function is the syntactic difference from a calculated insight, which is ordinary GROUP BY aggregation with no time window. The window duration can range from a 5-minute minimum to a 24-hour maximum. As with a calculated insight, every output column must be either a measure (an aggregate like COUNT or SUM) or a dimension (a grouping key), and the two are not interchangeable.

Do calculated insights and streaming insights consume Data 360 credits?

Yes, and the gap between them is the main cost story. Both bill by consumption, but a streaming insight is a standing, always-on process that meters continuously, while a calculated insight does its work on a schedule and stops — so continuous streaming aggregation costs substantially more than an equivalent batch pass, by a large multiple in practitioner estimates. Moving a metric that isn’t genuinely time-sensitive from an aggressive or streaming refresh to a daily calculated insight is routinely the single highest-leverage optimization on a Data 360 bill, the same discipline in our credit optimization playbook.


Building the metric layer under a segment or an agent and not sure whether a number should batch overnight or stream in real time — or why the bill is higher than the value? Talk to us — designing the Data 360 foundation so metrics are governed, consistent, and priced to their use is exactly the work we do.

Keep reading

All insights