๐ฌ In plain words: Reports are questions you ask of your data; report types decide which objects a report is even allowed to ask about; dashboards show many answers on one screen. Key trap: who a dashboard "runs as" decides whose data everyone sees.
๐ Example: The VP's dashboard shows 40 deals; a rep opens the same dashboard and sees 12. Check "View Dashboard As": it runs as the viewer, and the rep's sharing only reaches 12 opportunities. Same report, different eyes.
Concept
Reporting starts with Report Types. A report type decides which objects and fields are reportable, and whether the join is inner or outer — that is the "with or without related records" choice. It is the most under-appreciated lever on the platform. Custom report types unlock cross-object paths and relationships that are otherwise hidden.
- Reporting Snapshots: Capture data at a point in time into a custom object to track trends over time.
- Dashboard Running User: Dashboards have a running user; who that user is determines whose data is rendered — making it a critical security decision.
- Large Data Volume (LDV): Reports on massive objects hit row limits and time out, pushing you toward CRM Analytics (Tableau CRM) or an external BI tool.
- External Objects: Reportable only in a constrained manner compared to standard database tables.
๐ง Report TYPE decides what's reportable (with/without related = inner/outer join). Snapshot = trend over time. Dashboard running-user = whose data + security.
Core Q&A
Q: Users say a report is 'missing' records that clearly exist. Most likely causes?
๐ฏ Say this first: It's almost always visibility: sharing, the report type's join (inner join drops records), filters, or the running user's FLS.
A: Work down this diagnostic checklist in order:
- 1. Report Type Join: If set to "Accounts WITH Contacts", any account without a contact disappears (inner join). Switch to "with or without related records" (outer join).
- 2. Report Filters: Check date ranges, "My" scope vs. "All" scope, and picklist status filters.
- 3. Record Sharing: The running user only sees records they have access to. Admin access proves nothing when debugging end-user reports.
- 4. FLS and Record Types: Restricted Field-Level Security or unmapped Record Types hiding the fields being filtered on.
- 5. Layout Missing Fields: The specific field or record type was never added to the Custom Report Type field layout.
Follow-ups (Scenario-Based)
Q1: A dashboard shows different numbers to different users. Is that a bug?
A1: Usually not. It depends on the Running User setting:
- Dynamic Dashboard: Runs as the viewing user, rendering data scoped to each individual's record sharing access (ideal for sales reps).
- Static Dashboard: Runs as a single configured user, so every viewer sees the exact same data as that running user (ideal for company-wide executive metrics).
- Common Misconception: Calling it a bug when there is simply a mismatch between the dashboard's running-user mode and the business requirement. Note that dynamic dashboards also carry strict per-org limits.
Q2: Reports on a 50M-row object time out. Options?
A2: Make filters selective and indexed. Bound them tightly by date and filter on indexed fields (leveraging SOQL query optimizer rules).
- Reporting Snapshots: Use periodic snapshots for historical trends so users query a lean snapshot custom object rather than the massive source object.
- Data Archival: Move cold rows out of the working object into Big Objects or an external archive.
- Off-Platform Analytics: For massive analytical queries, transition off transactional tables to CRM Analytics, Tableau, or a Data Warehouse fed by Change Data Capture (CDC).
- Skinny Tables: Request skinny tables for specific hot report paths to combine frequently used fields.
- Architect Sequence: Filter & Index → Snapshot → Archive → Dedicated Analytics Platform.