Concurrency Monitoring
Concurrency controls how many calls your agents can handle simultaneously. Understanding and monitoring concurrency is essential for maintaining service quality, avoiding queue bottlenecks, and planning capacity as your usage grows. This guide covers concurrency limits, real-time monitoring, and strategies for scaling your AI agent deployments.
What is Concurrency?
Concurrency refers to the number of calls an agent can handle at the same time. Each active call consumes one concurrency slot until the call completes.
How Concurrency Works
Single Agent Concurrency:
- Agent A has 10 concurrent call slots
- 8 calls currently in progress
- 2 slots available for new calls
- 9th and 10th calls start immediately
- 11th call queues until a slot frees up
Multi-Agent Concurrency:
- Organization has 3 agents (10 slots each)
- Total organization capacity: 30 concurrent calls
- Each agent manages its own concurrency independently
- Calls don’t share slots across agents
Independent Agent Limits: Each agent has its own concurrency limit. An agent with 3 active calls out of 10 slots doesn’t affect another agent’s available capacity.
Why Concurrency Matters
Service Quality:
- Prevents agent overload and performance degradation
- Maintains consistent response times
- Ensures stable voice quality
- Protects LLM and TTS provider APIs from rate limits
Cost Control:
- Limits maximum simultaneous API usage
- Prevents unexpected LLM/TTS cost spikes
- Controls telephony carrier concurrency charges
- Enforces organizational budget constraints
Capacity Planning:
- Measure peak usage to plan scaling
- Identify when to add more agents
- Track growth trends over time
- Optimize resource allocation
Concurrency Limits by Tier
Dasha BlackBox sets concurrency limits based on your subscription tier.
Tier Comparison
Free Tier
Pro Tier
Enterprise Tier
Free Plan Limits
- Concurrent calls per agent: 2
- Maximum agents: 3
- Total organization capacity: 6 concurrent calls
- Queue behavior: Unlimited queue size
Best For: Testing, proof-of-concept, small-scale deployments Pro Plan Limits
- Concurrent calls per agent: 10
- Maximum agents: 25
- Total organization capacity: 250 concurrent calls
- Queue behavior: Priority-based scheduling
Best For: Production deployments, mid-sized businesses, call centers Enterprise Plan Limits
- Concurrent calls per agent: Custom (typically 50-100+)
- Maximum agents: Unlimited
- Total organization capacity: Custom (hundreds to thousands)
- Queue behavior: Advanced scheduling with custom rules
Best For: Large-scale deployments, multi-tenant platforms, high-volume campaignsContact sales for custom concurrency limits.
Current Limits
Check your current concurrency limits:
Dashboard:
- Navigate to Account Settings
- Click Billing & Usage
- View Concurrency Limits section
API:
const response = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const limits = await response.json();
console.log('Max concurrent calls:', limits.concurrency);
console.log('Currently active:', limits.active);
console.log('Available slots:', limits.concurrency - limits.active);
Response:
{
"concurrency": 10,
"active": 7
}
The concurrency API returns organization-wide limits. Tier information and per-agent breakdowns are available in your account settings on the dashboard, not via this API endpoint.
Viewing Real-Time Concurrency
Monitor active calls and concurrency usage across your organization.
Dashboard Monitoring
Organization Overview:
- Go to Dashboard home page
- View Active Calls widget
- Shows current concurrent calls vs limit
- Color-coded indicators:
- 🟢 Green: Under 70% capacity
- 🟡 Yellow: 70-90% capacity
- 🔴 Red: Over 90% capacity (nearing limit)
Agent-Level Detail:
- Navigate to Agents page
- Each agent card shows:
- Active calls count
- Maximum concurrent calls
- Current utilization percentage
- Click agent for detailed call list
Real-Time Call Table:
- Go to Calls page
- Select In Progress tab
- View all active calls with:
- Start time and duration
- Agent handling the call
- Call endpoint
- Priority level
API Monitoring
Get Organization-Wide Concurrency:
const response = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const data = await response.json();
console.log(`Active: ${data.active}/${data.concurrency}`);
console.log(`Utilization: ${(data.active / data.concurrency * 100).toFixed(1)}%`);
console.log(`Available: ${data.concurrency - data.active} slots`);
Get Per-Agent Concurrency:
const agentId = "550e8400-e29b-41d4-a716-446655440000";
const response = await fetch(`https://blackbox.dasha.ai/api/v1/agents/${agentId}`, {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const agent = await response.json();
// Get active calls for this agent
const callsResponse = await fetch(`https://blackbox.dasha.ai/api/v1/calls/list?agentId=${agentId}&status=InProgress`, {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const { calls } = await callsResponse.json();
console.log(`Agent "${agent.name}": ${calls.length} active calls`);
Monitor All Active Calls:
const response = await fetch('https://blackbox.dasha.ai/api/v1/calls/list?status=InProgress&skip=0&take=100', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const { calls, total } = await response.json();
// Group by agent
const byAgent = calls.reduce((acc, call) => {
acc[call.agentId] = (acc[call.agentId] || 0) + 1;
return acc;
}, {});
console.log('Active calls by agent:', byAgent);
console.log('Total active:', total);
Concurrency Metrics Explained
Key Metrics
Current Active Calls
- Number of calls in progress right now
- Updates in real-time as calls start/end
- Includes both inbound and outbound calls
- Critical for understanding live system load
Peak Concurrency
- Highest concurrent calls in a time period
- Typically measured per hour, day, or week
- Indicates maximum capacity needed
- Used for capacity planning
Average Concurrency
- Mean concurrent calls over time period
- Smooths out spikes and valleys
- Represents baseline capacity requirement
- Helpful for rightsizing agent limits
Concurrency Utilization
- Percentage of limit currently in use
- Formula: (Active Calls / Limit) × 100
- Target: Under 80% for buffer room
- Over 90%: Approaching capacity, consider scaling
Queue Depth
- Number of calls waiting for concurrency slot
- Indicates capacity constraints
- High queue depth = need more concurrency
- Measured alongside active calls
Active Calls Gauge:
- Circular gauge showing current vs limit
- Color changes as utilization increases
- Click to view list of active calls
- Updates every 5 seconds
Concurrency Timeline:
- Line chart of concurrent calls over time
- Shows peak and average usage
- Hover for exact values at any time
- Select time range: hour, day, week, month
Per-Agent Utilization:
- Bar chart comparing agents
- Shows which agents are busiest
- Identifies under-utilized capacity
- Helps balance load across agents
Approaching Concurrency Limits
Warning Indicators
Dashboard Alerts:
- Yellow warning at 80% utilization
- Red alert at 90% utilization
- Orange banner when at 100% (limit reached)
- Notification icon in top-right corner
Email Notifications:
- Sent when reaching 90% for first time today
- Sent again when reaching 100%
- Includes current usage statistics
- Provides recommendations for scaling
Custom Monitoring via Polling:
Since capacity alerts are not available as webhook events, implement your own monitoring:
// Poll concurrency and send custom alerts
async function monitorCapacity() {
const response = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const data = await response.json();
const utilization = (data.active / data.concurrency) * 100;
if (utilization >= 90) {
// Send alert to your monitoring system
await sendAlert({
type: 'capacity_warning',
utilization,
active: data.active,
concurrency: data.concurrency
});
}
}
// Run every minute
setInterval(monitorCapacity, 60000);
What Happens at Limit
When Concurrency Limit Reached:
- New calls cannot start immediately
- Calls enter queue (status: “Queued”)
- Queue processed based on priority
- Calls start as slots free up
- Deadline enforcement prevents indefinite queueing
Queue Processing Behavior:
- Priority-based: Higher priority calls processed first
- Deadline-aware: Calls near deadline get boosted priority
- DWRR algorithm: Dynamic Weighted Round Robin scheduling
- Fair distribution: Prevents starvation of low-priority calls
Impact on Service:
- Increased wait times for callers
- Reduced answer rates (if wait too long)
- Potential deadline expirations for time-sensitive calls
- Higher abandon rate for inbound calls
Quality Degradation: Running at 100% concurrency for extended periods can degrade service quality. Maintain buffer capacity (15-20%) for unexpected spikes.
Queue Behavior When at Limit
Call Queue Mechanics
Queue Entry:
// Call scheduled when at concurrency limit
const response = await fetch('https://blackbox.dasha.ai/api/v1/calls', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agentId: "550e8400-e29b-41d4-a716-446655440000",
endpoint: "+1-555-123-4567",
priority: 5,
deadline: "2025-10-20T18:00:00Z"
})
});
const call = await response.json();
console.log('Status:', call.status); // "Queued"
console.log('Next scheduled:', call.nextScheduleTime);
Queue Monitoring:
// View current queue depth
const response = await fetch('https://blackbox.dasha.ai/api/v1/calls/queue/list?agentId=550e8400-e29b-41d4-a716-446655440000', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const { calls, total } = await response.json();
console.log(`Queue depth: ${total} calls waiting`);
console.log('Next call priority:', calls[0]?.priority);
console.log('Next call deadline:', calls[0]?.deadline);
Priority-Based Queue Processing
Priority Levels in Queue:
| Priority | Processing Order | Typical Wait Time | Use Case |
|---|
| 10 | First (emergency) | Under 30 seconds | Critical alerts |
| 8-9 | High priority | Under 2 minutes | VIP, appointments |
| 5-7 | Normal priority | Under 5 minutes | Standard calls |
| 0-4 | Low priority | Under 15 minutes | Bulk campaigns |
Example Queue State:
{
queuedCalls: [
{ callId: "...", priority: 10, deadline: "2025-10-20T15:00:00Z" },
{ callId: "...", priority: 9, deadline: "2025-10-20T15:30:00Z" },
{ callId: "...", priority: 8, deadline: "2025-10-20T16:00:00Z" },
{ callId: "...", priority: 5, deadline: "2025-10-20T17:00:00Z" },
{ callId: "...", priority: 5, deadline: "2025-10-20T18:00:00Z" },
{ callId: "...", priority: 3, deadline: "2025-10-20T20:00:00Z" }
]
}
Processing Logic:
- Priority 10 call starts first (when slot available)
- Priority 9 call starts next
- Priority 8 call follows
- Two priority 5 calls: earliest deadline first
- Priority 3 call waits until all higher priority completed
Deadline Enforcement
Automatic Cancellation:
- Calls past deadline automatically removed from queue
- Status changes to “Cancelled”
- Webhook triggered (if configured)
- No charge for cancelled calls
Deadline Proximity Boost:
- Calls within 1 hour of deadline: +3 priority boost
- Calls within 15 minutes: +5 priority boost
- Prevents deadline expiration when possible
Example:
// Call with deadline approaching gets priority boost
{
callId: "...",
priority: 5, // Original priority
effectivePriority: 8, // Boosted (5 + 3) due to 30 min until deadline
deadline: "2025-10-20T15:30:00Z",
currentTime: "2025-10-20T15:00:00Z"
}
Scaling Strategies
Increasing Concurrency Limits
Upgrade Subscription Tier:
- Navigate to Account Settings → Billing
- Click Upgrade Plan
- Select Pro or Enterprise tier
- Confirm upgrade
- New limits active immediately
Request Custom Limits (Enterprise):
- Contact sales: sales+blackbox@dasha.ai
- Provide usage requirements:
- Expected peak concurrent calls
- Average call volume per day
- Growth projections for next 6 months
- Custom pricing and limits provided
- Activated within 24-48 hours
Multi-Agent Load Balancing
Create Multiple Agents:
// Instead of one agent with 10 slots, use 3 agents with 10 slots each = 30 total
const agents = [
{ id: "agent-1", concurrency: 10, active: 7 },
{ id: "agent-2", concurrency: 10, active: 8 },
{ id: "agent-3", concurrency: 10, active: 3 }
];
// Distribute calls to agent with most available capacity
function selectAgent(agents) {
return agents.reduce((best, agent) => {
const available = agent.concurrency - agent.active;
const bestAvailable = best.concurrency - best.active;
return available > bestAvailable ? agent : best;
});
}
const targetAgent = selectAgent(agents);
const response = await fetch('https://blackbox.dasha.ai/api/v1/calls', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agentId: targetAgent.id,
endpoint: "+1-555-123-4567",
priority: 5
})
});
Round-Robin Distribution:
// Simple round-robin across agents
let currentIndex = 0;
const agentIds = [
"550e8400-e29b-41d4-a716-446655440000",
"550e8400-e29b-41d4-a716-446655440001",
"550e8400-e29b-41d4-a716-446655440002"
];
function scheduleCallRoundRobin(endpoint, priority) {
const agentId = agentIds[currentIndex];
currentIndex = (currentIndex + 1) % agentIds.length;
return fetch('https://blackbox.dasha.ai/api/v1/calls', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agentId,
endpoint,
priority
})
});
}
Capacity-Based Routing
Smart Agent Selection:
async function scheduleWithCapacityCheck(endpoint, priority, agentIds) {
// Check overall concurrency first
const concurrency = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
if (concurrency.active >= concurrency.concurrency) {
console.log('At capacity - call will be queued');
}
// Get active calls per agent to find best one
const agentCounts = {};
for (const agentId of agentIds) {
const calls = await fetch(`https://blackbox.dasha.ai/api/v1/calls/list?agentId=${agentId}`, {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
// Count running calls
const activeCalls = calls.calls?.filter(c => c.status === 'Running').length || 0;
agentCounts[agentId] = activeCalls;
}
// Find agent with fewest active calls
const bestAgent = Object.entries(agentCounts)
.sort((a, b) => a[1] - b[1])[0][0];
// Schedule call to best agent
return fetch('https://blackbox.dasha.ai/api/v1/calls', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agentId: bestAgent,
endpoint,
priority
})
});
}
Monitoring via API
Concurrency Endpoint
GET /api/v1/misc/concurrency
Returns real-time concurrency limits and active call counts.
Request:
curl -X GET "https://blackbox.dasha.ai/api/v1/misc/concurrency" \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"concurrency": 10,
"active": 7
}
The API returns only organization-wide concurrency (limit) and active (current count). Per-agent breakdown is not available via this endpoint. To track per-agent utilization, query the calls list endpoint filtered by agent.
Continuous Monitoring Script
Poll Concurrency Every Minute:
async function monitorConcurrency() {
setInterval(async () => {
try {
const response = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const data = await response.json();
const utilization = (data.active / data.concurrency * 100).toFixed(1);
console.log(`[${new Date().toISOString()}] Concurrency: ${data.active}/${data.concurrency} (${utilization}%)`);
// Alert if approaching limit
if (utilization >= 90) {
await sendAlert('critical', `Concurrency at ${utilization}% - immediate action needed`);
} else if (utilization >= 80) {
await sendAlert('warning', `Concurrency at ${utilization}% - monitor closely`);
}
} catch (error) {
console.error('Failed to fetch concurrency:', error);
}
}, 60 * 1000); // Check every minute
}
monitorConcurrency();
Prometheus Exporter:
const express = require('express');
const app = express();
app.get('/metrics', async (req, res) => {
const concurrency = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
const metrics = `
# HELP blackbox_concurrency_limit Maximum concurrent calls allowed
# TYPE blackbox_concurrency_limit gauge
blackbox_concurrency_limit ${concurrency.concurrency}
# HELP blackbox_active_calls Current active calls
# TYPE blackbox_active_calls gauge
blackbox_active_calls ${concurrency.active}
# HELP blackbox_concurrency_utilization Concurrency utilization (0-1)
# TYPE blackbox_concurrency_utilization gauge
blackbox_concurrency_utilization ${concurrency.active / concurrency.concurrency}
`.trim();
res.set('Content-Type', 'text/plain');
res.send(metrics);
});
app.listen(9090, () => console.log('Metrics available at http://localhost:9090/metrics'));
Setting Up Concurrency Alerts
Dashboard Alerts
Configure Alert Thresholds:
- Navigate to Account Settings → Notifications
- Enable Concurrency Alerts
- Set thresholds:
- Warning: 80% (default)
- Critical: 90% (default)
- Select notification channels:
- Email
- Webhook
- Slack (if integrated)
- Save settings
Alert Examples:
- “Warning: Agent ‘Customer Support’ at 85% concurrency (17/20 calls)”
- “Critical: Organization concurrency at 92% (46/50 calls)”
- “Queue Alert: 12 calls waiting, average wait time 3 minutes”
Custom Polling Alerts
Since capacity webhooks are not available, implement polling-based alerts:
Polling Monitor with Slack Integration:
async function capacityMonitor() {
const response = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const data = await response.json();
const utilization = (data.active / data.concurrency) * 100;
// Get queue depth
const queueResponse = await fetch('https://blackbox.dasha.ai/api/v1/calls/queue/list', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const queueData = await queueResponse.json();
const queuedCalls = queueData.calls?.length || 0;
if (utilization >= 80) {
// Send Slack notification
await sendSlackMessage({
channel: '#ops-alerts',
text: `:warning: Concurrency Alert`,
attachments: [{
color: utilization >= 90 ? 'danger' : 'warning',
fields: [
{ title: 'Utilization', value: `${utilization.toFixed(1)}%`, short: true },
{ title: 'Active Calls', value: `${data.active}/${data.concurrency}`, short: true },
{ title: 'Queued Calls', value: String(queuedCalls), short: true }
]
}]
});
}
}
// Run every minute
setInterval(capacityMonitor, 60000);
Email Alerts
Configure Email Recipients:
- Go to Account Settings → Team
- Add team members with email addresses
- Assign alert permissions:
- Admin: All alerts
- Operator: Capacity and error alerts
- Viewer: No alerts
- Each recipient receives alerts based on role
Email Alert Content:
Subject: [Dasha BlackBox Alert] High Concurrency Usage - Immediate Action Needed
Your Dasha BlackBox organization is experiencing high concurrency usage:
Current Status:
- Active Calls: 18/20 (90%)
- Queued Calls: 7
- Average Wait Time: 4 minutes
Affected Agents:
- Customer Support Agent: 10/10 (100%)
- Sales Agent: 8/10 (80%)
Recommendations:
1. Upgrade to higher tier for increased limits
2. Create additional agents to distribute load
3. Review call queue and cancel non-urgent calls
View Dashboard: https://blackbox.dasha.ai/dashboard
Optimization Strategies
Reducing Concurrent Calls
Optimize Call Duration:
// Configure agent for shorter, focused conversations
{
config: {
llmConfig: {
maxTokens: 150, // Shorter responses
temperature: 0.6 // More focused
},
conversationConfig: {
maxDuration: 300, // 5 minute max
endCallAfterGoalAchieved: true, // End immediately when done
silenceTimeout: 10 // Detect dead air quickly
}
}
}
Stagger Call Scheduling:
// Instead of scheduling 100 calls at once, stagger over time
const totalCalls = 100;
const callsPerBatch = 10;
const delayBetweenBatches = 5 * 60 * 1000; // 5 minutes
for (let i = 0; i < totalCalls; i += callsPerBatch) {
const batch = calls.slice(i, i + callsPerBatch);
await scheduleBulkCalls(batch);
if (i + callsPerBatch < totalCalls) {
await sleep(delayBetweenBatches);
}
}
Priority Optimization:
// Use lower priority for non-urgent bulk calls
const urgentCalls = customers
.filter(c => c.urgency === 'high')
.map(c => ({ endpoint: c.phone, priority: 8 }));
const normalCalls = customers
.filter(c => c.urgency === 'normal')
.map(c => ({ endpoint: c.phone, priority: 5 }));
const bulkCalls = customers
.filter(c => c.urgency === 'low')
.map(c => ({ endpoint: c.phone, priority: 2 }));
// Schedule in separate batches with appropriate priorities
await scheduleBulkCalls(urgentCalls);
await scheduleBulkCalls(normalCalls);
await scheduleBulkCalls(bulkCalls);
Call Duration Management
Set Maximum Duration:
{
config: {
conversationConfig: {
maxDuration: 180, // 3 minutes max
warningBeforeEnd: 30, // Warn user 30 seconds before
endCallMessage: "We're running out of time. Let me help you quickly."
}
}
}
Early Termination Conditions:
{
config: {
conversationConfig: {
endCallAfterGoalAchieved: true,
endCallPhrases: [
"goodbye",
"that's all",
"nothing else",
"all set"
],
silenceTimeout: 15, // End after 15 seconds silence
maxTurns: 20 // End after 20 conversation turns
}
}
}
Best Practices
Capacity Planning
Monitor Peak Usage:
- Track concurrency at peak hours daily
- Identify weekly/monthly patterns
- Note seasonal variations
- Plan capacity for 2x peak usage
Growth Planning:
// Calculate required concurrency for growth
const currentPeakConcurrency = 18;
const currentCallsPerDay = 500;
const projectedCallsPerDay = 1000; // 100% growth
const growthMultiplier = projectedCallsPerDay / currentCallsPerDay;
const requiredConcurrency = Math.ceil(currentPeakConcurrency * growthMultiplier);
console.log(`Current peak: ${currentPeakConcurrency}`);
console.log(`Required for growth: ${requiredConcurrency}`);
console.log(`Additional capacity needed: ${requiredConcurrency - currentPeakConcurrency}`);
Buffer Zones:
- Maintain 20% buffer above typical peak
- Don’t run at 100% utilization regularly
- Reserve capacity for unexpected spikes
- Test at 80% before assuming 100% is safe
Load Distribution
Geographic Distribution:
// Distribute calls by timezone
const eastCoastAgent = "agent-east";
const westCoastAgent = "agent-west";
function selectAgentByTimezone(phoneNumber) {
const timezone = getTimezoneFromNumber(phoneNumber);
return timezone.includes('America/New_York') ? eastCoastAgent : westCoastAgent;
}
Use-Case Segmentation:
// Different agents for different use cases
const agents = {
support: "agent-support", // 10 concurrent
sales: "agent-sales", // 15 concurrent
surveys: "agent-survey" // 5 concurrent
};
function scheduleCall(endpoint, useCase) {
return fetch('https://blackbox.dasha.ai/api/v1/calls', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agentId: agents[useCase],
endpoint,
priority: useCase === 'support' ? 8 : 5
})
});
}
Monitoring Best Practices
Regular Reviews:
- Daily: Check peak concurrency and queue depth
- Weekly: Analyze trends and utilization patterns
- Monthly: Review capacity and plan scaling
- Quarterly: Evaluate tier and pricing optimization
Alert Fatigue Prevention:
- Set thresholds at actionable levels (80%, 90%)
- Use escalating severity (warning → critical)
- Group alerts (max 1 per hour for same issue)
- Auto-resolve when utilization drops
Documentation:
- Document normal utilization ranges
- Track capacity changes over time
- Record scaling decisions and outcomes
- Maintain runbook for capacity incidents
Troubleshooting
Calls Stuck in Queue
Symptoms:
- Calls remain “Queued” for extended periods
- Queue depth increasing
- Estimated start times getting later
Possible Causes:
- At concurrency limit with long-running calls
- Agent outside business hours (schedule configured)
- Agent disabled or experiencing errors
- All agents at capacity simultaneously
Diagnosis:
// Check concurrency status
const concurrency = await fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
console.log('At limit?', concurrency.active >= concurrency.concurrency);
// Check queue depth
const queue = await fetch('https://blackbox.dasha.ai/api/v1/calls/queue/list', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
console.log('Queue depth:', queue.total);
// Check active calls
const activeCalls = await fetch('https://blackbox.dasha.ai/api/v1/calls/list?status=InProgress', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
console.log('Active calls:', activeCalls.total);
console.log('Average duration:', calculateAverageDuration(activeCalls.calls));
Solutions:
- Increase concurrency limit (upgrade tier)
- Create additional agents for load distribution
- Reduce call duration with configuration changes
- Cancel low-priority queued calls
- Check agent business hours schedule
Unexpected Concurrency Spikes
Symptoms:
- Sudden increase in active calls
- Hitting limit unexpectedly
- Queue building rapidly
Possible Causes:
- Bulk call campaign scheduled
- Multiple systems scheduling simultaneously
- Webhook retry storm
- Test traffic from development environment
- External integration triggering calls
Diagnosis:
// Check recent call scheduling patterns
const recentCalls = await fetch('https://blackbox.dasha.ai/api/v1/calls/list?fromDate=' + new Date(Date.now() - 3600000).toISOString(), {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
// Group by creation minute
const callsByMinute = groupByMinute(recentCalls.calls);
console.log('Calls per minute:', callsByMinute);
// Check additionalData for campaign IDs
const campaigns = recentCalls.calls
.map(c => c.additionalData?.campaignId)
.filter(Boolean);
console.log('Active campaigns:', new Set(campaigns));
Solutions:
- Review and pause bulk campaigns
- Implement rate limiting in integration code
- Stagger call scheduling across time
- Separate production and test environments
- Add concurrency checks before scheduling
Concurrency Limit Reached Frequently
Symptoms:
- Regularly hitting 100% utilization
- Frequent queue buildup
- Increasing average wait times
Root Cause Analysis:
// Analyze historical concurrency data
const stats = await fetch('https://blackbox.dasha.ai/api/v1/calls/statistics/statuses?fromDate=2025-10-13T00:00:00Z&toDate=2025-10-20T23:59:59Z', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(r => r.json());
// Calculate peak hours
const callsByHour = groupCallsByHour(stats);
const peakHours = Object.entries(callsByHour)
.sort((a, b) => b[1] - a[1])
.slice(0, 5);
console.log('Top 5 peak hours:', peakHours);
console.log('Average calls per hour:', calculateAverage(Object.values(callsByHour)));
Long-Term Solutions:
- Upgrade tier for higher limits
- Add agents to distribute load
- Optimize call duration to free slots faster
- Stagger scheduling to smooth peaks
- Implement queueing logic in application
Next Steps
API Cross-Refs