A published Tableau extract refresh shows a green tick, yet a workbook built on it is still missing rows that changed upstream — how do you track down where the data is being lost?
answer
- a green refresh is not a fresh number
- which object did the refresh actually touch?
- appending is not the same as updating
- compare the extract's maximum timestamp with the source
- the refresh may have run before the load
basics
~20 sEstablish which data source the workbook actually queries, then compare its last-refresh time and row counts against the source. The usual causes are an incremental refresh that only appends new rows, an extract filter or aggregation, a workbook bound to a different embedded extract, or source data that had not landed when the refresh ran.
solid answer
~50 sWork outside in. First confirm **which** data source the workbook uses: a workbook can carry its own embedded extract while someone refreshes a published data source of the same name, in which case the green tick is on the wrong object. Then check the refresh **type**: incremental refresh appends only rows whose key exceeds the highest value already stored, so updates to existing rows and deletions are invisible — a full refresh is the test. Then check the extract's **shaping**: extract filters and aggregation for visible dimensions can exclude exactly the rows in question. Then check **ordering**: a refresh that runs before the upstream load finishes faithfully copies yesterday's warehouse. Finally rule out caching on Tableau Server or Cloud serving previously computed results. Compare `MAX(updated_at)` and row counts in the extract against the source — that one comparison usually names the cause.
go deeper
Know that an extract is only as current as its last refresh, and that you check a data source's last-refresh timestamp rather than assuming the dashboard is live.
Explain what incremental refresh does and does not do, and what extract filters and aggregation change about the stored rows, so you can name several reasons a green refresh yields stale numbers.
Show a systematic diagnosis: identify the object queried, compare row counts and maximum timestamps against the source, check refresh type and ordering with upstream, and only then consider caching.
Own freshness as a contract: published data sources over embedded extracts, pipeline-triggered refreshes, alerting when extracted data ages beyond its stated bound, and a visible 'data as of' on every dashboard.
## Why "the refresh succeeded" proves less than it seems A successful refresh means Tableau ran an extraction query and wrote a `.hyper` file without erroring. It does not mean the file now contains the rows you expect. Every diagnosis here is about the gap between those two statements. ## Step 1 — identify the object the workbook actually queries A workbook can connect to a **published data source** on Tableau Server or Cloud, or it can carry an **embedded** extract of its own. These are different objects with different refresh schedules. The classic case: someone publishes a data source, schedules its refresh, and watches it go green — while the dashboard in question was published with its own embedded extract months earlier and has been refreshing on a different schedule, or on none. Open the workbook's connection and confirm the target, then read the last-refresh timestamp of **that** object. Also check you are not looking at a same-named data source in another project. ## Step 2 — check the refresh type **Incremental refresh** appends rows whose value in a chosen key column is greater than the highest value already in the extract. That is all it does. It does not revisit rows already stored, so an amount corrected yesterday on an existing order will still show the old value; it does not remove rows deleted at the source; and if the key column itself is mutable, a re-issued row can arrive as a duplicate rather than an update. A full refresh is both the diagnostic and, usually, the fix. If full refresh does not fit the window, the source needs an append-only pattern — an immutable event key — for incremental to be safe. ## Step 3 — check the extract's shaping Extract creation can filter rows out, aggregate the data for the visible dimensions, roll dates up to a coarser level, or sample the top N rows. Each of these is invisible in the dashboard and each can explain missing recent data — most obviously a date filter written as a static range that has aged out, or an aggregation that no longer includes a dimension the report needs. Inspect the extract's filters and aggregation settings before blaming the pipeline. ## Step 4 — check the ordering against upstream A refresh scheduled at 02:00 that reads a table loaded at 02:30 will succeed every night and be a day stale every day. Compare the refresh's start time with the upstream load's completion time, including time zones — the refresh schedule and the ETL scheduler frequently disagree about which zone they are in. The robust pattern is to trigger the refresh from the pipeline once the load completes rather than pinning it to a clock time. ## Step 5 — rule out caching Tableau Server and Cloud can serve previously computed query results and rendered views for a period. A viewer may be looking at a cached rendering rather than a fresh query against a freshly refreshed extract. Forcing a refresh of the view — or comparing against a newly opened session — separates this from a genuine data problem. ## The measurement that settles it Rather than reasoning, measure. Put `MAX(updated_at)` and `COUNT(*)` on a sheet against the extract, and run the equivalent query against the source. Three outcomes, three diagnoses: the extract's maximum timestamp equals yesterday's — the extraction query never saw today's rows, so look upstream or at ordering; the counts differ but the maximum matches — rows are being filtered or the refresh is incremental and missing updates; both match, yet the dashboard disagrees — you are looking at a different data source, or a cached view. ## Preventing the recurrence Surface freshness in the product: put a "data as of" caption on the dashboard driven by `MAX(updated_at)` from the data itself, not from a refresh log. A refresh log records that a job ran; the data's own maximum timestamp records what the viewer will actually see, and those are exactly the two things that diverge in every scenario above. Beyond that, prefer published, certified data sources over embedded extracts so there is one object to refresh and one timestamp to trust; trigger refreshes from the pipeline rather than a wall clock; and reserve incremental refresh for genuinely append-only data.
- Why is incremental refresh unsafe on a table whose rows are updated in place?Incremental refresh only appends rows whose key exceeds the highest value already stored. A row corrected after it was first extracted is never revisited, so the extract keeps the stale value, and deletions never propagate at all. Only genuinely append-only data — immutable events with a monotonic key — is safe.
- How would you show viewers how fresh a dashboard's data is?Derive the caption from the data, not the schedule: display MAX of the source's update timestamp as a 'data as of' value on the dashboard. A refresh log tells you a job ran; the data's own maximum tells you what the viewer is actually seeing, and those diverge in exactly the failure cases that matter.
- How do you stop a refresh from running before the upstream load has finished?Trigger it from the pipeline once the load completes, rather than scheduling it at a fixed time and hoping. If the refresh must stay on a clock, place it far enough after the load's worst-case completion and alert when the extracted maximum timestamp falls behind expectations.
saying these in an interview costs you the question
- Treats a successful refresh as proof the data is current
- Assumes incremental refresh picks up updated and deleted rows
- Never checks whether the workbook uses the refreshed data source
- Blames caching before comparing extract and source row counts
- Forgets the refresh may run before the upstream load finishes