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 listdeprovision_users()- Remove specified usersget_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.