🚀 Executive Summary

TL;DR: Companies often waste millions annually on unused SaaS subscriptions due to decentralized purchasing, forgotten trials, and employee turnover, leading to ‘SaaS Sprawl.’ This waste can be stopped by implementing systematic usage audits, establishing centralized procurement processes, and conducting regular access reviews to de-provision inactive accounts.

🎯 Key Takeaways

  • Utilize a ‘Last Seen’ Audit Script by leveraging SaaS platform APIs (e.g., Slack, GitHub, Atlassian, AWS) to pull user last login timestamps and flag accounts inactive for 90+ days.
  • When de-provisioning, downgrade inactive users to a free tier or deactivate them instead of outright deletion to preserve associated data (e.g., in Jira or CRM) while stopping billing.
  • Establish a ‘Permanent Fix’ by implementing centralized procurement with a designated gatekeeper, creating a SaaS Registry, mandating quarterly access reviews, and consolidating billing.

$21 million annually wasted on unused SaaS. 
Here's how to see it (and stop it).

Discovering millions in SaaS waste is common, stemming from forgotten trials and employee turnover. Systematically auditing usage, implementing central procurement, and conducting regular access reviews can reclaim your budget and secure your stack.

I Saw a Ghost Rack Up a $60k Bill. Here’s How We Exorcised Our SaaS Budget.

I remember the meeting like it was yesterday. We were in our Q3 budget review, and the finance controller flagged a recurring $5,000 monthly charge from a high-end data visualization platform. I didn’t recognize it. My lead architect didn’t recognize it. We dug into the billing and found it was tied to a project account created by an engineer who had left the company eighteen months ago. For over a year, we’d been paying for a top-tier enterprise license for a tool that exactly zero people were using. It was a ghost in the machine, quietly siphoning $60,000 a year from our budget. This isn’t a rare horror story; it’s the default state of affairs in most fast-moving tech companies.

The “Why”: How We Got Here is Depressingly Simple

This isn’t about blaming individuals. It’s a systemic issue. We call it “SaaS Sprawl,” and it’s born from good intentions. An engineer needs a tool for a quick Proof-of-Concept (PoC), swipes a corporate card, and gets to work. The PoC fails or the project pivots, but the subscription? It’s on auto-renew. Multiply that by a hundred engineers, add a dash of employee turnover, and sprinkle in the lack of a central gatekeeper. Suddenly, you’re paying for three different project management tools, four monitoring platforms, and a suite of “shadow IT” that security has no idea about.

The root cause is decentralized purchasing and a lack of ownership. When anyone can buy anything, nobody is responsible for cleaning it up.

The Fixes: From Duct Tape to a New Foundation

Look, you can’t boil the ocean. You need to triage. Here are three approaches I’ve used, ranging from a quick weekend hack to a full-blown process overhaul.

1. The Quick Fix: The “Last Seen” Audit Script

This is the “stop the bleeding now” approach. It’s manual, it’s a bit hacky, but it gets you 80% of the way there in a day. Most major SaaS platforms (Slack, GitHub, Atlassian, AWS) have APIs that let you pull user data, including the last login timestamp. Your goal is to write a simple script that connects to your most expensive tools and flags any user who hasn’t logged in for 90+ days.

Here’s a pseudo-code concept for a Python script targeting a generic SaaS API:


import requests
import datetime

API_KEY = "your_secret_api_key"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
NINETY_DAYS_AGO = datetime.datetime.now() - datetime.timedelta(days=90)

def get_all_users():
    # Function to paginate through the /users API endpoint
    response = requests.get("https://api.saas-vendor.com/v1/users", headers=HEADERS)
    return response.json()["users"]

def find_inactive_accounts(users):
    inactive_users = []
    for user in users:
        last_login_str = user.get("last_login_timestamp")
        if last_login_str:
            last_login_date = datetime.datetime.fromisoformat(last_login_str)
            if last_login_date < NINETY_DAYS_AGO:
                inactive_users.append({
                    "email": user["email"],
                    "last_login": last_login_date.strftime("%Y-%m-%d")
                })
    return inactive_users

all_company_users = get_all_users()
zombie_accounts = find_inactive_accounts(all_company_users)

print("Found inactive accounts to investigate:")
for account in zombie_accounts:
    print(f"- {account['email']} (Last seen: {account['last_login']})")

Run this for your top 5-10 most expensive services. You will absolutely find paid seats for people who have left the company or teams that have been disbanded. De-provision them immediately. Boom, instant savings.

Pro Tip: Don’t just delete them. Downgrade them to a free tier or deactivate them first. Deleting a user can sometimes orphan their data (e.g., in Jira or a CRM), causing a much bigger headache. Deactivating preserves the data while stopping the billing.

2. The Permanent Fix: Centralized Procurement & Quarterly Reviews

A script is a temporary patch. The real fix is cultural and procedural. You need to establish a single pipeline for all SaaS purchasing and a regular cadence for reviewing what you own. It’s not sexy, but it works.

Step Action Required
1. Establish a Gatekeeper Designate a team (IT, FinOps, or even a DevOps lead) as the sole approver for new SaaS tools. All requests must go through them. No more “I’ll just put it on my card.”
2. Create a SaaS Registry A simple shared spreadsheet or a tool like Confluence. Every approved tool is logged with its owner, cost, renewal date, and business justification.
3. Mandate Quarterly Access Reviews Every 90 days, the owner of each tool is automatically prompted to review their user list. They must attest that every user still needs access. This shifts the burden of cleanup from a central team to the people who actually use the tool.
4. Consolidate Billing Work with finance to move all SaaS subscriptions to a single, centrally managed payment method. This gives you one place to see all the charges instead of hunting through dozens of expense reports.

This approach transforms SaaS management from a chaotic free-for-all into a deliberate, managed process. It takes time to implement but prevents the problem from recurring.

3. The ‘Nuclear’ Option: The SaaS Moratorium

Sometimes the sprawl is so bad you need to take drastic measures. I’ve only had to do this once, but it was incredibly effective. We declared a 30-day “SaaS Moratorium.” For one month, no new software could be purchased, period. No exceptions.

During this freeze, we forced every single team lead to do two things:

  • Inventory: List every single SaaS tool their team uses and pays for.
  • Justify: Write a one-paragraph justification for why each tool is critical to business operations.

Anything that wasn’t on a list with a valid justification by Day 30 was put on the chopping block. The peer pressure and visibility were immense. We discovered three different teams were paying for three different (and expensive) survey tools. We consolidated to one, saving nearly $100k annually. We cut dozens of smaller, forgotten tools that nobody was willing to fight for.

Warning: This is a high-friction move. It requires strong executive buy-in because you will get pushback from teams who feel their workflow is being disrupted. Use it as a one-time reset button, not a recurring strategy.

Ultimately, wrangling your SaaS spend isn’t just about saving money—it’s about security, efficiency, and operational maturity. Start with the script, build towards the process, and keep the nuclear option in your back pocket. Your CFO will thank you.

Darian Vance - Lead Cloud Architect

Darian Vance

Lead Cloud Architect & DevOps Strategist

With over 12 years in system architecture and automation, Darian specializes in simplifying complex cloud infrastructures. An advocate for open-source solutions, he founded TechResolve to provide engineers with actionable, battle-tested troubleshooting guides and robust software alternatives.


🤖 Frequently Asked Questions

âť“ How can I quickly identify unused SaaS accounts in my organization?

Implement a ‘Last Seen’ Audit Script leveraging SaaS APIs to check user last login timestamps. Flag and investigate accounts inactive for 90+ days, then de-provision them by downgrading or deactivating.

âť“ What are the different strategies for managing SaaS sprawl, and how do they compare?

The article outlines three strategies: a ‘Quick Fix’ (API-based ‘Last Seen’ audit script for immediate savings), a ‘Permanent Fix’ (centralized procurement, SaaS registry, quarterly reviews for long-term control), and a ‘Nuclear Option’ (30-day SaaS moratorium for drastic reset). The quick fix is fast but temporary, the permanent fix is procedural and sustainable, and the nuclear option is high-friction but effective for severe sprawl.

âť“ What is a common pitfall when de-provisioning SaaS users, and how can it be avoided?

A common pitfall is immediately deleting users, which can orphan their associated data (e.g., in Jira or a CRM). To avoid this, downgrade users to a free tier or deactivate them instead, preserving data while stopping billing.

Leave a Reply

Discover more from TechResolve - SaaS Troubleshooting & Software Alternatives

Subscribe now to keep reading and get access to the full archive.

Continue reading