User Limits & Resource Controls
Backflow provides flexible limit enforcement at two levels:
- Backflow to Tenants: Platform-level limits on tenant usage
- Tenants to End-Users: Tenant-configurable limits for their users
Configuration
Add limits to your tenant config:
json
{
"userLimits": {
"enabled": true,
"defaultGateAction": "upgrade",
"entityLimits": { ... },
"storageLimits": { ... },
"resourceLimits": [...]
}
}Entity Limits
Limit how many entities a user can create per collection:
json
{
"userLimits": {
"enabled": true,
"entityLimits": {
"projects": {
"limit": 10,
"gateAction": "upgrade",
"tiers": { "free": 3, "pro": 10, "enterprise": -1 },
"scope": "user"
},
"files": {
"limit": 100,
"scope": "tenant"
}
}
}
}Options
| Field | Type | Description |
|---|---|---|
limit | number | Default max count |
gateAction | login | upgrade | Action when limit reached |
tiers | Record | Per-tier overrides (-1 = unlimited) |
scope | user | tenant | Count per user or entire tenant |
Storage Limits
Limit file storage per user or tenant:
json
{
"userLimits": {
"storageLimits": {
"enabled": true,
"scope": "user",
"gateAction": "upgrade",
"tiers": {
"free": { "maxStorageMB": 100, "maxFileSizeMB": 10 },
"pro": { "maxStorageMB": 5000, "maxFileSizeMB": 100 }
}
}
}
}Resource Limits
Limit workflows, LLM calls, API requests, embeddings, and jobs:
json
{
"userLimits": {
"resourceLimits": [
{
"resource": "workflow",
"metric": "count",
"period": "day",
"limit": 100,
"tiers": { "free": 10, "pro": 100 }
},
{
"resource": "llm",
"metric": "tokens",
"period": "month",
"limit": 100000,
"scope": "user",
"gateAction": "block"
},
{
"resource": "api",
"metric": "count",
"period": "minute",
"limit": 60,
"conditions": { "roles": ["viewer"] }
}
]
}
}Resource Types
| Resource | Description |
|---|---|
workflow | Workflow executions |
llm | LLM/AI calls |
api | API requests |
embedding | Embedding operations |
job | Queue job submissions |
Metrics
| Metric | Description |
|---|---|
count | Number of operations |
tokens | Token usage (LLM) |
cost | Cost in cents |
Periods
| Period | Description |
|---|---|
minute | Per-minute limit |
hour | Per-hour limit |
day | Per-day limit |
month | Per-month limit |
Gate Actions
| Action | Behavior |
|---|---|
block | Reject request (default) |
warn | Allow but return warning |
upgrade | Suggest tier upgrade |
Conditions
Apply limits selectively:
json
{
"resource": "llm",
"metric": "tokens",
"period": "day",
"limit": 1000,
"conditions": {
"roles": ["viewer"],
"userTier": "free"
}
}SDK Usage
Check Limits Before Action
typescript
// Check if user can execute a workflow
const result = await bf.tenant.limits.resources.check('workflow', 'count', {
userId: 'user-123',
amount: 1,
context: { userTier: 'free' }
});
if (!result.allowed) {
console.log(result.reason); // "workflow count limit exceeded for day (10/10)"
console.log(result.upgrade); // { tier: 'pro', newLimit: 100 }
}Get Usage Stats
typescript
// Get all resource usage
const usage = await bf.tenant.limits.resources.getUsage('user-123');
// Get specific resource usage
const llmUsage = await bf.tenant.limits.resources.getUsage('user-123', 'llm');Get My Usage (User-Scoped)
For end-users viewing their own usage (no admin required):
typescript
// Get all my resource usage and limits
const myUsage = await sdk.mobile.getMyUsage();
// Returns: [{ resource: "llm", metric: "count", period: "hour", current: 5, limit: 10, percentage: 50, scope: "user" }]
// Filter to a specific resource
const llmUsage = await sdk.mobile.getMyUsage('llm');This uses the authenticated user's JWT — no userId parameter needed.
Track Usage Manually
typescript
// Track LLM token usage
await bf.tenant.limits.resources.track('llm', 'tokens', {
userId: 'user-123',
amount: 1500
});Check & Track via Mobile SDK
typescript
// Check before an LLM call
const { allowed, remaining, gate } = await sdk.mobile.checkResourceLimit('llm', 'count');
if (!allowed) {
// gate is "block" | "warn" | "upgrade"
}
// Track after success
await sdk.mobile.trackResourceUsage('llm', 'count');Entity Limits
typescript
// Check entity limit
const canCreate = await bf.tenant.limits.check(
'user-123',
'projects',
'create',
'free' // user tier
);
// Get usage stats
const usage = await bf.tenant.limits.getUsage('user-123');Storage Limits
typescript
// Check if file upload allowed
const result = await bf.tenant.limits.storage.check('user-123', 5000000); // 5MB
// Get storage usage
const stats = await bf.tenant.limits.storage.getUsage('user-123');Generated App Usage (sdk: prefix)
In generated apps, users can view their own limits with sdk:limits.myUsage():
json
{
"type": "list",
"dataSource": "sdk:limits.myUsage()",
"renderItem": {
"title": "{{resource}} ({{metric}}/{{period}})",
"subtitle": "{{current}}/{{limit}} used ({{percentage}}%)"
}
}Filter to a specific resource:
json
{
"dataSource": "sdk:limits.myUsage('llm')"
}API Endpoints
Resource Limits
| Method | Endpoint | Description |
|---|---|---|
| GET | /tenant/limits/resources | Get resource limits config |
| PUT | /tenant/limits/resources | Update resource limits |
| GET | /tenant/limits/resources/usage | Get usage statistics (admin) |
| GET | /tenant/limits/resources/my-usage | Get authenticated user's own usage |
| POST | /tenant/limits/resources/check | Check if action allowed |
| POST | /tenant/limits/resources/track | Track resource usage |
Entity Limits
| Method | Endpoint | Description |
|---|---|---|
| GET | /tenant/limits | Get limits config |
| PUT | /tenant/limits | Update limits config |
| GET | /tenant/limits/usage | Get usage stats |
| POST | /tenant/limits/check | Check if action allowed |
Storage Limits
| Method | Endpoint | Description |
|---|---|---|
| GET | /tenant/limits/storage | Get storage config |
| PUT | /tenant/limits/storage | Update storage config |
| GET | /tenant/limits/storage/usage | Get storage usage |
| POST | /tenant/limits/storage/check | Check upload allowed |
Automatic Enforcement
Resource limits are automatically enforced in:
- Mobile Routes (
/mobile/classify,/mobile/generate,/mobile/regenerate): Checksllmcount limit before each LLM call and tracks usage after success. Returns429with usage info when exceeded. - Workflow Executor: Checks
workflowlimits before execution - Queue Jobs: Checked before job submission
For custom enforcement, use the check/track APIs before operations.
MCP Tools
The following MCP tools are available for resource limits:
| Tool | Description |
|---|---|
check_resource_limit | Check if a resource action is allowed |
track_resource_usage | Record usage after an action |
get_resource_usage | Get tenant-wide usage stats |
get_my_resource_usage | Get authenticated user's own usage |