Usage based limits
Usage-based limits let you control feature access based on a merchant's activity, consumption, or other measurable metrics. This approach enables flexible pricing models where merchants are limited based on their usage patterns or allocated resources.
How usage-based limits work
Usage-based limits in Mantle combine two key components:
- Usage events - Track specific actions or consumption in your app
- Limit features - Define maximum thresholds in Mantle's feature system
When a merchant's usage approaches or exceeds their plan's limits, you can control access to features and prompt upgrades as needed.
Implementation steps
1. Configure usage metrics
Before implementing usage-based limits, set up appropriate usage metrics in Mantle:
- Create metrics that aggregate the events you want to limit
- Configure the appropriate time period (month-to-date or billing period)
- Link these metrics to features in your plans
2. Track usage events
When merchants use limited features, send usage events to Mantle:
// Using MantleClient
await mantleClient.sendUsageEvent({
eventName: 'product_created',
properties: {
productId: '123',
productType: 'physical'
}
});
// Or direct API request
await fetch('https://appapi.heymantle.com/v1/usage_events', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Mantle-App-Id': process.env.MANTLE_APP_ID,
'X-Mantle-Customer-Api-Token': customerApiToken
},
body: JSON.stringify({
eventName: 'product_created',
properties: {
productId: '123',
productType: 'physical'
}
})
});3. Check limits before access
Before allowing a merchant to use a limited feature, check their current usage against their plan limit:
async function canCreateProduct() {
// Get limit from merchant's current plan
const limit = await mantleClient.limitForFeature({
featureKey: 'product_limit'
});
// Get current usage
const { customer } = await mantleClient.getCustomer();
const used = customer.usage['Product limit']?.currentValue || 0;
// Check if merchant is within limit
return used < limit;
}4. Enforce limits in your application
Implement the limit check in the appropriate place in your code flow:
async function createProduct(productData) {
// Check feature limit before proceeding
const limit = await mantleClient.limitForFeature({
featureKey: 'product_limit'
});
const { customer } = await mantleClient.getCustomer();
const used = customer.usage['Product limit']?.currentValue || 0;
if (used >= limit) {
throw new Error('Product limit reached');
}
// Proceed with product creation
const product = await actuallyCreateProduct(productData);
// Track usage after successful creation
await mantleClient.sendUsageEvent({
eventName: 'product_created',
properties: {
productId: product.id,
productType: product.type
}
});
return product;
}5. Display remaining capacity to merchants
Keep merchants informed about their usage and limits:
import { useMantle } from '@heymantle/react';
function ProductLimitIndicator() {
const { customer, limitForFeature } = useMantle();
const productLimit = limitForFeature({
featureKey: 'product_limit'
});
const used = customer.usage['Product limit']?.currentValue || 0;
const remaining = productLimit - used;
const usagePercentage = (used / productLimit) * 100;
return (
<div>
<ProgressBar percentage={usagePercentage} />
<Text>
{used} of {productLimit} products used ({remaining} remaining)
</Text>
{remaining <= 5 && (
<Banner status="warning">
You're approaching your product limit. Consider upgrading your plan.
</Banner>
)}
</div>
);
}Common usage-based limit patterns
Pre-check pattern
Check limits before performing actions:
// Check limit before allowing feature access
if (await canUseFeature('product_limit')) {
// Allow feature access
} else {
// Show upgrade prompt
}Track-then-check pattern
Track usage and then verify against limits for reporting:
// Track usage first
await trackUsage('api_call');
// Then check if user is approaching limit for notifications
if (await isApproachingLimit('api_calls')) {
// Show warning about upcoming limit
}Batch-check pattern
For bulk operations, check if the entire batch can be processed:
const batchSize = products.length;
const remainingCapacity = await getRemainingCapacity('product_limit');
if (batchSize > remainingCapacity) {
// Can't process entire batch, show error or process partial
} else {
// Process entire batch
}Best practices
- Check limits early in your request lifecycle to prevent wasted processing
- Track usage accurately even when limits are exceeded for reporting purposes
- Provide clear feedback when merchants reach their limits
- Offer upgrade paths when limits are approached or reached
- Consider grace periods for small overages to improve user experience
- Cache limit values when appropriate to reduce API calls
Updated over 1 year ago