TallyUp: SaaS License Management and Offboarding Platform

As companies grow, so does their SaaS footprint. What starts as a handful of necessary tools quickly becomes dozens of subscriptions across multiple departments. But here's the problem: when employees leave or switch roles, their access often remains active, wasting thousands of dollars each month on unused licenses.

TallyUp is a Django-based platform built to solve this challenge. Working alongside ex-colleagues, we created a tool that helps organizations track SaaS spending, identify inactive users, and automate the offboarding process across multiple services.

Since its development, TallyUp has evolved into a comprehensive license management platform at usetallyup.com, helping businesses reclaim control of their SaaS expenses.


the problem: invisible waste

Most companies have no centralized view of their SaaS subscriptions. Finance teams see the invoices, IT manages the accounts, and individual teams sign up for tools as needed. The result? A fragmented picture where:

  • Inactive users remain on paid plans after leaving the company
  • License costs add up without anyone noticing
  • Manual offboarding is slow and error-prone across dozens of services
  • There's no visibility into total SaaS spending or potential savings

For a company with 100 employees using 20+ SaaS tools, this can translate to tens of thousands of dollars in wasted spend annually.


what TallyUp does

TallyUp centralizes SaaS license management into a single platform with three main capabilities:

1. comprehensive visibility

The dashboard provides a real-time view of your entire SaaS ecosystem:

  • Total monthly costs across all services
  • License breakdown by service, user, and activity status
  • Inactive user detection based on last login timestamps
  • Potential savings from removing unused licenses
  • Multi-currency support for international teams

Visual analytics show spending trends over time, cost distribution across services, and estimated savings per service. Instead of digging through spreadsheets or multiple admin panels, finance teams get a unified view of their SaaS spending.

2. automated user syncing

Rather than manually tracking who has access to what, TallyUp integrates directly with services to pull real data:

  • Google Workspace integration via OAuth2 automatically imports all users and their service assignments
  • Service-specific plugins fetch user lists and activity data
  • Regular syncing keeps the platform updated as team members are added or removed
  • Activity tracking identifies when users last accessed each service

This automation eliminates the manual work of maintaining spreadsheets and ensures the data is always current.

3. simplified offboarding

When it's time to remove access, TallyUp makes it fast:

  • Bulk deprovisioning removes users from multiple services at once
  • Individual service removal for selective access revocation
  • Status tracking shows which deprovisionings succeeded or failed
  • Activity log provides a complete audit trail
  • Plugin architecture supports automated removal for integrated services

Instead of logging into 15 different admin panels to remove one person, you can initiate the entire process from TallyUp's interface.


technical architecture

Built with Django and PostgreSQL, TallyUp uses a multi-tenant architecture where each organization has complete data isolation. The tech stack includes:

Backend:

  • Django for the web framework and ORM
  • PostgreSQL for reliable data storage
  • Gunicorn for production deployment
  • Django-SES for email notifications via AWS

Integrations:

  • Google Admin API for Workspace data
  • Selenium with undetected ChromeDriver for services without APIs
  • OAuth2 flows for secure authentication
  • Plugin system for extensible service support

Frontend:

  • Django templates for server-side rendering
  • Tailwind CSS for responsive design
  • PyEcharts for interactive data visualizations

Main Features:

  • Role-based access control (Owner, Admin, Read-only)
  • Multi-currency pricing and conversion
  • Batch operations for speed
  • Audit logging for compliance
  • Stripe integration for billing

The plugin architecture is particularly important. Each integrated service implements a standard interface with methods for authentication, fetching users, and deprovisioning. This makes it straightforward to add new service integrations as customer needs evolve.

Distributed Task Queue:

For long-running operations like bulk deprovisioning or syncing hundreds of users from external services, TallyUp uses Celery as its distributed task queue to keep the application responsive:

  • Celery workers process time-consuming tasks asynchronously
  • User requests immediately return with a status tracking ID
  • Background workers execute the actual API calls, browser automation, and data processing
  • Status updates allow users to monitor progress in real-time
  • Error handling at the worker level ensures failed operations are logged and can be retried
  • Redis or RabbitMQ acts as the message broker between Django and Celery workers

This architecture is necessary for operations that might take minutes to complete. When a user initiates bulk deprovisioning for 50 users across 10 services, the web request completes instantly, and Celery workers handle the 500 individual removal operations in the background. Users can navigate away and check back later, with the system tracking which items succeeded, failed, or are still in progress.

The Celery worker pattern also prevents timeout issues and allows for retry logic when external services are temporarily unavailable. It's the difference between a platform that feels sluggish and unreliable versus one that handles enterprise-scale operations gracefully.


the data model

At the center of TallyUp is a clean relational model:

Organizations own everything in a multi-tenant setup. Each organization has:

Users with roles and permissions who can manage the platform.

Services representing SaaS tools (Slack, Miro, Google Workspace, etc.), either global templates or organization-specific.

OrganizationServices connecting a service to an organization with pricing details, credentials, and configuration.

ServiceUsers representing individuals who have access to services.

ServiceUserLicenses tracking the many-to-many relationship between users and services, including:

  • Billing status (Active/Inactive)
  • Last activity timestamp
  • Cost allocation

DeprovisioningRequests and DeprovisioningItems for tracking removal operations with status codes and audit trails.

This structure provides flexibility while maintaining data integrity. Adding a new service doesn't require schema changes, and the system scales naturally as organizations grow.


smart features

Beyond simple tracking, TallyUp includes smart capabilities:

Inactive user detection: The system automatically flags users who haven't logged into a service in the last 90 days, making it easy to identify candidates for removal.

Cost projections: For each inactive user, TallyUp calculates the monthly savings from removing their access, giving finance teams concrete numbers for decision-making.

Bulk operations: Need to remove someone completely? TallyUp can remove them from all services in one action, then track the progress of each individual removal.

Service-specific handling: Different services have different APIs and capabilities. TallyUp's plugin system handles these variations transparently, whether it's a REST API, OAuth flow, or browser automation with Selenium.

Multi-currency support: For international teams, TallyUp tracks costs in multiple currencies and converts them for unified reporting.


integration examples

Google Workspace

The Google Workspace integration uses OAuth2 to securely access the Admin Directory API. With the appropriate scopes, TallyUp can:

  • Fetch the complete user list from your organization
  • Identify which Google services each user has access to
  • Track last login times and activity
  • Import this data into TallyUp automatically

The integration respects Google's security model, requesting only read-only access to user directories and security settings.

Slack

For services like Slack, TallyUp uses a hybrid approach:

  • The Slack API provides user lists and activity data
  • Selenium automation handles deactivation flows that aren't exposed via API
  • The system manages session state and handles 2FA when configured
  • Status tracking ensures operators know if removal succeeded or requires manual intervention

Extensibility

The plugin architecture makes adding new services straightforward. Each plugin implements:

  • get_users() - Fetch current user list
  • deprovision_users() - Remove specified users
  • get_metadata() - Service information and capabilities
  • _authenticate() - Handle login and session management

This abstraction allows TallyUp to support services with very different integration approaches under a unified interface.


real-world impact

For organizations using TallyUp, the benefits are tangible:

Cost savings: Identifying and removing inactive licenses recovers wasted spend. For a mid-sized company, this can mean thousands of dollars monthly.

Time savings: Removing access that previously took hours across multiple systems now happens in minutes with a few clicks.

Compliance: Complete audit trails show when access was removed and by whom, important for security and compliance requirements.

Visibility: Finance and IT teams finally have a shared view of SaaS spending, enabling better planning and budgeting.

Risk reduction: Removing access promptly when employees leave reduces the security risk of orphaned accounts.


lessons learned

Building TallyUp reinforced several important principles:

Multi-tenancy from day one: Building isolation into the data model from the start made it much easier to onboard new organizations securely. Retrofitting this later would have been painful.

API-first when possible, automation when necessary: We preferred official APIs for reliability and maintainability, but didn't let API limitations stop us. Selenium filled the gaps for services without programmatic access.

Status tracking is important: For operations like deprovisioning that can fail in complex ways, detailed status tracking and error messages make the difference between a useful tool and a black box.

Make data actionable: Showing total SaaS spend is interesting, but highlighting inactive users with calculated savings gives users a clear action to take.

Design for extensibility: The plugin system made it straightforward to add new service integrations without refactoring core logic each time.


Building TallyUp was an exercise in solving a real business problem with practical technology. It combined backend development, API integrations, data modeling, and collaborative software engineering into a platform that delivers measurable value.