perf: Optimize FrankenPHP/Octane configuration for high load

**Changes:**

1. **Caddyfile**:
   - Reduced num_threads from 24 to 20
   - Added request timeouts (read_body: 10s, write: 60s, idle: 120s)
   - With 4 containers: 20 × 4 = 80 total workers

2. **Dockerfile**:
   - Added explicit --workers=20 to octane:frankenphp command
   - Increased --max-requests from 250 to 1000
   - Applied to app-dev, app-release, and app stages

3. **Octane config**:
   - Enabled DisconnectFromDatabases listener
   - Enabled CollectGarbage listener
   - Prevents DB connection leaks and memory leaks

**Impact:**
- Better resource management under load
- Prevents connection pool exhaustion
- Requires db.t3.large (591 max connections) or better
- Supports up to 250 concurrent VUs

**Related:**
- Requires RDS upgrade from db.t4g.micro to db.t3.large
- Works with DB_CONNECTION_POOL_SIZE=25 (100 total connections)
- See configuration-analysis.md for details
This commit is contained in:
roncodes
2025-12-16 20:06:35 -05:00
parent c51f3ca6c8
commit a5a5ddb0d5
3 changed files with 18 additions and 6 deletions

View File

@@ -1,6 +1,9 @@
{
frankenphp {
num_threads 24
# Reduced from 24 to 20 for better resource management
# With 4 containers: 20 × 4 = 80 total workers
# Requires db.t3.large (591 max connections) or better
num_threads 20
}
order php_server before file_server
}
@@ -8,6 +11,15 @@
http://:8000 {
root * /fleetbase/api/public
encode zstd br gzip
# Request timeouts to prevent hanging
timeouts {
read_body 10s
read_header 5s
write 60s
idle 120s
}
php_server {
resolve_root_symlink
}

View File

@@ -105,8 +105,8 @@ return [
OperationTerminated::class => [
FlushOnce::class,
FlushTemporaryContainerInstances::class,
// DisconnectFromDatabases::class,
// CollectGarbage::class,
DisconnectFromDatabases::class, // ✅ Release DB connections after each request
CollectGarbage::class, // ✅ Prevent memory leaks
],
WorkerErrorOccurred::class => [

View File

@@ -158,14 +158,14 @@ CMD ["php", "artisan", "queue:work"]
# Application dev stage
FROM base AS app-dev
ENTRYPOINT ["docker-php-entrypoint"]
CMD ["sh", "-c", "php artisan octane:frankenphp --max-requests=250 --port=8000 --host=0.0.0.0 --watch"]
CMD ["sh", "-c", "php artisan octane:frankenphp --workers=20 --max-requests=1000 --port=8000 --host=0.0.0.0 --watch"]
# Application release stage
FROM base AS app-release
ENTRYPOINT ["docker-php-entrypoint"]
CMD ["sh", "-c", "php artisan octane:frankenphp --max-requests=250 --port=8000 --host=0.0.0.0"]
CMD ["sh", "-c", "php artisan octane:frankenphp --workers=20 --max-requests=1000 --port=8000 --host=0.0.0.0"]
# Application stage
FROM base AS app
ENTRYPOINT ["/sbin/ssm-parent", "-c", ".ssm-parent.yaml", "run", "--", "docker-php-entrypoint"]
CMD ["sh", "-c", "php artisan octane:frankenphp --max-requests=250 --port=8000 --host=0.0.0.0"]
CMD ["sh", "-c", "php artisan octane:frankenphp --workers=20 --max-requests=1000 --port=8000 --host=0.0.0.0"]