Stop PHP from searching for files. Save 5-10ms per request.
Without optimization, the Composer autoloader scans filesystem directories on every request. Each class lookup can trigger multiple file_exists() and stat() calls. With 100+ classes per request, this adds 5-15ms of overhead — completely unnecessary in production.
| Command | What It Does | Performance | When to Use |
|---|---|---|---|
composer install (default)
| Generates PSR-4 mapping only | Slow (scans directories) | Development only |
composer dump-autoload
| Regenerates autoloader files | Same as default | After adding new classes |
composer dump-autoload -o
| Optimized (classmap for PSR-4) | 2-3x faster than default | Production (good) |
composer dump-autoload --classmap-authoritative
| No fallback — classmap only | 5-10x faster than default | Production (best) | composer install --no-dev --optimize-autoloader --classmap-authoritative
| Everything optimized + no dev deps | Fastest possible | Production deployment (RECOMMENDED) |
composer install --no-dev --optimize-autoloader --classmap-authoritative
This does three things:
--no-dev — Skips development packages (PHPUnit, Laravel Debugbar, etc.)--optimize-autoloader — Converts PSR-4 to classmap for faster lookup--classmap-authoritative — Disables filesystem scan. If class not in classmap, it doesn't exist.| Optimization Level | Time to load 100 classes | Time per request (typical Laravel) | Improvement |
|---|---|---|---|
| No optimization (dev default) | ~12ms | ~15-20ms | Baseline |
-o (optimize)
| ~4ms | ~5-8ms | 2.5x faster |
--classmap-authoritative
| ~1ms | ~2-4ms | 5x faster |
--classmap-authoritative + APCu
| ~0.3ms | ~1-2ms | 10x faster |
With classmap-authoritative, if you add a new class and forget to regenerate the autoloader, PHP will throw a "class not found" error. There is no fallback filesystem scan. Always regenerate the autoloader after adding new classes.
# Step 1: Install APCu extension
sudo apt-get install php8.2-apcu
# Step 2: Configure APCu (php.ini)
apc.enabled=1
apc.shm_size=128M
apc.ttl=7200
apc.enable_cli=0
# Step 3: Optimize Composer with classmap-authoritative
composer install --no-dev --optimize-autoloader --classmap-authoritative
# Step 4: Verify
php -r "var_dump(class_exists('App\Models\User'));"
#!/bin/bash
# deploy.sh - Production deployment script
set -e # Exit on error
echo "🚀 Starting deployment..."
# 1. Put application in maintenance mode
php artisan down --retry=60
# 2. Pull latest code
git pull origin main
# 3. Install/update Composer dependencies (PRODUCTION MODE)
composer install \
--no-dev \ # Skip dev dependencies
--optimize-autoloader \ # Optimize PSR-4 to classmap
--classmap-authoritative \ # No filesystem fallback
--no-interaction \
--no-progress \
--no-suggest
# 4. Run database migrations
php artisan migrate --force --no-interaction
# 5. Clear and rebuild caches
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
# 6. Restart queue workers
php artisan queue:restart
# 7. Clear OpCache (if using)
sudo systemctl reload php8.2-fpm
# 8. Bring application back online
php artisan up
echo "✅ Deployment complete!"
# 9. Optional: Warm up the cache
curl -s https://example.com > /dev/null
# Check if classmap-authoritative is enabled
composer dump-autoload --classmap-authoritative --dry-run
# Check the generated autoloader
cat vendor/composer/autoload_classmap.php | head -20
# You should see an array mapping namespaces to file paths:
# 'App\\Models\\User' => '/var/www/app/Models/User.php',
composer dump-autoloadCOMPOSER_MEMORY_LIMIT=-1 composer installcomposer.json "autoload" section# Regenerate autoloader from scratch
composer dump-autoload --classmap-authoritative
# Clear Composer cache (if having weird issues)
composer clear-cache
# Debug autoloader
composer dump-autoload --classmap-authoritative --verbose
# Check what's being autoloaded
php -r "var_dump(get_declared_classes());" | grep -i "yourclass"
{
"name": "laravel/laravel",
"type": "project",
"require": {
"php": "^8.2",
"laravel/framework": "^11.0"
},
"require-dev": {
"laravel/pint": "^1.0",
"laravel/sail": "^1.0",
"nunomaduro/collision": "^8.0",
"phpunit/phpunit": "^10.0"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
]
},
"config": {
"optimize-autoloader": true, // ← Added
"classmap-authoritative": true, // ← Added (for production)
"sort-packages": true,
"allow-plugins": {
"pestphp/pest-plugin": true,
"php-http/discovery": true
}
}
}
Setting "classmap-authoritative": true in composer.json forces the autoloader to only use the classmap. This is great for production but breaks development if you add new classes frequently. Use it only in production deployments.
| Optimization | Command | Time per Request | Production? |
|---|---|---|---|
| Default (development) | composer install
| 15-20ms | ❌ No |
| Optimized autoloader | composer install -o
| 5-8ms | ✅ Yes (good) |
| Classmap authoritative | composer install --classmap-authoritative
| 2-4ms | ✅ Yes (better) |
| Classmap + APCu | APCu extension + authoritative | 1-2ms | ✅ Yes (best) |
| Full production command | composer install --no-dev --optimize-autoloader --classmap-authoritative
| 1-3ms | ✅ RECOMMENDED |
Topic 19: Database Proxy (ProxySQL) — Connection pooling for MySQL. How to eliminate TCP handshake overhead and reuse database connections across requests.