Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions apps/docs/content/docs/en/execution/costs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,38 @@ Different subscription plans have different usage limits:
| **Team** | $500 (pooled) | 50 sync, 100 async |
| **Enterprise** | Custom | Custom |

## Billing Model

Sim uses a **base subscription + overage** billing model:

### How It Works

**Pro Plan ($20/month):**
- Monthly subscription includes $20 of usage
- Usage under $20 → No additional charges
- Usage over $20 → Pay the overage at month end
- Example: $35 usage = $20 (subscription) + $15 (overage)

**Team Plan ($40/seat/month):**
- Pooled usage across all team members
- Overage calculated from total team usage
- Organization owner receives one bill

**Enterprise Plans:**
- Fixed monthly price, no overages
- Custom usage limits per agreement

### Threshold Billing

When unbilled overage reaches $50, Sim automatically bills the full unbilled amount.

**Example:**
- Day 10: $70 overage → Bill $70 immediately
- Day 15: Additional $35 usage ($105 total) → Already billed, no action
- Day 20: Another $50 usage ($155 total, $85 unbilled) → Bill $85 immediately

This spreads large overage charges throughout the month instead of one large bill at period end.

## Cost Management Best Practices

1. **Monitor Regularly**: Check your usage dashboard frequently to avoid surprises
Expand Down
4 changes: 4 additions & 0 deletions apps/sim/app/api/billing/update-cost/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { userStats } from '@sim/db/schema'
import { eq, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkAndBillOverageThreshold } from '@/lib/billing/threshold-billing'
import { checkInternalApiKey } from '@/lib/copilot/utils'
import { isBillingEnabled } from '@/lib/environment'
import { createLogger } from '@/lib/logs/console/logger'
Expand Down Expand Up @@ -148,6 +149,9 @@ export async function POST(req: NextRequest) {
addedTokens: totalTokens,
})

// Check if user has hit overage threshold and bill incrementally
await checkAndBillOverageThreshold(userId)

const duration = Date.now() - startTime

logger.info(`[${requestId}] Cost update completed successfully`, {
Expand Down
4 changes: 4 additions & 0 deletions apps/sim/app/api/wand-generate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { userStats, workflow } from '@sim/db/schema'
import { eq, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import OpenAI, { AzureOpenAI } from 'openai'
import { checkAndBillOverageThreshold } from '@/lib/billing/threshold-billing'
import { env } from '@/lib/env'
import { getCostMultiplier, isBillingEnabled } from '@/lib/environment'
import { createLogger } from '@/lib/logs/console/logger'
Expand Down Expand Up @@ -133,6 +134,9 @@ async function updateUserStatsForWand(
tokensUsed: totalTokens,
costAdded: costToStore,
})

// Check if user has hit overage threshold and bill incrementally
await checkAndBillOverageThreshold(userId)
} catch (error) {
logger.error(`[${requestId}] Failed to update user stats for wand usage`, error)
}
Expand Down
6 changes: 6 additions & 0 deletions apps/sim/lib/billing/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ export const DEFAULT_ENTERPRISE_TIER_COST_LIMIT = 200
* This charge is applied regardless of whether the workflow uses AI models
*/
export const BASE_EXECUTION_CHARGE = 0.001

/**
* Default threshold (in dollars) for incremental overage billing
* When unbilled overage reaches this amount, an invoice item is created
*/
export const DEFAULT_OVERAGE_THRESHOLD = 50
Loading