UNPKG

usagepilot

Version:

Open-core usage tracking for AI applications. Record, aggregate, and bill for token consumption across tenants with 95% storage reduction

195 lines (150 loc) 5.18 kB
# UsagePilot Open-core usage tracking for AI applications. Record, aggregate, and bill for token consumption across tenants with 95% storage reduction. ## The Problem Building AI-powered SaaS applications comes with unique challenges: - **Token costs add up fast** - Each API call to OpenAI, Anthropic, or other providers costs money - **Usage varies wildly** - Some users consume 100x more tokens than others - **Attribution is complex** - You need to track usage per user, team, and organization - **Storage explodes** - Storing every API call creates massive databases - **Billing is manual** - Converting usage data into invoices takes custom code ## Why UsagePilot? UsagePilot is purpose-built for AI token tracking in multi-tenant SaaS applications: ### 💾 95% Storage Reduction - Aggregates usage into 60-minute windows instead of storing every event - Keeps query performance under 100ms even at scale - Automatically finalizes historical data for immutable storage ### 👥 True Multi-tenancy - Flexible dimension-based tracking (user, team, organization, workspace, etc.) - No rigid tenant structure - adapt to your application's needs - Efficient indexing for fast lookups across any dimension ### 💳 Billing-Ready - Integrates with Stripe, Orb, Metronome, and other billing providers - Accurate cost calculation with up-to-date pricing models - Export usage data in billing-friendly formats ### 🚀 Production Performance - Sub-100ms queries for hourly aggregations - Handles 10,000+ events per second - Exponential backoff and retry for reliability ## Installation ```bash npm install usagepilot # or pnpm add usagepilot # or yarn add usagepilot ``` ## Basic Usage ### Initialize UsagePilot ```typescript import { UsagePilot } from "usagepilot"; import { PostgresStorage } from "usagepilot/storage"; // Define your dimension structure type Dimensions = { user_id: string; team_id: string; organization_id: string; }; // Create the storage adapter const storage = new PostgresStorage({ connectionString: process.env.DATABASE_URL, // Optional configuration batchSize: 100, flushInterval: 30000, // 30 seconds maxRetries: 3, retryDelay: 1000, }); // Initialize UsagePilot const usage = new UsagePilot<Dimensions>({ storage, }); ``` ### Track AI Usage with Vercel AI SDK ```typescript import { streamText } from "ai"; import { createOpenAI } from "@ai-sdk/openai"; // Create a fetch wrapper that tracks usage const trackedFetch = usage.createFetch((req) => ({ user_id: req.headers.get("x-user-id"), team_id: req.headers.get("x-team-id"), organization_id: req.headers.get("x-organization-id"), })); // Create OpenAI instance with tracked fetch const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY, fetch: trackedFetch, }); // Use it with Vercel AI SDK async function generateResponse(prompt: string, userId: string) { const result = await streamText({ model: openai("gpt-4"), prompt, headers: { "x-user-id": userId, "x-team-id": "team_456", "x-organization-id": "org_123", }, }); // Usage is automatically tracked and stored! return result; } ``` ### Query Usage Data ```typescript // Get usage for a specific organization this month const startOfMonth = new Date(); startOfMonth.setDate(1); startOfMonth.setHours(0, 0, 0, 0); const result = await usage.query({ dimensions: { organization_id: "org_123", }, timeRange: { start: startOfMonth, end: new Date(), }, }); // Calculate total tokens used const totalTokens = result.aggregates.reduce( (sum, agg) => sum + agg.metrics.totalTokens, 0, ); console.log(`Organization used ${totalTokens} tokens this month`); ``` ### Export for Billing ```typescript // Get daily usage for billing const dailyUsage = await usage.query({ dimensions: { organization_id: "org_123", }, timeRange: { start: billingPeriodStart, end: billingPeriodEnd, }, granularity: "day", // Aggregate by day }); // Calculate total tokens from daily aggregates const totalTokens = dailyUsage.aggregates.reduce( (sum, agg) => sum + agg.metrics.totalTokens, 0, ); // Send to your billing provider await stripe.usageRecords.create({ subscription_item: "si_123", quantity: totalTokens, timestamp: Math.floor(Date.now() / 1000), }); ``` ## Advanced Features - **Multiple Storage Backends**: PostgreSQL, ClickHouse, Redis (coming soon) - **Provider Support**: OpenAI, Anthropic, Google, Mistral, and more - **Real-time Dashboards**: Pre-aggregated materialized views - **Anomaly Detection**: Identify unusual usage patterns - **Cost Optimization**: Track and optimize model usage - **GDPR Compliant**: Built-in data retention policies ## Documentation For comprehensive documentation, visit [https://github.com/usagepilot/usagepilot](https://github.com/usagepilot/usagepilot) ## Contributing We welcome contributions! Please see our [Contributing Guide](https://github.com/usagepilot/usagepilot/blob/main/CONTRIBUTING.md) for details. ## License UsagePilot is licensed under the MIT License. See [LICENSE](https://github.com/usagepilot/usagepilot/blob/main/LICENSE) for details.