PHP Java MySQL

Tenant-Centric Quota Management with Manual Overrides

Managing resource quotas across multiple tenants can be challenging, especially when the need for manual overrides arises. This post explores how we refactored our token usage service to implement a tenant-centric quota system with support for manual adjustments.

The Challenge

Previously, our token quota management was user-based. This created inefficiencies when the context already provided the tenant information. We needed a more direct way to manage quotas at the tenant level, allowing for specific overrides when necessary.

The Solution: Tenant-Centric Design

We shifted the focus from individual users to tenants. This involved the following key changes:

  1. Plan Resolution: Moved plan resolution logic to a Tenant::resolvePlan() method. This centralizes the process of determining a tenant's plan based on various factors.
  2. Effective Daily Token Limit: Introduced a Tenant::getEffectiveDailyTokenLimit() method. This method calculates the daily token limit for a tenant, taking into account the plan and any manual overrides.
  3. Manual Override: Added a daily_token_limit column to the tenant configuration. This allows administrators to set a specific token limit for a tenant, overriding the default limit from the plan.
  4. Quota Method Updates: Modified all quota-related methods (canGenerate, getEffectiveLimit, getRemainingTokens, isNearLimit) to accept a Tenant object instead of a User object. This simplifies the calling code by removing the need to resolve users when the tenant is already available.

Implementing Manual Overrides

The core of the solution lies in the Tenant::getEffectiveDailyTokenLimit() method. Here's a simplified example of how it might work:

class Tenant
{
    public function resolvePlan(): Plan
    {
        // Logic to determine the tenant's plan based on subscription, usage, etc.
        return new BasicPlan();
    }

    public function getEffectiveDailyTokenLimit(): int
    {
        if ($this->daily_token_limit !== null) {
            return $this->daily_token_limit; // Manual override
        }

        return $this->resolvePlan()->getDailyTokenLimit(); // Default from plan
    }
}

class Plan {
    public function getDailyTokenLimit(): int {
        return 1000; // Basic Plan limit
    }
}

class BasicPlan extends Plan {
}

This code snippet demonstrates how the method checks for a manual override ($this->daily_token_limit) and, if present, returns that value. Otherwise, it retrieves the default token limit from the tenant's plan.

Benefits

  • Simplified Code: Eliminates the need to resolve users when the tenant context is already known.
  • Centralized Logic: Consolidates plan resolution and token limit calculation in the Tenant model.
  • Flexibility: Provides a mechanism for manual overrides, allowing administrators to adjust quotas as needed.

Conclusion

By refactoring our token usage service to be tenant-centric and incorporating manual overrides, we've created a more efficient and flexible system for managing resource quotas. Key takeaways include:

  • Prioritize tenant-level operations when the tenant context is readily available.
  • Centralize plan resolution and limit calculation for better maintainability.
  • Implement manual overrides to handle exceptions and specific tenant needs.
Gerardo Ruiz

Gerardo Ruiz

Author

Share: