Back to skills
SKILL.md
2421 User Budget Tracking B07585c9
ASecurityTrack and enforce budgets per user with automatic time-based resets.
- 9 stars
- 0 votes
- 0 copies
- 0 views
- Added October 11, 2026
Works with
Security analysis
100/100npx -y skills add tools-only/X-Skills --skill 2421-user-budget-tracking_b07585c9 --agent claude-codeAre you the author of 2421 User Budget Tracking B07585c9?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-2421-user-budget-tracking-b07585c9)# Per-User Budget Tracking
Track and enforce budgets per user with automatic time-based resets.
## Overview
cascadeflow's per-user budget tracking helps you control costs in multi-user applications by:
- **Tracking costs per user** - Separate cost tracking for each user ID
- **Enforcing tier-based budgets** - Different limits for free, pro, enterprise users
- **Multiple time periods** - Daily, weekly, monthly, and total lifetime budgets
- **Automatic resets** - Daily budgets reset after 24 hours, weekly after 7 days
- **Warning thresholds** - Get alerts when users reach 80% (configurable) of budget
- **100% backward compatible** - Existing v0.1.1 code continues to work
## Quick Start
```python
from cascadeflow.telemetry import BudgetConfig, CostTracker
# Configure tier-based budgets
tracker = CostTracker(
user_budgets={
"free": BudgetConfig(daily=0.10), # $0.10/day for free users
"pro": BudgetConfig(daily=1.0, weekly=5.0), # $1/day, $5/week
},
warn_threshold=0.8, # Warn at 80% of budget
)
# Track costs with user context
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=1000,
cost=0.003,
user_id="user_123",
user_tier="free",
)
# Check user's budget status
summary = tracker.get_user_summary("user_123", "free")
if summary["budget_exceeded"]:
print("⚠️ User has exceeded their daily budget!")
```
## API Reference
### BudgetConfig
Configure budget limits for a user tier.
```python
from cascadeflow.telemetry import BudgetConfig
# Daily budget only (most common for SaaS)
free_tier = BudgetConfig(daily=0.10)
# Multiple periods for comprehensive control
pro_tier = BudgetConfig(
daily=1.00,
weekly=5.00,
monthly=20.00,
)
# Total lifetime budget (for trials)
trial = BudgetConfig(total=5.00)
# No limits (tracking only)
unlimited = BudgetConfig() # No enforcement, just tracking
```
**Parameters:**
- `daily` (float, optional): Daily budget in USD (resets every 24 hours)
- `weekly` (float, optional): Weekly budget in USD (resets every 7 days)
- `monthly` (float, optional): Monthly budget in USD (resets every 30 days)
- `total` (float, optional): Total lifetime budget in USD (never resets)
### CostTracker with User Budgets
```python
from cascadeflow.telemetry import BudgetConfig, CostTracker
tracker = CostTracker(
budget_limit=100.0, # Optional global budget (v0.1.1 - backward compatible)
user_budgets={ # Per-user budgets
"free": BudgetConfig(daily=0.10),
"pro": BudgetConfig(daily=1.0, weekly=5.0),
"enterprise": BudgetConfig(daily=10.0, monthly=200.0),
},
warn_threshold=0.8, # Warn at 80% of budget
verbose=True, # Enable logging
)
```
### add_cost() with User Tracking
```python
# v0.2.0 style - with user tracking
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=1000,
cost=0.003,
user_id="user_123", # NEW: User identifier
user_tier="free", # NEW: User tier name
query_id="query_456", # Optional
metadata={"app": "web"}, # Optional
)
# v0.1.1 style - still works (no user tracking)
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=1000,
cost=0.003,
)
```
### get_user_summary()
Get detailed cost summary for a specific user.
```python
summary = tracker.get_user_summary("user_123", "free")
# Summary structure:
{
"user_id": "user_123",
"total_cost": 0.045, # Total cost across all time
"total_entries": 3, # Number of queries
"user_tier": "free",
"budget_config": "BudgetConfig(daily=$0.10)",
"period_costs": {
"daily": {
"cost": 0.045,
"limit": 0.10,
"remaining": 0.055,
"used_pct": 45.0,
"exceeded": False,
}
},
"budget_exceeded": False, # True if ANY period exceeded
}
```
### get_all_users()
Get list of all tracked user IDs.
```python
users = tracker.get_all_users()
# Returns: ["user_123", "user_456", "user_789"]
```
### get_users_by_tier()
Get all users in a specific tier.
```python
free_users = tracker.get_users_by_tier("free")
# Returns: ["user_123", "user_456"]
```
## Real-World Scenarios
### Scenario 1: SaaS with Free and Pro Tiers
```python
from cascadeflow.telemetry import BudgetConfig, CostTracker
# Configure budgets
tracker = CostTracker(
user_budgets={
"free": BudgetConfig(daily=0.10),
"pro": BudgetConfig(daily=1.0, weekly=5.0, monthly=20.0),
},
warn_threshold=0.8,
)
# Process user query
def process_query(user_id, user_tier, query):
# ... run query through cascadeflow ...
# Track cost
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=tokens_used,
cost=calculated_cost,
user_id=user_id,
user_tier=user_tier,
)
# Check if budget exceeded
summary = tracker.get_user_summary(user_id, user_tier)
if summary["budget_exceeded"]:
# Deny request or show upgrade prompt
return {"error": "Daily budget exceeded. Please upgrade to Pro!"}
return result
```
### Scenario 2: Trial Users with Lifetime Budget
```python
# Trial users get $5 total budget
tracker = CostTracker(
user_budgets={
"trial": BudgetConfig(total=5.0),
}
)
# Track trial user
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=1000,
cost=0.60,
user_id="trial_user_001",
user_tier="trial",
)
# Check remaining budget
summary = tracker.get_user_summary("trial_user_001", "trial")
remaining = summary["period_costs"]["total"]["remaining"]
print(f"Trial budget remaining: ${remaining:.2f}")
```
### Scenario 3: Enterprise with Monthly Budget
```python
# Enterprise gets high daily limit but capped monthly
tracker = CostTracker(
user_budgets={
"enterprise": BudgetConfig(daily=50.0, monthly=1000.0),
}
)
# Track enterprise user
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=10000,
cost=5.0,
user_id="enterprise_user_001",
user_tier="enterprise",
)
# Monthly budget tracking
summary = tracker.get_user_summary("enterprise_user_001", "enterprise")
monthly = summary["period_costs"]["monthly"]
print(f"Monthly usage: ${monthly['cost']:.2f} / ${monthly['limit']:.2f}")
```
## Time-Based Resets
Budgets automatically reset based on the time period:
| Period | Reset Frequency | Example |
|--------|----------------|---------|
| Daily | Every 24 hours | User spent $0.10 on Monday, budget resets to $0 on Tuesday |
| Weekly | Every 7 days | Week starts on Monday, resets the following Monday |
| Monthly | Every 30 days | 30-day rolling window |
| Total | Never | Lifetime cumulative budget |
**Note:** Resets happen automatically when checking budgets. If a user makes their first query on Tuesday at 3pm, their daily budget runs until Wednesday at 3pm.
## Warning Thresholds
Configure when to warn users about budget usage:
```python
tracker = CostTracker(
user_budgets={"free": BudgetConfig(daily=0.10)},
warn_threshold=0.8, # Warn at 80%
)
# When user reaches 80% of $0.10 ($0.08), you'll see:
# WARNING: User user_123 (free): 80.0% of daily budget used ($0.080 / $0.10)
```
You can listen to these warnings by enabling verbose logging:
```python
import logging
logging.basicConfig(level=logging.WARNING)
tracker = CostTracker(
user_budgets={"free": BudgetConfig(daily=0.10)},
warn_threshold=0.8,
verbose=True, # Enable logging
)
```
## Performance
Per-user budget tracking is designed for production use:
- **<1ms overhead** per `add_cost()` call (measured with 100 calls)
- **O(users)** memory complexity
- **Thread-safe** - uses only atomic operations
- **Minimal CPU** - simple dict lookups and comparisons
Benchmark on MacBook Pro:
```
1000 users × 10 queries each = 10,000 add_cost() calls
Total time: ~8ms
Average per call: 0.8ms
```
## Integration with Auth Systems
### With Stripe
```python
import stripe
from cascadeflow.telemetry import BudgetConfig, CostTracker
# Map Stripe subscription tiers to budgets
TIER_BUDGETS = {
"price_free": BudgetConfig(daily=0.10),
"price_pro": BudgetConfig(daily=1.0, weekly=5.0),
"price_enterprise": BudgetConfig(daily=50.0, monthly=1000.0),
}
tracker = CostTracker(user_budgets=TIER_BUDGETS)
# Get user's Stripe subscription
subscription = stripe.Subscription.retrieve(user_subscription_id)
price_id = subscription["items"]["data"][0]["price"]["id"]
# Track with Stripe price ID as tier
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=1000,
cost=0.003,
user_id=user.id,
user_tier=price_id, # Use Stripe price ID
)
```
### With Auth0
```python
from cascadeflow.telemetry import BudgetConfig, CostTracker
# Map Auth0 roles to budgets
ROLE_BUDGETS = {
"free-user": BudgetConfig(daily=0.10),
"pro-user": BudgetConfig(daily=1.0, weekly=5.0),
"enterprise-user": BudgetConfig(daily=50.0, monthly=1000.0),
}
tracker = CostTracker(user_budgets=ROLE_BUDGETS)
# Get user's Auth0 role
user_roles = auth0_user["app_metadata"]["roles"]
tier = user_roles[0] # Primary role
# Track with Auth0 role
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=1000,
cost=0.003,
user_id=auth0_user["user_id"],
user_tier=tier,
)
```
## Best Practices
### 1. Define Clear Tier Budgets
```python
# Good: Clear tier budgets
TIER_BUDGETS = {
"free": BudgetConfig(daily=0.10), # 10 cents/day
"pro": BudgetConfig(daily=1.0, weekly=5.0), # $1/day, $5/week
"enterprise": BudgetConfig(monthly=1000.0), # $1000/month only
}
# Bad: Overly complex
TIER_BUDGETS = {
"free": BudgetConfig(daily=0.10, weekly=0.50, monthly=2.0, total=10.0),
# Too many periods - hard to explain to users
}
```
### 2. Use Appropriate Periods
```python
# For SaaS: Daily budgets (easy to understand)
BudgetConfig(daily=0.10)
# For trials: Total budgets (fixed lifetime)
BudgetConfig(total=5.0)
# For enterprise: Monthly budgets (matches billing cycle)
BudgetConfig(monthly=1000.0)
```
### 3. Handle Budget Exceeded Gracefully
```python
def handle_query(user_id, user_tier, query):
summary = tracker.get_user_summary(user_id, user_tier)
if summary.get("budget_exceeded"):
# Show friendly message
if user_tier == "free":
return {
"error": "Daily budget exceeded",
"message": "Upgrade to Pro for higher limits!",
"upgrade_url": "/upgrade",
}
else:
return {
"error": "Budget limit reached",
"message": "Contact sales to increase your limit.",
"support_email": "sales@example.com",
}
# Process query normally
return process_query(query)
```
### 4. Monitor Budget Usage
```python
# Periodic monitoring (e.g., daily cron job)
def monitor_budget_usage():
all_users = tracker.get_all_users()
for user_id in all_users:
summary = tracker.get_user_summary(user_id)
# Send warning email if close to limit
if summary.get("period_costs", {}).get("daily", {}).get("used_pct", 0) > 90:
send_email(
user_id,
subject="Budget Warning",
body=f"You've used {summary['period_costs']['daily']['used_pct']:.0f}% of your daily budget"
)
```
### 5. Track Without Enforcement (Optional)
```python
# Track costs but don't enforce limits (analytics only)
tracker = CostTracker() # No user_budgets
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=1000,
cost=0.003,
user_id="user_123",
# No user_tier - just tracking
)
# Still get cost breakdown
summary = tracker.get_user_summary("user_123")
print(f"User has spent: ${summary['total_cost']:.2f}")
```
## Backward Compatibility
All v0.1.1 code continues to work without modification:
```python
# v0.1.1 style - still works
tracker = CostTracker(budget_limit=10.0)
tracker.add_cost(model="gpt-4", provider="openai", tokens=100, cost=0.003)
summary = tracker.get_summary()
# v0.2.0 adds optional user tracking
tracker.add_cost(
model="gpt-4",
provider="openai",
tokens=100,
cost=0.003,
user_id="user_123", # Optional - if omitted, no user tracking
user_tier="free", # Optional
)
```
## Next Steps
- [Production Deployment Guide](production.md) - Deploy with user tracking
- [Cost Tracking Guide](cost_tracking.md) - Reduce costs with cascading
- [API Reference](../api/telemetry.md) - Full telemetry API docs
- [Budget Enforcement Examples](../../examples/enforcement/) - Complete working examples
## Troubleshooting
### Budget not resetting
**Problem:** Daily budget shows same cost after 24 hours
**Solution:** Budgets reset automatically when `add_cost()` is called. If a user doesn't make any queries, the reset won't happen until their next query.
```python
# Budget resets happen in add_cost() when checking if period expired
tracker.add_cost(...) # This triggers reset check
```
### User not found
**Problem:** `get_user_summary()` returns `total_cost: 0.0` for existing user
**Solution:** Make sure you're using the exact same `user_id` string:
```python
# Good
tracker.add_cost(..., user_id="user_123", user_tier="free")
summary = tracker.get_user_summary("user_123", "free") # Same ID
# Bad
tracker.add_cost(..., user_id="user_123", user_tier="free")
summary = tracker.get_user_summary("user-123", "free") # Different ID (dash vs underscore)
```
### Budget exceeded not triggering
**Problem:** Budget shows exceeded but no warning/error logged
**Solution:** Enable verbose logging:
```python
import logging
logging.basicConfig(level=logging.WARNING)
tracker = CostTracker(
user_budgets={"free": BudgetConfig(daily=0.10)},
verbose=True, # Must be True to see logs
)
```
Or check the `budget_exceeded` flag programmatically:
```python
summary = tracker.get_user_summary(user_id, user_tier)
if summary.get("budget_exceeded"):
# Handle exceeded budget
pass
```
Attribution
Comments
Loading comments…