River
Y CombinatorBacked by Y Combinator

Business & Revenue OpsFree

Unused Report Audit and Retirement Plan

Send the asset list and whatever usage data you have, get every report a keep, merge or retire call with a sequence.

Start here

River starts the audit from the asset list, not the usage list, and that one choice changes the answer. Every report in the estate gets a row, including the ones your usage data has already dropped. Each row carries an owner, a real last-viewed date pulled from exported activity rather than the built-in view, the cadence the report is meant to run at, and the decision it supports. Anything that cannot name a decision gets a retire or merge call.

Every guide to this says the same thing: pull last-viewed dates and retire whatever nobody opened in ninety days. It sounds obviously right and it quietly fails, because the source it tells you to pull from has a retention ceiling shorter than the reports you are trying to judge. A report absent from the usage view looks identical to a report that does not exist, so the audit sees the healthy reports clearly and is blind to exactly the population it was built to find.

Written for whoever owns the BI estate and has been told to clean it up before a platform migration, and for the analyst who inherited 400 reports and two authors who left. Reach for it when the refresh window is full or a field cannot be dropped. The definitions the survivors compute belong in a metric register, each survivor's purpose in a dashboard spec, and the weekly view in a RevOps dashboard pack.

The usage report could not see 118 of the 159 retirements

The ceilings are published. Power BI's usage metrics model contains usage data for the last 30 days only, and the report itself only lists content opened inside that window. Looker stores a maximum of 90 days of historical query and event data. Neither ceiling reaches an annual cycle, so no BI tool can tell you whether a year-end report is used. That question has to be answered from the schedule list and the people on it.

Ardsley Group's asset list held 412 reports. The 30-day usage view showed 168. Working the other 244 from thirteen months of exported activity split them four ways. There were 118 unopened for the whole period and 74 opened inside their own cadence but outside the window. Another 29 were delivered by a schedule and never opened in the tool, and 23 were copies whose live twin was already in the usage view. Only the first group retires, and the naive audit could not see any of it.

The decision column does the rest. Of the 168 that looked alive, 104 named a decision and 64 could not, and those 64 are the expensive ones because they consume refresh capacity while looking justified. Forty-one retire, 23 merge. Across the estate that is 207 keep, 159 retire and 46 merge. The migration wanted 47 fields dropped and was blocked; 31 of them are only referenced by retiring reports, so the blocker falls to 16, and those 16 need a conversation rather than an audit.

How it works

  1. Send the asset list

    Every report the platform knows about, plus whatever usage or activity export you can get.

  2. Find the blind spot

    River works out which reports your usage source cannot see, and why each one is missing.

  3. Force the decision

    Each report names the decision it supports, judged against its own cadence rather than a fixed window.

  4. Take a sequence in

    Keep, merge or retire on every row, ordered so nothing breaks the report downstream of it.

What you get

  • Every report on the asset list gets a row, not just the recently opened ones
  • A last-viewed date from exported activity, with the retention ceiling stated beside it
  • The cadence each report runs at, so a quarterly report is judged quarterly
  • Scheduled deliveries counted separately from human opens, because only one is evidence
  • The decision each report supports, written out, or the report goes on the list
  • A retirement sequence ordered by dependency, and the fields each wave releases

Common questions

Why not just use the built-in usage report?

Because it has already discarded your candidates. Power BI's improved usage report only includes content opened in the past thirty days, so a report abandoned in March is not on it in September. At Ardsley that hid 118 of the 159 retirements, or 74 percent of the work. The asset list is the only complete population.

How do you judge a quarterly or annual report?

Against its own cadence, and from a source that outlives it. A quarterly report legitimately shows zero views in eleven weeks of thirteen, so a ninety-day window fails it for running correctly. Where the cadence is longer than the platform's retention ceiling, the evidence is the subscription list and whether a named human is still on it.

Does a scheduled email count as usage?

It counts as delivery, which is a different fact, and the good tools already separate them. Looker's unused-content tile reports views in the UI, in an embed and through the API alongside scheduled deliveries as its own count. A report emailed weekly to a list nobody reads generates delivery events forever and no evidence at all.

What if a report is opened often but supports no decision?

That is the most expensive category and the one a usage-only audit protects. Sixty-four of Ardsley's 168 live reports could not name a decision, and they were being opened and refreshed. Forty-one retired and 23 merged. The same test, applied to a page rather than an estate, is the executive one-pager.

How does this help a migration?

Because a report is a dependency, and retiring it releases the fields it pinned. Ardsley's migration wanted 47 fields dropped and was blocked on all of them. Twelve turned out to be referenced by nothing and 19 only by retiring reports, so the blocker fell to 16 real conversations. The sequence puts the releases in dependency order.

What if I have no usage data at all?

Then the audit runs on the asset list, the schedule list and the owner column, and says so. Ownership plus cadence plus a named decision already sorts most of an estate, because the reports nobody can place are the reports nobody uses. The output marks every verdict reached without usage evidence, so the risky retirements are visible.

Will retiring a report break something downstream?

That is what the sequence is for. Reports depend on datasets and datasets on fields, so retiring in the wrong order breaks a survivor. River orders the waves so each one only removes things nothing surviving depends on, and where two reports depend on each other it says which conversation has to happen first.

Unused Report Audit and Retirement Plan

Fill in the form and your workspace opens with the work already underway.