Whimsical enchanted forest scene with two gnomes wielding magical wands beside a giant tree. On the left a cloud holds scattered, disordered documents; on the right an organized bookshelf with glowing orbs — symbolizing the cleanup of old file versions into structured, well-governed storage.

SharePoint Online Storage Optimization: Cleaning Up the Red Category

A phased version-history cleanup of the largest Teams-connected SharePoint sites reclaimed 10.1 TB of storage — with reporting, owner communication, and governance built into the process.

In my previous post, SharePoint Online Storage Optimization , I described how a Microsoft 365 tenant can quietly move from “everything is fine” to “we need to act now”. The main driver was not one single oversized site collection, but the accumulated effect of many active Microsoft Teams-connected SharePoint sites, channel sites, and version histories.

The first analysis showed that the red category was the most important area to tackle first: the largest Teams-connected SharePoint sites and channel sites were responsible for a significant part of the total tenant storage consumption - around 40% of the of the total storage usage. They were also active, which meant that simply waiting or hoping for storage usage to stabilize was not a realistic option.

This follow-up is about the next step: moving from analysis to controlled cleanup.

The goal was not to delete user content. The goal was to reduce unnecessary storage consumption caused by old file versions, using SharePoint Online’s automatic version history trimming capabilities.

Why We Started with the Red Category

When dealing with tenant-wide storage pressure, it is tempting to start everywhere at once. I deliberately did not do that.

Instead, the cleanup was focused on the red category first. These were the largest Teams-connected SharePoint sites and related channel sites. Starting there had several advantages:

  • The potential storage impact was high.
  • The number of sites was still manageable.
  • The cleanup approach could be tested in a controlled way.
  • Communication with owners was easier than in a full tenant-wide rollout.
  • The results could be used to decide how to continue with other categories later.

The cleanup was split into two steps:

  1. Init phase — two selected Teams, including their channel sites.
  2. First larger cleanup phase — all remaining sites in the red category.

This phased approach helped to validate the process, the reporting, the communication, and the operational behavior before scaling out.

Communication Before Cleanup

A storage cleanup is not only a technical activity. It also affects site owners, Teams owners, and business stakeholders.

Before running the cleanup, the User Adoption Team informed the Teams and channel owners. This communication was sent one week before the cleanup started.

That step was important because version trimming can be misunderstood. The cleanup does not remove the current files, but it permanently removes file versions that are expired according to the configured version policy. Even if the technical action is safe and supported, the business still needs to understand what is happening.

For me, this was one of the key governance learnings: storage optimization needs transparency. If users only see that “IT deleted something”, trust is lost. If they understand that obsolete file versions are being cleaned up according to a defined policy, the conversation changes.

Building the Working Report

Before running trim jobs, I created a working report for the targeted Teams, channels, sites, libraries, and ownership information.

The report included properties such as:

  • Team name
  • Microsoft 365 group ID
  • Main SharePoint site URL
  • Group owners
  • Channel type
  • Channel name
  • Channel site URL
  • Channel owners
  • Channel document libraries
  • Channel storage usage
  • Automatic expiration status

This report became the operational inventory for the cleanup.

It was especially important because Teams-connected SharePoint storage is not limited to the main team site. Private and shared channel sites can also contribute a relevant amount of storage. Without including channel sites, the analysis would be incomplete.

Creating Version Expiration Reports

The next step was to generate version expiration reports for every targeted site.

For this, I used the site file version expiration report job. In my implementation, this had to be executed in a delegated user context and it had to be executed for every site individually. It isn’t supported to run this jobs in app context.

To keep the reports close to the site and make them accessible for later processing, I created a hidden document library on each site and stored the generated report there.

The important column for the analysis was:

AutomaticPolicyExpirationDate

If a file version had an automatic policy expiration date in scope, it could be considered for deletion by the automatic trim job.

This made it possible to estimate the cleanup potential before actually deleting versions.

Init Phase: Validating the Approach

The init phase covered two selected Teams including their channel sites. The intention was to validate the complete process end to end:

  1. Prepare the owner communication.
  2. Create the Teams, channels, and site inventory.
  3. Generate version expiration reports.
  4. Calculate potential savings.
  5. Run the cleanup jobs.
  6. Enable automatic version history trimming on the sites.
  7. Compare expected and actual storage savings.

Across the init phase, the pre-cleanup report showed approximately 320.34 GB of version storage marked for expiration out of approximately 652.66 GB analyzed in the report data. That equals a projected cleanup potential of approximately 49.1% for the analyzed version storage.

After running the cleanup jobs, the init phase released approximately 320.42 GB of storage.

The cleanup was triggered with PnP PowerShell by queuing the automatic version trim job and enabling automatic version expiration on the site:

New-PnPSiteFileVersionBatchDeleteJob -Automatic -Connection $cnSite
Set-PnPSiteVersionPolicy -EnableAutoExpirationVersionTrim $true -Connection $cnSite

This confirmed that the approach worked and that the potential savings were not only theoretical.

Scaling Out: First Cleanup Phase for the Remaining Red Category

After the init phase, the same approach was applied to the remaining sites in the red category.

The process stayed the same, but one operational detail became important: authentication throttling.

Because the reporting needed to run in user context and had to process many sites, the sites were split into batches of 20. This reduced the risk of running into login throttling against Microsoft Entra ID and made the execution easier to control.

The cleanup results per batch were:

Batch Storage released
1 2,219.35 GB
2 1,503.99 GB
3 724.02 GB
4 838.05 GB
5 872.20 GB
6 428.41 GB
7 506.34 GB
8 1,034.76 GB
9 150.49 GB
10 804.37 GB
11 511.87 GB
12 439.33 GB

In total, this phase released approximately 9.79 TB of storage.

For the complete red category, this means:

  • Total storage of all red category sites: 36.02 TB
  • Storage released by cleanup: 10.1 TB
  • Relative reduction: 28.04%

That is a significant result. It shows that version history optimization is not a small housekeeping task. In active collaboration environments with many Teams-connected sites, old versions can become one of the largest storage consumers.

What Worked Well

The most important success factor was the phased approach.

Starting with two Teams made the process manageable and helped to validate the reporting and cleanup logic before applying it to the rest of the red category. It also gave us concrete figures that could be shared with business and project owners.

The second success factor was visibility. The inventory report made it possible to understand which Teams, channels, sites, and libraries were involved. The pre-cleanup reports made it possible to estimate the potential impact. The cleanup results then provided measurable evidence.

The third success factor was automation. Doing this manually in the SharePoint Admin Center would not have been realistic. The process needed scripting, repeatability, and reporting.

Lessons Learned

1. Channel sites must be part of the analysis

If the analysis only looks at the main Teams-connected SharePoint site, it misses part of the picture. Private and shared channel sites can have their own storage footprint and must be processed separately.

2. Reporting before deletion is essential

The expiration report is not just a technical helper. It is the basis for business communication, validation, and risk reduction. It gives a view of the expected effect before cleanup jobs are queued.

3. User-context execution can influence scaling

In this case, generating the reports had to be done per site and in delegated user context. At larger scale, that affects how the process should be batched and monitored.

4. Batching makes the rollout controllable

Splitting the remaining red category into batches of 20 sites made the cleanup easier to operate. It helped avoid authentication pressure and provided clear checkpoints.

5. Automatic version history trimming is effective, but it needs governance

Enabling automatic trimming is not only a technical setting. It should be connected to an overall governance model: owner communication, reporting, exceptions, quotas, and recurring review.

Script Contribution

As part of this work, I also prepared the supporting script and contributed it to the PnP script samples repository.

You can find the committed script sample here:

SharePoint storage optimization script sample commit

The script was created to support the practical cleanup process: collecting Teams and channel site information, preparing the data needed for reporting, and helping to execute the process in a repeatable way.

My Main Takeaway

The biggest takeaway from this phase is simple:

SharePoint Online storage optimization becomes much more manageable when it is treated as a controlled governance process, not as a one-time cleanup task.

The technical feature — automatic version history trimming — is only one part of the solution. The real value comes from combining it with:

  • clear categorization of storage consumers,
  • transparent communication,
  • impact analysis before deletion,
  • controlled batching,
  • measurable reporting,
  • and follow-up decisions with business and project owners.

In this cleanup, the red category alone released 10.1 TB of storage. More importantly, the process created a repeatable pattern for future optimization work.

What Comes Next

The next step is to decide how to proceed with the remaining storage categories and how to embed this into a sustainable governance model.

Possible follow-up areas are:

  • applying the same cleanup pattern to the yellow category,
  • reviewing quota models for Teams-connected sites,
  • improving owner-facing storage visibility,
  • creating recurring storage reports,
  • and defining when sites should move between green, yellow, and red categories.

Storage optimization is not finished after one cleanup run. But this phase showed that with the right reporting and a controlled process, it is possible to reclaim a meaningful amount of storage without attacking the current working content of users.