# LiveComponents Memory Management

## Current Architecture (✅ Already Good)

### No Instance Caching
- **ComponentRegistry** creates fresh instances on each `resolve()`
- No memory leaks from accumulated component instances
- Components are garbage-collected after request

### TTL-Based Rendering Cache
- **ComponentCacheManager** caches rendered HTML only
- Automatic expiry via `Cacheable::getCacheTTL()`
- Tag-based invalidation for related components
- Delegates to Framework Cache (FileCache, ApcuCache, Redis)

### Framework Cache Handles Memory
- FileCache: Disk-based, no memory issues
- ApcuCache: APCu's memory management
- Redis: Redis memory eviction policies
- All support TTL and automatic cleanup

## Best Practices

### Component Design

**✅ DO:**
```php
final readonly class UserCardComponent implements LiveComponentContract
{
    public function __construct(
        private ComponentId $id,
        private UserId $userId  // ✅ Small Value Object
    ) {}

    public function getRenderData(): ComponentRenderData
    {
        // ✅ Load data on-demand
        $user = $this->userRepository->find($this->userId);

        return new ComponentRenderData(
            templatePath: 'user-card',
            data: ['user' => $user->toArray()]
        );
    }
}
```

**❌ DON'T:**
```php
final readonly class BadComponent implements LiveComponentContract
{
    public function __construct(
        private ComponentId $id,
        private array $allUsers  // ❌ Large dataset in constructor!
    ) {}
}
```

### Caching Strategy

**Cache Expensive Renders:**
```php
final readonly class StatsComponent implements LiveComponentContract, Cacheable
{
    public function shouldCache(): bool
    {
        return true;  // ✅ Expensive calculation
    }

    public function getCacheTTL(): Duration
    {
        return Duration::fromMinutes(5);  // ✅ Reasonable TTL
    }

    public function getCacheKey(): string
    {
        return "stats:{$this->dateRange->format()}";  // ✅ Vary by parameters
    }
}
```

**Don't Cache Simple Renders:**
```php
final readonly class ButtonComponent implements LiveComponentContract
{
    // ❌ Don't implement Cacheable for simple components
    // Caching overhead > render cost
}
```

### Memory Monitoring

**Per-Request Component Limits:**
```php
// Future Enhancement: Request-level tracking
final readonly class ComponentRequestTracker
{
    private int $componentsCreated = 0;
    private const MAX_COMPONENTS_PER_REQUEST = 100;

    public function track(ComponentId $id): void
    {
        $this->componentsCreated++;

        if ($this->componentsCreated > self::MAX_COMPONENTS_PER_REQUEST) {
            throw new TooManyComponentsException(
                "Request exceeded component limit: {$this->componentsCreated}"
            );
        }
    }
}
```

## Troubleshooting

### High Memory Usage

**Symptoms:**
- PHP memory limit errors
- Slow response times
- Cache growing too large

**Diagnosis:**
```php
// Check cache size
$stats = $cacheManager->getStats($component);
// Look at 'age_seconds' - old caches not expiring?

// Monitor per-request component creation
error_log("Components created this request: " . count($componentIds));
```

**Solutions:**

1. **Reduce Cache TTL:**
```php
public function getCacheTTL(): Duration
{
    return Duration::fromMinutes(1);  // Shorter TTL
}
```

2. **Implement Cache Tags:**
```php
public function getCacheTags(): array
{
    return ['user:' . $this->userId, 'dashboard'];
}

// Invalidate by tag when data changes
$registry->invalidateCacheByTag('user:123');
```

3. **Use Conditional Caching:**
```php
public function shouldCache(): bool
{
    // Only cache for non-admin users
    return !$this->user->isAdmin();
}
```

4. **Clear Old Caches:**
```bash
# Cron job for cleanup
*/30 * * * * php console.php cache:clear --tags=livecomponents
```

### Memory Leaks

**Potential Issues:**
- Event listeners not unsubscribed
- Database connections in lifecycle hooks
- Large closures in component state

**Prevention:**
```php
final readonly class SafeComponent implements LiveComponentContract, LifecycleAware
{
    public function onMount(): void
    {
        // ✅ Subscribe to events
        $this->eventBus->subscribe('user.updated', $this->handleUserUpdate(...));
    }

    public function onDestroy(): void
    {
        // ✅ ALWAYS unsubscribe
        $this->eventBus->unsubscribe('user.updated', $this->handleUserUpdate(...));
    }
}
```

## Monitoring

### Recommended Metrics

**Component Metrics:**
- `livecomponent.created.count` - Components created per request
- `livecomponent.render.duration_ms` - Render time distribution
- `livecomponent.cache.hit_rate` - Cache effectiveness

**Memory Metrics:**
- `php.memory.usage_bytes` - Current memory usage
- `php.memory.peak_bytes` - Peak memory per request
- `cache.size_bytes` - Total cache size

**Alert Thresholds:**
- Memory usage > 80% of limit
- Components per request > 50
- Cache hit rate < 50%
- Render time > 200ms (p95)

## Production Configuration

```php
// config/cache.php
return [
    'livecomponents' => [
        'default_ttl' => 300,        // 5 minutes
        'max_cache_size' => '100MB', // Per-driver limit
        'cleanup_interval' => 3600,  // 1 hour
        'enable_metrics' => true
    ]
];
```

## Future Enhancements

### Planned Improvements

1. **Request-Level Component Tracking**
   - Track component creation count
   - Enforce per-request limits
   - Alert on threshold violations

2. **Memory Usage Profiling**
   - Component memory footprint tracking
   - Automatic large component detection
   - Performance regression alerts

3. **Intelligent Cache Eviction**
   - LRU eviction when cache full
   - Prioritize by component usage frequency
   - Automatic TTL adjustment based on hit rate

4. **Component Lifecycle Monitoring**
   - Track component lifetime
   - Detect components never destroyed
   - Memory leak detection

## Summary

✅ **Current State:** Memory management is solid
- No instance caches
- TTL-based rendering cache
- Framework cache handles underlying memory

✅ **No Immediate Action Required**
- Architecture is already memory-safe
- Follow best practices above
- Implement monitoring for production

⚠️ **Future Work:** Request-level limits and enhanced monitoring (Phase 5 - Observability)
