# El Captain Sports Management — Infrastructure & Capacity Planning

## Current Production Hardware Usage

**Server:** AWS EC2 (Frankfurt — eu-central-1)  
**IP:** 18.192.166.221  
**OS:** Ubuntu 24.04.4 LTS  
**Orchestration:** CapRover (Docker Swarm)

### Current Container Stats

| Container | RAM Usage | CPU Usage | Image Size |
|-----------|-----------|-----------|------------|
| App (Laravel + Nginx + PHP-FPM) | 111.1 MiB | 0.02% | 975 MB |
| Database (PostgreSQL 16) | 37.4 MiB | 0.00% | ~400 MB |
| **Total System** | **148.5 MiB** | **~0.02%** | **~1.4 GB** |

### Current Database Stats

| Metric | Value |
|--------|-------|
| Total DB Size | 15 MB |
| Total Tables | 76 |
| Total Rows | 1,797 |
| Active Connections | 3 |
| Total Index Size | 3.8 MB |
| Largest Table | permission_role (344 KB / 1,002 rows) |

### Current Data Volume (10 Participants)

| Entity | Row Count |
|--------|-----------|
| Participants | 10 |
| Invoices | 9 |
| Payments | 6 |
| Audit Logs | 135 |
| Permission-Role | 1,002 |

### App Configuration

| Setting | Value |
|---------|-------|
| PHP Memory Limit | 256 MB |
| PHP-FPM Workers | Default (dynamic) |
| Queue Workers | 2 (supervisor) |
| PostgreSQL shared_buffers | 128 MB |
| PostgreSQL work_mem | 4 MB |
| PostgreSQL max_connections | 100 |
| PostgreSQL effective_cache_size | 4 GB |

---

## Scaling Projections

### Methodology

Based on current data (10 participants = 1,797 rows / 15 MB / 148.5 MiB RAM), we extrapolate using realistic ratios for a sports academy:

**Per participant (annual, normal usage):**
- ~15 invoices/year (monthly fees + extras)
- ~12 payments/year
- ~150 attendance records/year (3 sessions/week × 50 weeks)
- ~200 audit log entries/year (CRUD on profile, payments, attendance)
- ~3 enrollments/year (seasonal programs)
- ~5 inventory movements/year (equipment, uniforms)
- ~30 notifications/year

### Row Growth Formula (per year)

```
Annual Rows per Participant ≈ 415 rows
Base System Rows (roles, permissions, settings, accounts) ≈ 2,000 rows (fixed)
```

### Storage Growth Formula

```
DB Size ≈ 2 MB (base) + (participants × 0.8 MB/year)
Audit Logs ≈ participants × 200 rows × 0.5 KB/row = participants × 100 KB/year
Total Annual Growth ≈ participants × 1.0 MB/year
```

---

## Capacity Tiers

### Tier Breakdown

| Tier | Players | Annual DB Growth | Year-End DB Size | RAM (App) | RAM (DB) | Total RAM | vCPUs |
|------|---------|-----------------|------------------|-----------|----------|-----------|-------|
| Starter | 50 | 50 MB | ~65 MB | 256 MB | 256 MB | 512 MB | 1 |
| Small | 200 | 200 MB | ~215 MB | 512 MB | 512 MB | 1 GB | 1 |
| Medium | 500 | 500 MB | ~515 MB | 1 GB | 1 GB | 2 GB | 2 |
| Large | 2,000 | 2 GB | ~2.1 GB | 2 GB | 2 GB | 4 GB | 2 |
| Enterprise | 5,000 | 5 GB | ~5.1 GB | 4 GB | 4 GB | 8 GB | 4 |
| Multi-Academy | 10,000+ | 10+ GB | ~10.1 GB | 8 GB | 8 GB | 16 GB | 8 |

### Concurrent Users Estimation

| Players | Peak Concurrent Users | Requests/sec (peak) | PHP Workers Needed |
|---------|----------------------|--------------------|--------------------|
| 50 | 5-10 | 2-5 | 2 |
| 200 | 20-40 | 10-20 | 4 |
| 500 | 50-100 | 25-50 | 8 |
| 2,000 | 200-400 | 100-200 | 16 |
| 5,000 | 500-1000 | 250-500 | 32 |
| 10,000 | 1000-2000 | 500-1000 | 64 (clustered) |

---

## 500-Player Academy — Full Year Projection

### Monthly Data Growth

| Month | Cumulative Rows | DB Size | Audit Logs | Attendance Records |
|-------|----------------|---------|------------|-------------------|
| Jan | 12,000 | 12 MB | 8,300 | 6,000 |
| Feb | 29,000 | 25 MB | 16,600 | 12,000 |
| Mar | 46,000 | 42 MB | 24,900 | 18,000 |
| Apr | 63,000 | 58 MB | 33,200 | 24,000 |
| May | 80,000 | 72 MB | 41,500 | 30,000 |
| Jun | 97,000 | 88 MB | 49,800 | 36,000 |
| Jul | 114,000 | 105 MB | 58,100 | 42,000 |
| Aug | 131,000 | 120 MB | 66,400 | 48,000 |
| Sep | 148,000 | 138 MB | 74,700 | 54,000 |
| Oct | 165,000 | 155 MB | 83,000 | 60,000 |
| Nov | 182,000 | 170 MB | 91,300 | 66,000 |
| Dec | 209,500 | 515 MB* | 100,000 | 75,000 |

*Year-end includes indexes, TOAST data, and bloat factor (~3x raw data for PostgreSQL with indexes)

### Recommended Hardware (500 Players)

| Component | Minimum | Recommended | Notes |
|-----------|---------|-------------|-------|
| vCPUs | 1 | 2 | Handles peak registration days |
| RAM | 1.5 GB | 2 GB | 1 GB app + 1 GB PG |
| Storage | 5 GB | 20 GB | Room for 3 years + backups |
| Network | Shared | Shared | <100 Mbps sufficient |
| Backup | Daily | Daily + WAL | Point-in-time recovery |

### Hosting Cost Estimate (500 Players)

| Provider | Instance | Monthly Cost (USD) | Monthly Cost (EGP) |
|----------|----------|-------------------|--------------------|
| AWS EC2 | t3.small (2 vCPU / 2 GB) | $18.40 | 920 ج.م |
| Hetzner | CX22 (2 vCPU / 4 GB) | $5.39 | 270 ج.م |
| DigitalOcean | Basic (2 vCPU / 2 GB) | $18.00 | 900 ج.م |
| CapRover (current) | Shared | ~$5.00 | 250 ج.م |

---

## Mermaid Diagrams

### System Architecture

```mermaid
graph TB
    subgraph "CapRover Host (18.192.166.221)"
        subgraph "App Container"
            NGINX[Nginx Reverse Proxy]
            PHP[PHP-FPM Workers]
            QUEUE[Queue Workers x2]
            SCHED[Scheduler]
        end
        subgraph "DB Container"
            PG[(PostgreSQL 16)]
        end
        NGINX --> PHP
        PHP --> PG
        QUEUE --> PG
    end
    
    CLIENT[Browser / Mobile] -->|HTTPS| NGINX
    CAPROVER[CapRover Proxy] --> NGINX
```

### RAM Usage by Player Count

```mermaid
xychart-beta
    title "RAM Requirements by Player Count"
    x-axis ["50", "200", "500", "1K", "2K", "5K", "10K"]
    y-axis "RAM (GB)" 0 --> 16
    bar [0.5, 1, 2, 3, 4, 8, 16]
```

### Database Size Growth (500 Players — 12 Months)

```mermaid
xychart-beta
    title "Database Size Growth — 500 Player Academy (Year 1)"
    x-axis ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    y-axis "Size (MB)" 0 --> 550
    line [12, 25, 42, 58, 72, 88, 105, 120, 138, 155, 170, 515]
    bar [12, 25, 42, 58, 72, 88, 105, 120, 138, 155, 170, 515]
```

### Row Count Growth (500 Players — 12 Months)

```mermaid
xychart-beta
    title "Total Row Count — 500 Player Academy (Year 1)"
    x-axis ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    y-axis "Rows (thousands)" 0 --> 220
    line [12, 29, 46, 63, 80, 97, 114, 131, 148, 165, 182, 209]
```

### Concurrent Users vs Required PHP Workers

```mermaid
xychart-beta
    title "PHP-FPM Workers Needed by Concurrent Users"
    x-axis ["10", "40", "100", "200", "400", "1000"]
    y-axis "Workers" 0 --> 64
    bar [2, 4, 8, 16, 32, 64]
```

### Cost vs Player Count (Monthly USD)

```mermaid
xychart-beta
    title "Monthly Hosting Cost by Tier (USD)"
    x-axis ["50 players", "200 players", "500 players", "2K players", "5K players"]
    y-axis "USD/month" 0 --> 80
    bar [5, 10, 18, 40, 75]
```

### Data Distribution (500 Players — Year End)

```mermaid
pie title "Row Distribution at Year End (500 Players)"
    "Attendance Records" : 75000
    "Audit Logs" : 100000
    "Invoices & Payments" : 13500
    "Notifications" : 15000
    "Enrollments & Groups" : 4000
    "Base System" : 2000
```

### Scaling Decision Tree

```mermaid
flowchart TD
    START[Current Load] --> CHECK{Response Time > 200ms?}
    CHECK -->|No| MONITOR[Continue Monitoring]
    CHECK -->|Yes| CPU{CPU > 70%?}
    CPU -->|Yes| SCALE_CPU[Add vCPUs / More Workers]
    CPU -->|No| RAM{RAM > 80%?}
    RAM -->|Yes| SCALE_RAM[Upgrade Instance RAM]
    RAM -->|No| DB{DB Queries Slow?}
    DB -->|Yes| DB_OPT[Add Indexes / Tune PG]
    DB -->|No| QUEUE{Queue Backlog?}
    QUEUE -->|Yes| SCALE_QUEUE[Add Queue Workers]
    QUEUE -->|No| NETWORK[Check Network / CDN]
    
    SCALE_CPU --> VERIFY[Verify Fix]
    SCALE_RAM --> VERIFY
    DB_OPT --> VERIFY
    SCALE_QUEUE --> VERIFY
    NETWORK --> VERIFY
    VERIFY --> MONITOR
```

### Year-Over-Year Projection (500 Players)

```mermaid
xychart-beta
    title "3-Year Storage Projection — 500 Players (GB)"
    x-axis ["Year 1", "Year 2", "Year 3"]
    y-axis "Storage (GB)" 0 --> 2
    bar [0.5, 1.1, 1.7]
```

---

## Key Recommendations

### For a 500-Player Academy (Standard Deployment)

1. **Hosting:** 2 vCPU / 2 GB RAM instance (t3.small or equivalent) — $18/month
2. **Storage:** 20 GB SSD (allows 3+ years of growth with headroom)
3. **Database:** PostgreSQL 16, shared_buffers=512MB, work_mem=8MB
4. **PHP-FPM:** 8 workers (handles 50-100 concurrent users)
5. **Queue:** 2-4 workers for background jobs (notifications, attendance, reports)
6. **Backup:** Daily pg_dump + WAL archiving for point-in-time recovery
7. **Monitoring:** Set alerts at 80% RAM, 70% CPU, 80% disk

### When to Scale Up

| Signal | Action |
|--------|--------|
| p95 response > 500ms | Add PHP workers or vCPUs |
| RAM consistently > 80% | Upgrade to 4 GB instance |
| DB > 5 GB | Consider read replicas |
| Concurrent users > 200 | Move to 4 vCPU instance |
| Multiple academies on same DB | Shard or separate databases |

### Current System Health

The system is **massively over-provisioned** for its current 10 participants:
- Using 0.02% CPU (needs ~0.0001% per player)
- Using 148 MB of RAM (needs ~15 MB per player for app overhead)
- Database at 15 MB (well under the 515 MB projected for 500 players after a full year)
- 97 idle PostgreSQL connections available

**Bottom line:** The current infrastructure can handle **500+ players** without any changes. Scaling only becomes necessary at **2,000+ players** or when adding multiple academies.

---

## Summary Table

| Metric | Current (10 players) | Target (500 players) | Growth Factor |
|--------|---------------------|---------------------|---------------|
| DB Size | 15 MB | 515 MB | 34x |
| Total Rows | 1,797 | 209,500 | 117x |
| RAM Usage | 148 MB | ~1.5 GB | 10x |
| CPU Usage | 0.02% | ~5-15% | 250-750x |
| Monthly Cost | $5 (shared) | $18 (dedicated) | 3.6x |
| Annual Cost | $60 | $216 | 3.6x |
