# Concurrent Calls Capacity Analysis

## Current Configuration Summary

### 1. Application-Level Limits

#### Call Manager (Main Bottleneck)
- **Max Concurrent Calls**: `50` (configured in `call_manager.py`)
- **Location**: `homebook/services/call_manager.py:129`
- **Code**:
  ```python
  call_manager = CallManager(max_concurrent_calls=50)
  ```

#### ElevenLabs Connection Limiter (Secondary Bottleneck)
- **Max Concurrent ElevenLabs Connections**: `30` (configured in `elevenlabs_connection_limiter.py`)
- **Location**: `homebook/services/elevenlabs_connection_limiter.py:27-28`
- **Code**:
  ```python
  cls._instance.max_connections = 30
  cls._instance.semaphore = asyncio.Semaphore(30)
  ```

### 2. Server Resources

#### Hardware Specs
- **CPU Cores**: 24 cores
- **Total RAM**: 62 GB
- **Available RAM**: 51 GB (free + buff/cache)
- **Current Memory Usage**: 10 GB used
- **Swap**: 8 GB (85 MB used)

#### Current Service Status
- **Service**: `websocket_api.service` (running)
- **Process**: Python 3.8.10
- **Memory**: 51.9 MB (very low, single process)
- **Port**: 7900

## Answer: How Many Parallel Calls Can You Run?

### Current Limit: **30 Concurrent Calls**

**Why 30 and not 50?**

You have TWO limits configured:
1. ✅ **Call Manager**: 50 concurrent calls
2. ❌ **ElevenLabs Limiter**: 30 concurrent connections ← **THIS IS YOUR BOTTLENECK**

Since each call requires one ElevenLabs connection, you're limited to **30 concurrent calls** maximum.

### What Happens When You Hit the Limit?

#### At 30 concurrent calls:
- New calls will be queued/rejected
- Error message: `"ElevenLabs connection limit reached (30)"`
- Calls wait for slots to free up (with 5-second timeout)

#### At 50 concurrent calls (if ElevenLabs limit was removed):
- Call Manager would reject new calls
- Error message: `"Service overloaded - too many concurrent calls"`
- WebSocket closes with code 1013

## Resource Capacity Analysis

### Can Your Server Handle More?

**YES! Your server can handle MUCH more than 30 calls.**

#### Memory Analysis
- **Current usage**: 51.9 MB for the service
- **Per-call memory estimate**: ~10-20 MB per concurrent call
- **For 50 calls**: ~500 MB - 1 GB total
- **Available memory**: 51 GB
- **Verdict**: ✅ Memory is NOT a constraint

#### CPU Analysis
- **CPU cores**: 24 cores
- **Per-call CPU**: Minimal (mostly I/O-bound, async operations)
- **For 50 calls**: ~10-20% CPU usage estimated
- **Verdict**: ✅ CPU is NOT a constraint

#### Network/I/O
- **WebSocket connections**: Async I/O (very efficient)
- **Audio streaming**: Buffered, non-blocking
- **Database queries**: Connection pooling
- **Verdict**: ✅ Network is NOT a constraint

### Recommended Configuration

Based on your server specs, you can safely support **50-100 concurrent calls**.

## How to Increase to 50 Concurrent Calls

### Option 1: Quick Fix (Match ElevenLabs Limit to Call Manager)

Edit `homebook/services/elevenlabs_connection_limiter.py`:

```python
# Line 27-28
cls._instance.max_connections = 50  # Changed from 30
cls._instance.semaphore = asyncio.Semaphore(50)  # Changed from 30
```

### Option 2: Conservative Approach (Start with 40)

If you want to test gradually:

```python
# Line 27-28
cls._instance.max_connections = 40  # Start conservative
cls._instance.semaphore = asyncio.Semaphore(40)
```

### After Making Changes

```bash
# Restart the service
sudo systemctl restart websocket_api.service

# Monitor the service
sudo systemctl status websocket_api.service

# Watch logs for any issues
tail -f /var/www/html/live_calls/homebook/logs/voicebot.log
```

## Monitoring Concurrent Calls

### Check Active Sessions

The application exposes system status via the Call Manager:

```python
status = call_manager.get_system_status()
# Returns:
# {
#     "active_sessions": 15,
#     "max_concurrent_calls": 50,
#     "utilization_percent": 30.0,
#     "available_slots": 35,
#     "session_ids": [...]
# }
```

### Monitor Server Resources

```bash
# Watch CPU and memory usage
htop

# Check service memory
ps aux | grep "python3.*main.py"

# Monitor network connections
netstat -an | grep 7900 | wc -l

# Check Apache connections
netstat -an | grep :443 | grep ESTABLISHED | wc -l
```

## ElevenLabs Workspace Limits

### Important Note

The comment in `elevenlabs_connection_limiter.py` mentions:
- **Workspace limit**: 6 (base) or 14 (with bursting)
- **Agent limit**: 14 concurrent calls

However, the code is set to **30**, which suggests:
1. You may have a higher-tier ElevenLabs plan
2. Or the limit was increased manually

**⚠️ Check your ElevenLabs plan limits before increasing beyond 30!**

If your ElevenLabs plan only supports 14 concurrent connections, you'll get errors when exceeding that limit, regardless of your server capacity.

## Summary Table

| Resource | Current Limit | Server Capacity | Recommended |
|----------|--------------|-----------------|-------------|
| **Call Manager** | 50 | No limit (software) | 50-100 |
| **ElevenLabs Limiter** | 30 ⚠️ | Depends on plan | 50 (if plan allows) |
| **Memory** | No limit | 51 GB available | 100+ calls possible |
| **CPU** | No limit | 24 cores | 100+ calls possible |
| **Network** | No limit | Async I/O | 100+ calls possible |

## Bottleneck Priority

1. 🔴 **ElevenLabs API Plan Limit** - Check your subscription
2. 🟡 **ElevenLabs Connection Limiter** - Currently set to 30
3. 🟢 **Call Manager** - Set to 50
4. 🟢 **Server Resources** - Can handle 100+ easily

## Recommendation

### Immediate Action
1. **Check your ElevenLabs plan** - Verify concurrent connection limit
2. **If plan supports 50+**: Increase `elevenlabs_connection_limiter.py` to 50
3. **Test gradually**: Start with 40, monitor, then increase to 50

### Long-term
- Monitor actual usage patterns
- If you consistently need 50+ calls, consider:
  - Upgrading ElevenLabs plan
  - Implementing call queuing system
  - Load balancing across multiple servers

## Current Answer to Your Question

**Right now, you can run 30 parallel calls maximum.**

**After fixing the ElevenLabs limiter (and if your plan supports it), you can run 50 parallel calls.**

**Your server hardware can easily handle 100+ calls, but you're limited by the ElevenLabs connection limiter configuration.**

