Cause 1: Caching and refresh lag
Most BI tools don't query the live database on every dashboard view — they run on a schedule (hourly, nightly) or cache results until manually refreshed. A dashboard showing yesterday's total while today's orders have already landed in the database is expected behavior, not a bug, if the refresh hasn't run yet.
-- Confirm how recent the underlying data actually is
SELECT MAX(updated_at) AS latest_row
FROM orders;
-- Compare this against the dashboard's stated last-refresh time
Cause 2: Timezone cutoff mismatches
-- If order_date is stored in UTC but the dashboard buckets in a local timezone,
-- rows near midnight shift between days between the two totals
SELECT
order_id,
order_date AS utc_timestamp,
order_date AT TIME ZONE 'America/New_York' AS local_timestamp
FROM orders
WHERE order_date BETWEEN '2026-08-21 22:00:00' AND '2026-08-22 02:00:00';
-- Rows here can land on Aug 21 in one timezone and Aug 22 in the other
Cause 3: Hidden BI tool filters
Row-level security, permission-based filters, and dashboard-level defaults configured inside a BI tool often don't show up as a visible filter chip on the dashboard itself. Two people viewing the same dashboard can legitimately see different totals if one has a region restricted by a permission filter the other doesn't. The SQL-side check is to reproduce the dashboard's stated filters explicitly and compare — if a manual query with the same visible filters still doesn't match, an invisible filter is the likely explanation, and the BI tool's data model or permissions configuration needs checking directly.
Cause 4: Aggregation grain mismatches
-- Summing at the order level
SELECT SUM(total_amount) FROM orders;
-- Summing at the line-item level — will differ if line items include
-- separately-tracked amounts like shipping or tax not in total_amount,
-- or if total_amount itself is a pre-computed, possibly stale, rollup
SELECT SUM(unit_price * quantity) FROM order_line_items;
Both queries are "correctly" summing revenue — they're just summing different things. Matching the dashboard's actual grain, not just its label, is the fix.
Real-world example: a revenue dashboard $1,800 short
A dashboard shows $52,300 in revenue for the current day; a direct query against the orders table returns $54,100. Checking the dashboard's refresh metadata shows it last ran 3 hours ago. Querying orders for rows created in the last 3 hours and summing their amounts returns exactly $1,800 — the dashboard isn't wrong, it simply hasn't ingested the last 3 hours of orders yet. The fix here isn't a data correction; it's either shortening the refresh interval or clearly labeling the dashboard with its actual "as of" time so viewers don't mistake a stale snapshot for a live number.
Common mistakes
- Assuming the database is always "correct" and the dashboard is wrong, without checking which one is actually stale or scoped differently.
- Not checking the dashboard's actual filter and permission configuration before concluding the underlying data is broken.
- Comparing totals without confirming both are summing at the same grain.
- Ignoring timezone settings on both the BI tool and the database connection when debugging a near-midnight discrepancy.
Key takeaways
- A dashboard-vs-database mismatch isn't automatically a data bug — check refresh timing before assuming corruption.
- Timezone bucketing differences show up specifically as errors clustered near midnight boundaries.
- Hidden BI filters can make the same dashboard show different numbers to different viewers.
- Always confirm both sides are aggregating at the same grain before comparing totals.