Clarify scope first: which dashboards, SQL/data sources, timezones shown, definition of “active” (any event vs specific events), and the date range with discrepancy. Then reproduce both dashboards with controlled queries and run focused checks for aggregation, timezone, duplication, and filtering.1) Reproduce baseline DAU from each sourcesql
-- Dashboard A: using events_a table
SELECT DATE(event_timestamp AT TIME ZONE 'UTC') AS day_utc,
COUNT(DISTINCT user_id) AS dau_a
FROM events_a
WHERE event_timestamp >= '2025-11-01' AND event_timestamp < '2025-11-08'
GROUP BY 1
ORDER BY 1;
-- Dashboard B: using events_b table or materialized view
SELECT DATE(event_time AT TIME ZONE 'America/Los_Angeles') AS day_pst,
COUNT(DISTINCT user_id) AS dau_b
FROM events_b
WHERE event_time >= '2025-11-01' AND event_time < '2025-11-08'
GROUP BY 1
ORDER BY 1;
Compare results row-by-row.2) Check timezone handling- Convert both to a common timezone and to UTC-day boundary:sql
SELECT DATE((event_timestamp AT TIME ZONE 'UTC')) AS day_utc,
COUNT(DISTINCT user_id) FROM events_a GROUP BY 1;
SELECT DATE((event_time AT TIME ZONE 'UTC')) AS day_utc,
COUNT(DISTINCT user_id) FROM events_b GROUP BY 1;
- Spot off-by-one shifts (e.g., same user counted on adjacent days).3) Check aggregation logic (distinct vs count)sql
-- Are dashboards using DISTINCT user_id or counting events?
SELECT day_utc, COUNT(*) AS events, COUNT(DISTINCT user_id) AS distinct_users
FROM (
SELECT user_id, DATE(event_timestamp AT TIME ZONE 'UTC') AS day_utc FROM events_a
) t GROUP BY day_utc;
If one dashboard used COUNT(*) instead of COUNT(DISTINCT), that'll inflate DAU.4) Check event duplication / ingestion duplicatessql
-- Identify duplicate event_ids or identical rows
SELECT event_id, COUNT(*) FROM events_a GROUP BY event_id HAVING COUNT(*)>1 LIMIT 10;
-- Or duplicates per user-day
SELECT user_id, day_utc, COUNT(*) AS hits
FROM (
SELECT user_id, DATE(event_timestamp AT TIME ZONE 'UTC') AS day_utc, event_signature
FROM events_a
) t
GROUP BY user_id, day_utc HAVING COUNT(*) > 1 ORDER BY hits DESC LIMIT 20;
If duplicates present, dashboards must dedupe by event_id or use DISTINCT user.5) Check filtering differences (event types, user segments, exclude bots)sql
-- Compare predicates used
SELECT COUNT(DISTINCT user_id) FROM events_a WHERE event_type IN ('open','engage');
SELECT COUNT(DISTINCT user_id) FROM events_a WHERE user_agent NOT LIKE '%bot%';
Ask for or inspect dashboard queries to find mismatched WHERE clauses (is one excluding test users, opt-outs, or merging anonymous IDs?).6) Row-level diff samplingsql
-- Users counted in A but not B for a given day
WITH a AS (
SELECT DISTINCT user_id FROM events_a WHERE DATE(event_timestamp AT TIME ZONE 'UTC')='2025-11-05'
),
b AS (
SELECT DISTINCT user_id FROM events_b WHERE DATE(event_time AT TIME ZONE 'UTC')='2025-11-05'
)
SELECT 'only_in_a' AS side, a.user_id FROM a LEFT JOIN b USING (user_id) WHERE b.user_id IS NULL
UNION ALL
SELECT 'only_in_b', b.user_id FROM b LEFT JOIN a USING (user_id) WHERE a.user_id IS NULL;
Sample 20 user_ids and inspect raw events to see why counted in one and not the other.7) Verify dedup/identity resolution (anonymous_id vs user_id)- Check joins or mapping tables used to resolve identities across sources; mismatches can cause under/over-counting.Interpretation checklist:- If counts equal after converting timezones to same boundary → timezone bug.- If COUNT(*) >> COUNT(DISTINCT) → aggregation mistake.- If many duplicate event_ids → ingestion duplication.- If set differences reveal excluded user cohorts → filtering mismatch.Actionables: share these SQLs with engineers, compare dashboard SQL, fix whichever layer is incorrect (ETL dedupe, timezone normalization, aggregation change, or filter alignment), and add unit tests/monitoring to prevent regressions.