mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-31 09:48:06 -05:00
Compare commits
1 Commits
feat/gm
...
improvemen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afead54c2e |
@@ -27,16 +27,16 @@ All API responses include information about your workflow execution limits and u
|
||||
"limits": {
|
||||
"workflowExecutionRateLimit": {
|
||||
"sync": {
|
||||
"requestsPerMinute": 60, // Sustained rate limit per minute
|
||||
"maxBurst": 120, // Maximum burst capacity
|
||||
"remaining": 118, // Current tokens available (up to maxBurst)
|
||||
"resetAt": "..." // When tokens next refill
|
||||
"requestsPerMinute": 150, // Sustained rate limit per minute
|
||||
"maxBurst": 300, // Maximum burst capacity
|
||||
"remaining": 298, // Current tokens available (up to maxBurst)
|
||||
"resetAt": "..." // When tokens next refill
|
||||
},
|
||||
"async": {
|
||||
"requestsPerMinute": 200, // Sustained rate limit per minute
|
||||
"maxBurst": 400, // Maximum burst capacity
|
||||
"remaining": 398, // Current tokens available
|
||||
"resetAt": "..." // When tokens next refill
|
||||
"requestsPerMinute": 1000, // Sustained rate limit per minute
|
||||
"maxBurst": 2000, // Maximum burst capacity
|
||||
"remaining": 1998, // Current tokens available
|
||||
"resetAt": "..." // When tokens next refill
|
||||
}
|
||||
},
|
||||
"usage": {
|
||||
@@ -107,28 +107,28 @@ Query workflow execution logs with extensive filtering options.
|
||||
}
|
||||
],
|
||||
"nextCursor": "eyJzIjoiMjAyNS0wMS0wMVQxMjozNDo1Ni43ODlaIiwiaWQiOiJsb2dfYWJjMTIzIn0",
|
||||
"limits": {
|
||||
"workflowExecutionRateLimit": {
|
||||
"sync": {
|
||||
"requestsPerMinute": 60,
|
||||
"maxBurst": 120,
|
||||
"remaining": 118,
|
||||
"resetAt": "2025-01-01T12:35:56.789Z"
|
||||
"limits": {
|
||||
"workflowExecutionRateLimit": {
|
||||
"sync": {
|
||||
"requestsPerMinute": 150,
|
||||
"maxBurst": 300,
|
||||
"remaining": 298,
|
||||
"resetAt": "2025-01-01T12:35:56.789Z"
|
||||
},
|
||||
"async": {
|
||||
"requestsPerMinute": 1000,
|
||||
"maxBurst": 2000,
|
||||
"remaining": 1998,
|
||||
"resetAt": "2025-01-01T12:35:56.789Z"
|
||||
}
|
||||
},
|
||||
"async": {
|
||||
"requestsPerMinute": 200,
|
||||
"maxBurst": 400,
|
||||
"remaining": 398,
|
||||
"resetAt": "2025-01-01T12:35:56.789Z"
|
||||
"usage": {
|
||||
"currentPeriodCost": 1.234,
|
||||
"limit": 10,
|
||||
"plan": "pro",
|
||||
"isExceeded": false
|
||||
}
|
||||
},
|
||||
"usage": {
|
||||
"currentPeriodCost": 1.234,
|
||||
"limit": 10,
|
||||
"plan": "pro",
|
||||
"isExceeded": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</Tab>
|
||||
@@ -188,15 +188,15 @@ Retrieve detailed information about a specific log entry.
|
||||
"limits": {
|
||||
"workflowExecutionRateLimit": {
|
||||
"sync": {
|
||||
"requestsPerMinute": 60,
|
||||
"maxBurst": 120,
|
||||
"remaining": 118,
|
||||
"requestsPerMinute": 150,
|
||||
"maxBurst": 300,
|
||||
"remaining": 298,
|
||||
"resetAt": "2025-01-01T12:35:56.789Z"
|
||||
},
|
||||
"async": {
|
||||
"requestsPerMinute": 200,
|
||||
"maxBurst": 400,
|
||||
"remaining": 398,
|
||||
"requestsPerMinute": 1000,
|
||||
"maxBurst": 2000,
|
||||
"remaining": 1998,
|
||||
"resetAt": "2025-01-01T12:35:56.789Z"
|
||||
}
|
||||
},
|
||||
@@ -477,10 +477,10 @@ The API uses a **token bucket algorithm** for rate limiting, providing fair usag
|
||||
|
||||
| Plan | Requests/Minute | Burst Capacity |
|
||||
|------|-----------------|----------------|
|
||||
| Free | 10 | 20 |
|
||||
| Pro | 30 | 60 |
|
||||
| Team | 60 | 120 |
|
||||
| Enterprise | 120 | 240 |
|
||||
| Free | 30 | 60 |
|
||||
| Pro | 100 | 200 |
|
||||
| Team | 200 | 400 |
|
||||
| Enterprise | 500 | 1000 |
|
||||
|
||||
**How it works:**
|
||||
- Tokens refill at `requestsPerMinute` rate
|
||||
|
||||
@@ -170,16 +170,16 @@ curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" htt
|
||||
"rateLimit": {
|
||||
"sync": {
|
||||
"isLimited": false,
|
||||
"requestsPerMinute": 25,
|
||||
"maxBurst": 50,
|
||||
"remaining": 50,
|
||||
"requestsPerMinute": 150,
|
||||
"maxBurst": 300,
|
||||
"remaining": 300,
|
||||
"resetAt": "2025-09-08T22:51:55.999Z"
|
||||
},
|
||||
"async": {
|
||||
"isLimited": false,
|
||||
"requestsPerMinute": 200,
|
||||
"maxBurst": 400,
|
||||
"remaining": 400,
|
||||
"requestsPerMinute": 1000,
|
||||
"maxBurst": 2000,
|
||||
"remaining": 2000,
|
||||
"resetAt": "2025-09-08T22:51:56.155Z"
|
||||
},
|
||||
"authType": "api"
|
||||
@@ -206,11 +206,11 @@ curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" htt
|
||||
|
||||
Different subscription plans have different usage limits:
|
||||
|
||||
| Plan | Monthly Usage Limit | Rate Limits (per minute) |
|
||||
|------|-------------------|-------------------------|
|
||||
| **Free** | $20 | 5 sync, 10 async |
|
||||
| **Pro** | $100 | 10 sync, 50 async |
|
||||
| **Team** | $500 (pooled) | 50 sync, 100 async |
|
||||
| Plan | Monthly Usage Included | Rate Limits (per minute) |
|
||||
|------|------------------------|-------------------------|
|
||||
| **Free** | $20 | 50 sync, 200 async |
|
||||
| **Pro** | $20 (adjustable) | 150 sync, 1,000 async |
|
||||
| **Team** | $40/seat (pooled, adjustable) | 300 sync, 2,500 async |
|
||||
| **Enterprise** | Custom | Custom |
|
||||
|
||||
## Billing Model
|
||||
|
||||
@@ -13,8 +13,8 @@ import { SlackMonoIcon } from '@/components/icons'
|
||||
import type { PlanFeature } from '@/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/subscription/components/plan-card'
|
||||
|
||||
export const PRO_PLAN_FEATURES: PlanFeature[] = [
|
||||
{ icon: Zap, text: '25 runs per minute (sync)' },
|
||||
{ icon: Clock, text: '200 runs per minute (async)' },
|
||||
{ icon: Zap, text: '150 runs per minute (sync)' },
|
||||
{ icon: Clock, text: '1,000 runs per minute (async)' },
|
||||
{ icon: HardDrive, text: '50GB file storage' },
|
||||
{ icon: Building2, text: 'Unlimited workspaces' },
|
||||
{ icon: Users, text: 'Unlimited invites' },
|
||||
@@ -22,8 +22,8 @@ export const PRO_PLAN_FEATURES: PlanFeature[] = [
|
||||
]
|
||||
|
||||
export const TEAM_PLAN_FEATURES: PlanFeature[] = [
|
||||
{ icon: Zap, text: '75 runs per minute (sync)' },
|
||||
{ icon: Clock, text: '500 runs per minute (async)' },
|
||||
{ icon: Zap, text: '300 runs per minute (sync)' },
|
||||
{ icon: Clock, text: '2,500 runs per minute (async)' },
|
||||
{ icon: HardDrive, text: '500GB file storage (pooled)' },
|
||||
{ icon: Building2, text: 'Unlimited workspaces' },
|
||||
{ icon: Users, text: 'Unlimited invites' },
|
||||
|
||||
@@ -13,8 +13,8 @@ interface FreeTierUpgradeEmailProps {
|
||||
|
||||
const proFeatures = [
|
||||
{ label: '$20/month', desc: 'in credits included' },
|
||||
{ label: '25 runs/min', desc: 'sync executions' },
|
||||
{ label: '200 runs/min', desc: 'async executions' },
|
||||
{ label: '150 runs/min', desc: 'sync executions' },
|
||||
{ label: '1,000 runs/min', desc: 'async executions' },
|
||||
{ label: '50GB storage', desc: 'for files & assets' },
|
||||
{ label: 'Unlimited', desc: 'workspaces & invites' },
|
||||
]
|
||||
|
||||
@@ -161,14 +161,14 @@ export const env = createEnv({
|
||||
// Rate Limiting Configuration
|
||||
RATE_LIMIT_WINDOW_MS: z.string().optional().default('60000'), // Rate limit window duration in milliseconds (default: 1 minute)
|
||||
MANUAL_EXECUTION_LIMIT: z.string().optional().default('999999'),// Manual execution bypass value (effectively unlimited)
|
||||
RATE_LIMIT_FREE_SYNC: z.string().optional().default('10'), // Free tier sync API executions per minute
|
||||
RATE_LIMIT_FREE_ASYNC: z.string().optional().default('50'), // Free tier async API executions per minute
|
||||
RATE_LIMIT_PRO_SYNC: z.string().optional().default('25'), // Pro tier sync API executions per minute
|
||||
RATE_LIMIT_PRO_ASYNC: z.string().optional().default('200'), // Pro tier async API executions per minute
|
||||
RATE_LIMIT_TEAM_SYNC: z.string().optional().default('75'), // Team tier sync API executions per minute
|
||||
RATE_LIMIT_TEAM_ASYNC: z.string().optional().default('500'), // Team tier async API executions per minute
|
||||
RATE_LIMIT_ENTERPRISE_SYNC: z.string().optional().default('150'), // Enterprise tier sync API executions per minute
|
||||
RATE_LIMIT_ENTERPRISE_ASYNC: z.string().optional().default('1000'), // Enterprise tier async API executions per minute
|
||||
RATE_LIMIT_FREE_SYNC: z.string().optional().default('50'), // Free tier sync API executions per minute
|
||||
RATE_LIMIT_FREE_ASYNC: z.string().optional().default('200'), // Free tier async API executions per minute
|
||||
RATE_LIMIT_PRO_SYNC: z.string().optional().default('150'), // Pro tier sync API executions per minute
|
||||
RATE_LIMIT_PRO_ASYNC: z.string().optional().default('1000'), // Pro tier async API executions per minute
|
||||
RATE_LIMIT_TEAM_SYNC: z.string().optional().default('300'), // Team tier sync API executions per minute
|
||||
RATE_LIMIT_TEAM_ASYNC: z.string().optional().default('2500'), // Team tier async API executions per minute
|
||||
RATE_LIMIT_ENTERPRISE_SYNC: z.string().optional().default('600'), // Enterprise tier sync API executions per minute
|
||||
RATE_LIMIT_ENTERPRISE_ASYNC: z.string().optional().default('5000'), // Enterprise tier async API executions per minute
|
||||
|
||||
// Knowledge Base Processing Configuration - Shared across all processing methods
|
||||
KB_CONFIG_MAX_DURATION: z.number().optional().default(600), // Max processing duration in seconds (10 minutes)
|
||||
|
||||
@@ -28,24 +28,24 @@ function createBucketConfig(ratePerMinute: number, burstMultiplier = 2): TokenBu
|
||||
|
||||
export const RATE_LIMITS: Record<SubscriptionPlan, RateLimitConfig> = {
|
||||
free: {
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_FREE_SYNC) || 10),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_FREE_ASYNC) || 50),
|
||||
apiEndpoint: createBucketConfig(10),
|
||||
},
|
||||
pro: {
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_PRO_SYNC) || 25),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_PRO_ASYNC) || 200),
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_FREE_SYNC) || 50),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_FREE_ASYNC) || 200),
|
||||
apiEndpoint: createBucketConfig(30),
|
||||
},
|
||||
pro: {
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_PRO_SYNC) || 150),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_PRO_ASYNC) || 1000),
|
||||
apiEndpoint: createBucketConfig(100),
|
||||
},
|
||||
team: {
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_TEAM_SYNC) || 75),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_TEAM_ASYNC) || 500),
|
||||
apiEndpoint: createBucketConfig(60),
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_TEAM_SYNC) || 300),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_TEAM_ASYNC) || 2500),
|
||||
apiEndpoint: createBucketConfig(200),
|
||||
},
|
||||
enterprise: {
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_ENTERPRISE_SYNC) || 150),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_ENTERPRISE_ASYNC) || 1000),
|
||||
apiEndpoint: createBucketConfig(120),
|
||||
sync: createBucketConfig(Number.parseInt(env.RATE_LIMIT_ENTERPRISE_SYNC) || 600),
|
||||
async: createBucketConfig(Number.parseInt(env.RATE_LIMIT_ENTERPRISE_ASYNC) || 5000),
|
||||
apiEndpoint: createBucketConfig(500),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -125,8 +125,8 @@ app:
|
||||
|
||||
# Rate Limiting Configuration (per minute)
|
||||
RATE_LIMIT_WINDOW_MS: "60000" # Rate limit window duration (1 minute)
|
||||
RATE_LIMIT_FREE_SYNC: "10" # Sync API executions per minute
|
||||
RATE_LIMIT_FREE_ASYNC: "50" # Async API executions per minute
|
||||
RATE_LIMIT_FREE_SYNC: "50" # Sync API executions per minute
|
||||
RATE_LIMIT_FREE_ASYNC: "200" # Async API executions per minute
|
||||
|
||||
# UI Branding & Whitelabeling Configuration
|
||||
NEXT_PUBLIC_BRAND_NAME: "Sim" # Custom brand name
|
||||
|
||||
Reference in New Issue
Block a user