When a CRM Analytics Recipe Silently Drops Rows (and the Dashboard Renders Blank)

You open a dashboard, the widgets are blank, and the dataset preview shows far fewer rows than you expected. No error message. No red banner. The recipe ran and reported success. This is one of the more frustrating failure modes in CRM Analytics (formerly Tableau CRM, Einstein Analytics, and Wave Analytics before that), because the platform gives you almost no signal when a sync drops data quietly.

Here is what actually causes it and how to work through it systematically.

Why Recipes Drop Rows Without Telling You

The short version: a recipe can succeed at the job-level while producing a dataset that is materially incomplete. The run log shows green, the dataset timestamp updates, and the dashboard queries that dataset and returns nothing useful.

There are a handful of specific mechanisms behind this.

The watermark off-by-one problem. If you are running incremental syncs, the recipe uses a watermark field (usually LastModifiedDate) to decide which records to pull. Salesforce stores LastModifiedDate at millisecond precision. If your watermark is stored or compared at second precision, records modified in that sub-second window get skipped on the next run. One missed window compounds into the next, and eventually your dataset drifts far enough from reality that widgets render blank because the filtered slices they expect simply have no matching rows.

The fix is precise: store and compare the watermark with full millisecond resolution, and use a strictly-greater-than comparison (not greater-than-or-equal) against the stored value to avoid double-counting the boundary record.

The late-arrival window. Salesforce can take up to 30 minutes to fully commit a record update. If your recipe fires before that commit completes, those records are invisible to the sync. A dashboard with time-based filters set to "today" or "this week" will appear to have holes that fill in hours later, or not at all if the schedule does not re-cover that window. The practical fix is to buffer the watermark ceiling: do not sync right up to the current moment. Pull data up to 30 minutes ago and let the next run cover the gap.

Formula fields do not trigger LastModifiedDate. This one surprises people. If a formula field recalculates because a related record changed, the parent record's LastModifiedDate does not update. An incremental sync based on LastModifiedDate will not pick up that parent record. If your dashboard is filtering or aggregating on a formula field, you can silently lose entire record groups between full refreshes.

Deletes are invisible to standard incremental logic. When a Salesforce record is hard deleted, its LastModifiedDate does not change because the record is gone. An incremental sync has no way to know the record should be removed from the dataset. The dataset grows stale in the opposite direction: rows that should be absent stay present, filters produce wrong counts, and joins downstream can inflate or distort numbers. Handling deletes requires a separate query that explicitly surfaces deleted records and removes them from the target dataset.

The Recipe vs. Dataflow Choice Matters Here

One thing worth understanding is that Recipes and Dataflows handle these problems differently, and the Salesforce documentation does not always make the tradeoffs clear.

Recipes autoexpose schema from Salesforce, which feels convenient until a field gets renamed upstream. A downstream recipe that depends on OldName__c breaks silently when it becomes NewName__c. You find out when the dashboard stops populating. Dataflows, by contrast, use explicit JSON schema definitions, so a rename forces a visible edit rather than a silent failure.

For large tables, the performance gap is also real. On datasets of 50 to 90 million rows, a dataflow using sfdcDigest with proper watermarking consistently outperforms a Recipe using a Salesforce input transform, sometimes by a factor of two on sync time. That matters because slower syncs are more likely to hit API governor limits and fail partway through, leaving the dataset in a partially-refreshed state.

Recipes are not the wrong choice for every situation. For simpler pipelines without complex joins or high row counts, they are fine. The problem is that teams often start with a Recipe because it is the path of least resistance, then encounter these edge cases at scale, and spend significant time debugging what is fundamentally a tool-selection problem.

How to Diagnose a Missing-Row Problem Step by Step

Start with the dataset, not the dashboard. Open the dataset in the Analytics Studio data browser and check the total row count. Compare it to what you expect from the source object in Salesforce. If the counts diverge, the problem is in the sync layer, not the dashboard SAQL.

Next, look at the recipe run history. A recipe that partially succeeded will still show as completed. What you want to see is whether the node-level output row count dropped across runs. If the row count was stable for weeks and then dropped on a specific run date, something changed around that time: a schema change, a volume spike that hit a governor limit, or a watermark that advanced past a batch of records it should have covered.

Check the watermark value stored in your control dataset (if you have one) against the actual LastModifiedDate distribution in Salesforce. Run a quick report in Salesforce showing records modified in the last 48 hours and compare that count to what the recipe ingested in the same window. A gap here points directly to the watermark precision or late-arrival problem.

If the row count looks correct but the dashboard widgets are still blank, the problem is likely in the SAQL step definitions or the filter bindings. A step that filters on a dimension value that no longer exists in the dataset will return zero rows. Check whether any staticflex or filter components are passing values that do not match the current data.

If widgets render blank only on some pages and not others, and the pages share steps, a SAQL parse error in one step can propagate across sibling widgets that depend on shared state. The widget will show blank rather than an error, because the query returned nothing rather than failing explicitly.

What a Clean Incremental Sync Actually Looks Like

A well-built incremental sync handles four things: millisecond-precise watermark storage, a 30-minute ceiling buffer to account for late commits, a separate delete-detection pass, and a recovery path for when the scheduler misses a window entirely. The recovery path is often the part that gets skipped. It matters because a single missed sync can leave the watermark advanced past the gap, meaning subsequent runs will not go back and fill it unless you explicitly re-cover the missed window with a wider query.

None of this is exotic, but it requires deliberate design. The default recipe setup in Studio does not give you these controls out of the box.

When It Is Worth Getting Outside Help

Most teams hit these problems once, spend a week debugging, fix the immediate symptom, and move on. What they often miss is that the same underlying design gap will cause a different symptom six months later when data volume grows or a schema changes.

A diagnostic pass over the full pipeline, looking at the recipe graph, watermark logic, node output counts, and the SAQL in the dashboard steps, usually surfaces several of these issues at once. In one recent engagement, that kind of audit reduced dashboard JSON size by 53% and cut page-one load queries by 37%, with no change to what the dashboard actually displayed. Most of those gains came from finding redundant sync steps and overlapping queries that were each partially covering the same data, producing inflated row counts that then had to be deduplicated downstream.

That work is genuinely tedious if you are doing it for the first time. It is faster if you have seen the failure patterns before.


If you want a structured look at what is causing blank widgets or dropped rows in a specific dashboard, CRMA Labs offers a $249 teardown on crmalabs.com. You export the dashboard JSON from Studio (no org access needed on our end), we turn around a step-level audit and prioritized fix list within 48 hours, with expected query reduction noted for each item. No retainer required.