How to Run a Salesforce Inactive User Report (and What to Do With It)
LastLoginDate alone lies. Here's the right way to identify truly inactive users — and how to build a document your Finance team will act on.
Why LastLoginDate isn't enough
Most admins check LastLoginDate on the User object. It's fast and it's tempting. The problem: LastLoginDate does not tell you how that login happened. A scheduled API call from an integration counts as a login. A password reset flow can update it. A single accidental click counts the same as an active daily user.
For meaningful inactive user identification — the kind that holds up in a Finance conversation — you need LoginHistory.
The right SOQL query
Run this in Developer Console or Workbench to find users with no interactive logins in the last 90 days:
SELECT UserId, LoginTime, LoginType, Status
FROM LoginHistory
WHERE LoginTime = LAST_N_DAYS:90
AND LoginType IN (
'Application', 'SAML', 'SSO',
'Remote Access 2.0'
)
ORDER BY LoginTime DESCCross-reference the UserId values against your active Users. Users who appear nowhere in this result set have not had an interactive login in 90 days. That's your starting list.
Filtering out false positives
Before you send this list to Finance, remove:
- Integration users. Any user whose profile name or username contains "integration", "api", "system", or "service" should be flagged separately — not counted as an inactive human user.
- Recently onboarded users. A user created in the last 30 days who hasn't logged in yet isn't inactive — they're new.
- Known leave cases. Parental leave, long-term sick leave, sabbatical. If you have a process for flagging these, exclude them and document why.
Calculating the dollar impact
As of August 2025, Salesforce list prices are:
- Salesforce Enterprise: ~$165/seat/month
- Salesforce Unlimited: ~$330/seat/month
Multiply your confirmed-inactive count by the per-seat cost for your edition. 15 inactive Enterprise users = $2,475/month = $29,700/year. Put that number in your renewal conversation.
What to do with the list
- Deactivate confirmed-inactive users. Coordinate with HR to confirm they've left or been reassigned. Deactivating (not deleting) preserves their record ownership and history.
- Negotiate your renewal. Take your verified inactive-user list and savings figure into the Salesforce AE conversation. You're not asking for a discount — you're presenting evidence that you need fewer seats.
- Set a cadence. Do this analysis quarterly, not just at renewal time. Users go inactive year-round; catching them early prevents 12 months of paying for nothing.
The problem with doing this manually
The SOQL approach works. But it requires a Salesforce admin to run it, export it, build a spreadsheet, and format it for Finance — every quarter, manually. The LoginHistory object is also only queryable for the last 180 days, and only via API (not standard reports). Most orgs run this once before renewal and forget it exists.
SpendReady runs this analysis weekly and delivers a formatted PDF to your inbox — and your CFO's inbox. No SOQL, no spreadsheets, no manual work.
Get your first audit free →