You open library settings, set major versions to 5, click OK, and SharePoint replies: For the number of major versions that may be stored, you must enter a number between 100 and 50000. One admin on Microsoft Q&A had 1.4 million files to fix and had raised the ticket "several times" before finding out the answer is: not through that page.
The floor is in the page, not the platform
The modern library-settings UI enforces 100 as a minimum. The platform does not. Anything that talks to SharePoint directly, PnP PowerShell, CSOM, the REST API, can set a lower number:
Connect-PnPOnline -Url https://contoso.sharepoint.com/sites/Finance -Interactive
Set-PnPList -Identity 'Documents' -EnableVersioning $true -MajorVersions 5
Get-PnPList -Identity 'Documents' | Select-Object Title, MajorVersionLimit
Run it per library. If you have many, wrap it in Get-PnPList | Where-Object BaseTemplate -eq 101 and loop.
What a lower limit does — and doesn't — do
Lowering the limit changes what happens on the next save: SharePoint keeps the newest N versions of that file and drops the oldest. Files nobody touches again keep every version they have today.
So on a library where the storage problem is a thousand archived files with 200 versions each, setting the limit to 5 recovers nothing until those files are edited. To reclaim the space now you need to trim existing versions.
Trimming existing versions
Microsoft added on-demand trim jobs to the SharePoint Online Management Shell. They run server-side, asynchronously, and they delete permanently.
Connect-SPOService -Url https://contoso-admin.sharepoint.com
$site = 'https://contoso.sharepoint.com/sites/Finance'
# 1. What WOULD be deleted? (report only)
New-SPOSiteFileVersionExpirationReportJob -Identity $site -ReportUrl "$site/Shared Documents/version-report.csv"
Get-SPOSiteFileVersionExpirationReportJobProgress -Identity $site -ReportUrl "$site/Shared Documents/version-report.csv"
# 2. Then trim - pick ONE mode:
New-SPOSiteFileVersionBatchDeleteJob -Identity $site -MajorVersionLimit 5 -MajorWithMinorVersionsLimit 0 # keep newest 5 per file
# New-SPOSiteFileVersionBatchDeleteJob -Identity $site -DeleteBeforeDays 365 # drop versions older than a year
# New-SPOSiteFileVersionBatchDeleteJob -Identity $site -Automatic # Microsoft's intelligent thinning
Get-SPOSiteFileVersionBatchDeleteJobProgress -Identity $site
New-SPOListFileVersionBatchDeleteJob -Site $site -List 'Documents' ... does the same for one library.
Three things to know before pressing enter:
- It is permanent. Trimmed versions are not in any recycle bin. Microsoft's own doc says to run the what-if report first. Do.
- The report is a CSV of every version that would go, which is exactly what you want to look at, but on a large site it is huge and slow.
- Automatic mode keeps more recent versions and thins older ones (Microsoft quotes up to 96% storage reduction). It is the safer default if you have no policy to enforce.
The bit that is genuinely hard by hand
The problem on the Q&A thread was not the command. It was confidence: which libraries have the bloat, how many GB a 5-version rule would reclaim per library, and which files would lose versions that someone might still want. The expiration report answers that per site, in a CSV nobody enjoys reading.
TrimVersions365 exists for that step: a free analysis that shows files, historical versions and estimated version storage per library; a What-if tab that shows exactly what a given policy would delete before it deletes anything; and an execute step that only ever removes old versions, never the current one and never the file. Under the hood it calls the same version-delete endpoint, one version at a time, with a record of what went.
Suggested order
- Set the going-forward limit with
Set-PnPList(or intelligent versioning tenant-wide). - Run the what-if for one big library.
- Trim that library, verify storage drops (allow 24–48 hours for the numbers to update).
- Repeat where it matters. Leave small libraries alone.