Overview
Codex-LB tracks real-time usage metrics for each account in your pool, including:- Rate limit consumption - Percentage of 5-minute sliding window used
- Quota consumption - Percentage of weekly/monthly allocation used
- Token counts - Input and output tokens per request
- Credit balances - Available ChatGPT credits for Plus/Pro accounts
- 28-day trends - Historical usage patterns for capacity planning
How Usage Tracking Works
Automatic Refresh
Codex-LB automatically refreshes usage data from ChatGPT’s backend API:Usage refresh happens automatically during account selection. No separate background job is required.
Usage Windows
ChatGPT enforces two types of usage windows: Primary Window (Rate Limiting):- Duration: 5 minutes (sliding window)
- Limit: Varies by plan (e.g., 80 requests per 5 minutes for Plus)
- Reset behavior: Continuous sliding - older requests expire rolling off
- Duration: 7 days (weekly) or 30 days (monthly)
- Limit: Varies by plan (e.g., 10M tokens/week for Plus)
- Reset behavior: Hard reset at fixed interval
Data Model
Usage data is stored in theusage_history table:
Usage in Load Balancing
The load balancer uses usage data to make routing decisions:used_percent:
- Secondary usage % (quota window) - lowest first
- Primary usage % (rate limit window) - lowest first
- Last selection time - oldest first
- Account ID - for stable ordering
Quota Application
The system applies quota logic to determine account availability:- Monthly/weekly quota exhaustion →
QUOTA_EXCEEDED - 5-minute rate limit exhaustion →
RATE_LIMITED - Otherwise →
ACTIVE
Credit Tracking
For Plus and Pro accounts with credit-based billing:Usage API
Get Current Usage
Get Usage Trends
bucket_seconds: Aggregation interval (default: 21600 = 6 hours)since: Start time for historical data (default: 28 days ago)window: Filter by “primary” or “secondary” (default: both)account_id: Filter to specific account (default: all)
Trend Calculation
Fromapp/modules/usage/repository.py:115-167:
- Average usage % across all samples in that time window
- Sample count for data quality assessment
- Per-account, per-window granularity
Dashboard Visualization
The web dashboard displays usage data in multiple views:Overview Cards
- Active Accounts: Count of accounts in
ACTIVEstatus - Average Usage: Mean
used_percentacross all active accounts - Accounts Near Limit: Count where
used_percent > 80%
Account Table
Columns:- Status (with color coding)
- Plan Type
- Usage % (primary window)
- Quota % (secondary window)
- Reset time (relative, e.g., “in 4 hours”)
Usage Trends Chart
- X-axis: Time (6-hour buckets over 28 days)
- Y-axis: Average usage percentage
- Lines: One per account, colored by status
- Shading: Highlighted regions where usage exceeded 80%
Configuration
Environment Variables
Disabling Usage Tracking
To disable usage tracking entirely:- Usage-weighted routing falls back to round-robin behavior
- Dashboard shows stale usage data
- No new
usage_historyrows created - Reduces API calls to ChatGPT backend
Performance Considerations
Database Growth
With default settings:- Refresh interval: 300 seconds (5 minutes)
- Rows per account per day: 288 (24 hours × 12 refreshes/hour)
- Retention period: 28 days
- Total rows for 10 accounts: ~80,000 rows
- Each row: ~200 bytes
- 80,000 rows: ~16 MB
API Call Overhead
- Calls per refresh: 1 per account
- Calls per day: (86400 / interval) × account_count
- Example (10 accounts, 5-min interval): 10 × 288 = 2,880 calls/day
Query Performance
Indexes optimize common queries:- Latest usage by account: Less than 10ms
- 28-day trend aggregation: Less than 100ms
- Full usage export: Less than 500ms
Troubleshooting
Stale Usage Data
Symptom: Usage percentages not updating Causes:USAGE_REFRESH_ENABLED=false- All accounts deactivated (no refresh triggers)
- ChatGPT API returning errors (check logs)
Missing Usage History
Symptom: Trends chart empty or incomplete Causes:- Recently added accounts (no historical data yet)
- Database cleared or reset
- Retention policy deleted old data
Usage Not Reflecting Reality
Symptom: Dashboard shows low usage but requests failing Causes:- Cached data (5-minute refresh lag)
- Primary vs secondary window confusion
- Multiple Codex-LB instances not sharing state
- Wait for next refresh cycle
- Check which window (primary/secondary) is exhausted
- Ensure single Codex-LB instance or shared database
Related Features
- Load Balancing - How usage affects routing
- Account Pooling - Account state management
- API Keys - Per-key usage limits
Technical Reference
Key source files:app/modules/usage/updater.py- Usage refresh logicapp/modules/usage/repository.py- Usage data queriesapp/core/usage/quota.py- Quota application rulesapp/core/usage/types.py- Type definitionsapp/db/models.py:62-77- UsageHistory model