Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.blackbox.dasha.ai/llms.txt

Use this file to discover all available pages before exploring further.

Know how many calls you can handle simultaneously. Monitor utilization in real time, set up alerts for capacity limits, and scale before calls start queueing. What you’ll learn: Concurrency metrics, utilization thresholds, queue status, alerting setup, and scaling strategies.
Screenshots may differ from current UI version.

Understanding concurrency

Concurrency is the number of simultaneous active calls across your organization or agent. Each active call consumes one slot from your concurrency limit until it completes.

Key metrics

MetricDefinitionCalculation
Active callsCalls currently in progress (Running status)Count of calls where status = Running
Concurrency limitMaximum simultaneous calls allowedSet by subscription tier
UtilizationPercentage of limit currently in use(Active Calls / Limit) × 100
Queue depthCalls waiting for available slotsCount of calls where status = Queued
Available capacitySlots available for new callsLimit - Active Calls
Definition: Percentage of concurrency capacity currently in use.Calculation method:
Utilization % = (Active Calls / Concurrency Limit) × 100
Performance thresholds:
UtilizationStatusInterpretationRecommended action
0-70%HealthyNormal operations, ample headroomMonitor normally
70-85%ElevatedApproaching capacityMonitor closely, plan scaling
85-95%WarningLimited headroom for spikesConsider scaling soon
95-100%CriticalNear or at capacityCalls may queue, scale immediately
100%At limitAll slots in useNew calls queue until slots free
Running at 100% utilization for extended periods degrades service quality. Calls queue longer, deadlines may expire, and inbound callers may abandon. Maintain at least 15-20% buffer capacity above typical peak usage.

View concurrency status

  1. Navigate to Dashboard home page
  2. View Active Calls section showing current utilization
  3. Color indicators:
    • 🟢 Green: Under 70% utilization
    • 🟡 Yellow: 70-90% utilization
    • 🔴 Red: Over 90% utilization
Monitor calls waiting in queue:
// Get queued calls count
const queueResponse = await fetch(
  'https://blackbox.dasha.ai/api/v1/calls?status=Queued&take=1',
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
).then(r => r.json());

console.log(`Calls waiting in queue: ${queueResponse.totalCount}`);
async function getConcurrencyStatus() {
  const [concurrencyData, queued, pending] = await Promise.all([
    fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }).then(r => r.json()),

    fetch('https://blackbox.dasha.ai/api/v1/calls?status=Queued&take=1', {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }).then(r => r.json()),

    fetch('https://blackbox.dasha.ai/api/v1/calls?status=Pending&take=1', {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }).then(r => r.json())
  ]);

  const { active, concurrency } = concurrencyData;

  return {
    activeCalls: active,
    queuedCalls: queued.totalCount,
    pendingCalls: pending.totalCount,
    concurrencyLimit: concurrency,
    utilization: ((active / concurrency) * 100).toFixed(1) + '%',
    availableSlots: Math.max(0, concurrency - active)
  };
}

const status = await getConcurrencyStatus();
console.log('Concurrency Status:', status);

Concurrency metrics

Definition: Number of calls currently in Running status (actively connected and processing).Calculation method:
Active Calls = Count of calls where status = 'Running'
Typical range: 0 to concurrency limit. What high values indicate:
  • Peak usage periods
  • Bulk campaign in progress
  • Long average call durations
Definition: Number of calls waiting for an available slot to start processing.Calculation method:
Queue Depth = Count of calls where status IN ('Created', 'Queued', 'Pending')
Performance thresholds:
DepthStatusInterpretation
0OptimalNo waiting calls
1-10AcceptableBrief waits expected
10-50ElevatedMonitor for growth
50-100HighExtended wait times likely
> 100CriticalSignificant delays, scale needed
Definition: Time calls spend in queue before processing begins.Estimated calculation:
Estimated Wait Time = (Queue Depth / Active Calls) × Average Call Duration
What long wait times indicate:
  • Insufficient concurrency for volume
  • Long call durations consuming slots
  • Bulk campaigns overwhelming capacity

Concurrency limits by plan

Limits vary by subscription plan:
PlanConcurrent LinesMinutes/Month
Developer11,000
GrowthMultipleUnlimited
Check your specific limits in Account SettingsBilling & Usage. Contact sales for Growth plan pricing.

What happens at capacity

When all concurrency slots are in use:
  1. New calls enter queue — Status changes to “Queued”
  2. Queue processed by priority — Higher priority calls processed first
  3. Calls start as slots free — First queued call gets next available slot
  4. Deadlines enforced — Calls exceeding deadline are auto-canceled

Impact on service quality

MetricAt capacity impactMitigation
Wait timeIncreases with queue depthScale concurrency
Deadline expirationsQueued calls may timeoutSet longer deadlines
Inbound abandonmentCallers may hang up waitingReserve capacity for inbound
Campaign velocityOutbound campaigns slow downStagger campaign scheduling

Priority during capacity constraints

Calls are processed by priority value (lower values processed first), then by deadline:
PriorityBehavior at capacity
0-1 (Highest)Processed first when slots free
2-4 (Normal)Processed after higher priority calls
5+ (Lower)May wait longer during high utilization
Within the same priority level, calls closer to their deadline are processed first.

Monitor utilization

async function monitorConcurrency(intervalMs = 60000) {
  async function check() {
    const { active, concurrency } = await fetch(
      'https://blackbox.dasha.ai/api/v1/misc/concurrency',
      { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
    ).then(r => r.json());

    const utilization = (active / concurrency * 100);
    const timestamp = new Date().toISOString();

    console.log(`[${timestamp}] ${active}/${concurrency} (${utilization.toFixed(1)}%)`);

    // Alert on high utilization
    if (utilization >= 95) {
      console.error('CRITICAL: At capacity limit');
    } else if (utilization >= 85) {
      console.warn('WARNING: High utilization - consider scaling');
    } else if (utilization >= 70) {
      console.warn('NOTICE: Elevated utilization');
    }

    return { timestamp, active, concurrency, utilization };
  }

  // Initial check
  await check();

  // Continuous monitoring
  setInterval(check, intervalMs);
}

// Monitor every minute
monitorConcurrency(60000);
Track utilization for specific agents:
async function getAgentUtilization(agentId) {
  const response = await fetch(
    `https://blackbox.dasha.ai/api/v1/calls?agentId=${agentId}&status=Running&take=1`,
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  ).then(r => r.json());

  return {
    agentId,
    activeCalls: response.totalCount
  };
}

// Check multiple agents
const agentIds = ['agent-1', 'agent-2', 'agent-3'];

const agentStats = await Promise.all(
  agentIds.map(id => getAgentUtilization(id))
);

console.table(agentStats);
Analyze patterns over time:
async function analyzeUtilizationHistory() {
  // Get recent call results to analyze duration patterns
  const results = await fetch(
    'https://blackbox.dasha.ai/api/v1/call-results?take=500',
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  ).then(r => r.json());

  // Group by hour
  const byHour = {};
  results.items.forEach(call => {
    const hour = new Date(call.createdTime).getHours();
    if (!byHour[hour]) byHour[hour] = { count: 0, totalDuration: 0 };
    byHour[hour].count++;
    byHour[hour].totalDuration += call.durationSeconds;
  });

  // Calculate peak hours
  const sortedHours = Object.entries(byHour)
    .map(([hour, data]) => ({
      hour: parseInt(hour),
      callCount: data.count,
      avgDuration: (data.totalDuration / data.count / 60).toFixed(1) + ' min'
    }))
    .sort((a, b) => b.callCount - a.callCount);

  console.log('Peak hours by call volume:');
  console.table(sortedHours.slice(0, 5));

  return sortedHours;
}

Set up alerts

async function capacityAlert(thresholds = { warning: 85, critical: 95 }) {
  const { active, concurrency } = await fetch(
    'https://blackbox.dasha.ai/api/v1/misc/concurrency',
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  ).then(r => r.json());

  const utilization = (active / concurrency) * 100;

  if (utilization >= thresholds.critical) {
    await sendAlert({
      severity: 'critical',
      message: `Concurrency at ${utilization.toFixed(1)}%`,
      active,
      limit: concurrency,
      action: 'Calls are queueing. Consider immediate scaling.'
    });
  } else if (utilization >= thresholds.warning) {
    await sendAlert({
      severity: 'warning',
      message: `Concurrency at ${utilization.toFixed(1)}%`,
      active,
      limit: concurrency,
      action: 'Monitor closely. Plan scaling if trend continues.'
    });
  }
}

// Check every minute
setInterval(() => capacityAlert(), 60000);
Export metrics for Prometheus monitoring:
const express = require('express');
const app = express();

app.get('/metrics', async (req, res) => {
  const [concurrencyData, queued] = await Promise.all([
    fetch('https://blackbox.dasha.ai/api/v1/misc/concurrency', {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }).then(r => r.json()),

    fetch('https://blackbox.dasha.ai/api/v1/calls?status=Queued&take=1', {
      headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
    }).then(r => r.json())
  ]);

  const { active, concurrency } = concurrencyData;

  const metrics = `
# HELP blackbox_concurrency_limit Maximum concurrent calls allowed
# TYPE blackbox_concurrency_limit gauge
blackbox_concurrency_limit ${concurrency}

# HELP blackbox_active_calls Current number of active calls
# TYPE blackbox_active_calls gauge
blackbox_active_calls ${active}

# HELP blackbox_queued_calls Current number of queued calls
# TYPE blackbox_queued_calls gauge
blackbox_queued_calls ${queued.totalCount}

# HELP blackbox_utilization_percent Current utilization percentage
# TYPE blackbox_utilization_percent gauge
blackbox_utilization_percent ${(active / concurrency * 100).toFixed(2)}
  `.trim();

  res.set('Content-Type', 'text/plain').send(metrics);
});

app.listen(9090, () => {
  console.log('Prometheus metrics available at http://localhost:9090/metrics');
});

Alert thresholds reference

ConditionThresholdSeverityResponse
Utilization spike> 95%CriticalImmediate investigation
Sustained high> 85% for 15 minWarningPlan scaling
Queue buildup> 50 callsWarningReview call durations
Unexpected drop< 10% of normalInfoVerify system health

Scaling strategies

Increase concurrency limits

Upgrade subscription tier:
  1. Navigate to Account SettingsBilling
  2. Click Upgrade Plan
  3. Select tier with higher concurrency
  4. New limits active immediately
Enterprise custom limits: Contact support for limits above standard tiers.
Distribute load across multiple agents:
async function selectLeastLoadedAgent(agentIds) {
  const loads = await Promise.all(
    agentIds.map(async (agentId) => {
      const response = await fetch(
        `https://blackbox.dasha.ai/api/v1/calls?agentId=${agentId}&status=Running&take=1`,
        { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
      ).then(r => r.json());

      return {
        agentId,
        activeCalls: response.totalCount
      };
    })
  );

  // Sort by active calls (ascending)
  loads.sort((a, b) => a.activeCalls - b.activeCalls);

  console.log('Agent loads:', loads);
  return loads[0].agentId; // Return least loaded agent
}

// Use when enqueuing calls
const agents = ['agent-support', 'agent-sales', 'agent-general'];
const targetAgent = await selectLeastLoadedAgent(agents);

await fetch(`https://blackbox.dasha.ai/api/v1/calls/enqueue/${targetAgent}`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    endpoint: '+1-555-123-4567'
  })
});
Shorter calls free slots faster:
// Agent configuration for efficient calls
{
  "config": {
    "llmConfig": {
      "temperature": 0.6       // Focused outputs
    },
    "features": {
      "maxCallDuration": 300,  // 5 minute maximum
      "silenceTimeout": 15     // End on extended silence
    }
  }
}
Avoid overwhelming capacity with large campaigns:
async function staggeredEnqueue(agentId, calls, options = {}) {
  const { batchSize = 50, delayMs = 5 * 60 * 1000 } = options;

  for (let i = 0; i < calls.length; i += batchSize) {
    const batch = calls.slice(i, i + batchSize);

    // Enqueue batch
    await fetch(`https://blackbox.dasha.ai/api/v1/calls/enqueue/${agentId}/batch`, {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(batch)
    });

    console.log(`Enqueued batch ${Math.floor(i / batchSize) + 1}: ${batch.length} calls`);

    // Wait before next batch (unless last batch)
    if (i + batchSize < calls.length) {
      console.log(`Waiting ${delayMs / 1000}s before next batch...`);
      await new Promise(resolve => setTimeout(resolve, delayMs));
    }
  }
}

// Example: Stagger 500 calls in batches of 50, 5 minutes apart
const callList = Array.from({ length: 500 }, (_, i) => ({
  endpoint: `+1-555-${String(i).padStart(7, '0')}`
}));

await staggeredEnqueue('agent-campaign', callList, {
  batchSize: 50,
  delayMs: 5 * 60 * 1000
});

Best practices

Capacity planning

PracticeRecommendation
Buffer capacityMaintain 20% headroom above typical peak
Monitor trendsTrack daily and weekly utilization patterns
Plan aheadScale before campaigns, not during
Test limitsVerify behavior at capacity before production

Load management

PracticeRecommendation
Priority tiersReserve high priority for time-sensitive calls
Stagger campaignsBatch large campaigns with delays
Balance agentsDistribute load across multiple agents
Monitor durationInvestigate unusually long calls

Alert configuration

AlertThresholdCheck interval
Critical capacity> 95% utilizationEvery 1 minute
High utilization> 85% for 15 minutesEvery 5 minutes
Queue buildup> 50 queued callsEvery 2 minutes
Duration anomalyCalls > 2× average durationEvery 10 minutes

Troubleshooting

Symptoms: Calls remain in Queued status for extended periods.Causes:
  • All concurrency slots in use
  • Agent disabled or outside business hours
  • Long-running calls consuming all slots
Solutions:
  1. Check current utilization — verify you’re at capacity
  2. Review active call durations — identify unusually long calls
  3. Verify agent is enabled and within schedule
  4. Increase concurrency limit or add agents
  5. Check for stuck calls in Running status that should have ended
Symptoms: Sudden increase in active calls not matching expected volume.Causes:
  • Bulk campaign started
  • Multiple systems scheduling simultaneously
  • Webhook retry storms
  • Inbound call surge
Solutions:
  1. Review recent call scheduling patterns
  2. Check if bulk campaigns started unintentionally
  3. Implement rate limiting in scheduling systems
  4. Stagger scheduled calls with delays
  5. Add capacity checks before scheduling
Symptoms: Regularly reaching 100% utilization.Causes:
  • Insufficient capacity for volume
  • Long average call durations
  • Poor load distribution
Solutions:
  1. Upgrade to higher tier for more concurrency
  2. Add agents for load distribution
  3. Optimize prompts for shorter conversations
  4. Set maximum call duration limits
  5. Implement application-level rate limiting
Symptoms: Some agents at capacity while others idle.Causes:
  • Fixed agent assignment
  • Uneven scheduling distribution
  • Different agent schedules
Solutions:
  1. Implement load balancing when scheduling
  2. Route calls to least-loaded agent
  3. Align agent schedules with expected volume
  4. Consider using agent pools for similar use cases

What’s next

Call History

Manage scheduled call queue

Outbound Calls

Schedule outbound campaigns