← All articles
·8 min read·How-toLicensing

Microsoft 365 Usage Reports: What 'Active' Actually Means (and When It Lies)

Every recommendation in a license audit — reclaim this seat, downgrade that one, leave the third alone — rests on one question: did this person use it? Microsoft answers that question better than almost any other vendor. But the answer has semantics, and misreading them cuts both ways: you either strip a license from someone who needed it, or you keep paying for hundreds of seats that look busy and aren't.

We learned the second lesson the hard way. In one ~1,700-user tenant we analyse, a data-handling slip in our own pipeline made every licensed user look active as of the latest report for three product categories — for months. The fix was one line. The cleanup deleted about a million bogus rows. More on that below, because the same mistake is easy to make in a spreadsheet.

Where the usage data actually comes from

There are two sources, and they measure different things.

The usage reports (admin center → Reports → Usage, or the Graph reports API) are per-user, per-product summaries Microsoft generates on a schedule. The ones that matter for licensing decisions:

  • Microsoft 365 Apps usage — which apps (Outlook, Word, Excel, PowerPoint, Teams, OneNote) each user launched, and on which platform: Windows, Mac, web, or mobile. This is the only report that tells you what kind of client someone uses.
  • Email activity — send, receive, and read actions per mailbox.
  • Teams user activity — chat messages, calls, and meetings.
  • OneDrive and SharePoint activity — files viewed, edited, shared, or synced.
  • Active users — the roll-up: one row per user with a last-activity date for each service.

Each row carries two dates: a report refresh date (when Microsoft generated the report) and a last activity date per service (the last day the user did something that counts).

The sign-in logs (Entra ID → Sign-in logs) are the other source: one event per authentication, with the app, the client, and the outcome. They are event-level rather than summarised, and Entra keeps them for 30 days on P1/P2 and 7 days on the free tier. If you want a 90-day view of sign-ins, you have to collect them yourself.

What "active" means, report by report

"Active" in every report means at least one qualifying action in the period — and the qualifying action is defined per service:

  • Exchange: sent, received, or read an email. A mailbox that receives newsletters and is never opened still shows as active for "received". Look at read and sent when you want to know if a human is there.
  • Teams: posted a chat message, made or joined a call, or attended a meeting. Having Teams open in the tray does not count.
  • OneDrive / SharePoint: viewed, edited, synced, or shared a file. A laptop with the sync client running counts as active every time it syncs.
  • Apps usage: launched the app on that platform. This is the cleanest signal of the lot — you cannot accidentally "launch Excel on Windows" from a phone — which is why it anchors web-only downgrade decisions.

The period matters too. Reports come in 7-, 30-, 90-, and 180-day flavours. A user with no activity in the D7 report may be on leave; a user with no activity in D90 has a pattern.

Five ways the data lies, or gets misread

1. A blank last-activity date is not "today"

When a user did nothing in the period, the last-activity date for that service is blank. It is not "unknown", and it is emphatically not the report refresh date. It means no activity in this window.

This is our confession. Our connector once filled blank last-activity dates with the report refresh date, on the theory that a row in the report meant something happened. It didn't. For the Exchange, OneDrive, and SharePoint roll-ups, every licensed user was stamped "active as of the last report" on every sync. Inactive users vanished from the inactive list. Downgrade candidates were undercounted. The bug ran quietly because the output looked plausible: everyone was active, and everyone being active is exactly what a busy tenant looks like.

If you build your own pipeline or spreadsheet, the rule is: blank means no activity. Never substitute another date.

2. The report is two to three days behind

The refresh date is typically 48–72 hours before today, and a given day's activity can take that long to land. "No activity yesterday" is not evidence of anything. Treat the most recent three days as unknown and make decisions on the window before that.

3. A sign-in is not usage

Sign-in logs are noisy in a specific way: background token refreshes, the Windows sign-in itself, Intune check-ins, and the Office licensing service all generate sign-in events without a human doing anything. A user with fifty sign-ins a week and zero app launches is a device, not a person at work. Use sign-ins to confirm someone can still access the tenant; use the usage reports to decide whether they do.

4. Concealed names break every join

Microsoft 365 has a privacy setting — Settings → Org settings → Services → Reports → Display concealed user, group, and site names in all reports — and it is on by default in many tenants. With it on, every usage report replaces the user principal name with a pseudonym. Your export still has 1,700 rows; none of them can be matched to a license. Either turn it off (with the appropriate approvals — it exists for a reason) or resolve the pseudonyms through Graph before you try to join.

5. Not every active row is a human

Shared mailboxes receive mail all day. Room and equipment resources accept meeting invites. Service accounts run scheduled jobs that read mail and touch SharePoint. All of them show as active in one report or another, and none of them justify a per-user license. Filter them out before you compute inactivity, or your "active users" number will be inflated by exactly the accounts that should cost nothing.

Pick an evidence window and hold it

The window you judge activity over is a policy decision, and it should be written down. Our default is 90 days:

  • 30 days flags anyone on extended leave, a long project site rotation, or a month of back-to-back travel. Too twitchy.
  • 180 days is slower than most NCE renewal cycles give you to act on the findings. Too slow.
  • 90 days survives a quarter's worth of normal absence and lines up with Microsoft's own D90 report period, so the two views agree.

Whatever you choose, the reports are snapshots — each pull tells you the latest activity, not a history. If you want to say "no activity in 90 days" with confidence, you need to have been collecting the reports (or the sign-in logs, which expire in 30) for at least that long. Start collecting before you need the answer.

A pre-flight check before acting on any usage report

  1. Check the concealment setting. If the names are pseudonyms, nothing downstream is valid.
  2. Note the refresh date and treat the last 72 hours as unknown.
  3. Treat blank dates as no activity, never as today.
  4. Exclude shared mailboxes, resources, and service accounts before counting.
  5. Require two signals before calling a person inactive — no app launches and no Exchange or Teams actions — and require the apps report specifically before calling anyone web-only.
  6. Check the client platform before a cross-tier downgrade. A user with Windows app launches probably has a managed device, and dropping from E3 to E1 also drops Intune. Web-only users are the safe candidates; desktop users need a conversation first.
  7. Keep your own history. Ninety days of daily pulls is the minimum that makes a 90-day claim honest.

Done manually, this is a quarterly afternoon with Graph exports and a lookup table — and step 7 is the one that quietly stops happening. SeatPrune collects the reports and sign-ins on a schedule, applies every rule above (blank means blank; resources excluded; platform-aware downgrades), and shows you the evidence window each finding rests on, so the decision to cut a seat is one you can defend.

Microsoft's usage data is good enough to run a license programme on. It is also good enough to be confidently wrong with. The difference is knowing what each column means before you sort by it.

Find out what your tenant is wasting

SeatPrune audits your Microsoft 365 licenses and prices every finding in $/month. Free up to 200 users.

Start Free