📁 Volume II: Laravel Performance Tuning Kit

📚 Topic 18: Composer Autoloader Optimization

Stop PHP from searching for files. Save 5-10ms per request.

"Every time you use a class, PHP searches for it.
It checks PSR-4 directories, PSR-0 directories, classmap, and falls back to filesystem scanning.
This search costs time. Optimizing the autoloader removes the search entirely.
Your classes are found instantly."
⚠️ THE HIDDEN I/O

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.

🔍 How Composer Autoloading Works

HOW PHP FINDS CLASSES (WITHOUT OPTIMIZATION) ═══════════════════════════════════════════════════════════════════ When you write: $user = new App\Models\User; Step 1: PHP checks if class is already loaded → No Step 2: Calls Composer autoloader Step 3: Composer checks PSR-4 mapping (namespace → directory) Step 4: Composer builds path: src/Models/User.php Step 5: Composer checks if file exists in that location → file_exists('src/Models/User.php') ← I/O operation Step 6: If not found, tries fallback directories Step 7: Finally gives up or includes the file FOR EVERY SINGLE CLASS! WITH OPTIMIZATION (classmap-authoritative) ═══════════════════════════════════════════════════════════════════ Step 1: PHP checks if class is already loaded → No Step 2: Calls Composer autoloader Step 3: Composer checks classmap (pre-built array) → $classmap['App\\Models\\User'] = 'src/Models/User.php' Step 4: Includes the file directly Step 5: NO file_exists() calls. NO directory scanning. NO fallbacks. 1 I/O operation (the classmap file) vs 100+ I/O operations!

📊 Composer Optimization Levels

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)
THE COMMAND YOU SHOULD USE IN PRODUCTION
composer install --no-dev --optimize-autoloader --classmap-authoritative

This does three things:

📊 Performance Impact of Autoloader Optimization

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
⚠️ THE TRADE-OFF

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.

⚡ The Ultimate Speed: APCu + Classmap

WITH APCu AUTOLOADER CACHING ═══════════════════════════════════════════════════════════════════ Without APCu (even with classmap): ┌─────────────────────────────────────────────────────────────────┐ │ Request 1: Load classmap from disk → Cache in memory │ │ Request 2: Load classmap from disk → Cache in memory │ │ Request 3: Load classmap from disk → Cache in memory │ │ │ │ Problem: classmap is read from disk on every request! │ └─────────────────────────────────────────────────────────────────┘ With APCu: ┌─────────────────────────────────────────────────────────────────┐ │ Request 1: Load classmap from disk → Store in APCu (shared) │ │ Request 2: Fetch classmap from APCu (RAM) → NO disk I/O │ │ Request 3: Fetch classmap from APCu (RAM) → NO disk I/O │ │ │ │ Result: Classmap stays in shared memory across all requests │ └─────────────────────────────────────────────────────────────────┘ ENABLE APCu AUTOLOADER (PHP 8.1+) ═══════════════════════════════════════════════════════════════════ # php.ini apc.enabled=1 apc.shm_size=128M # Composer will automatically use APCu if available composer install --classmap-authoritative # Verify APCu is working php -m | grep apcu
ULTIMATE AUTOLLOADER CONFIGURATION
# 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'));"

🛠️ Complete Deployment Script with Autoloader Optimization

#!/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
HOW TO VERIFY OPTIMIZATION WORKED
# 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',

🔧 Troubleshooting Autoloader Issues

COMMON PROBLEMS
QUICK FIXES
# 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"

📝 composer.json Optimizations for Production

{
    "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
        }
    }
}
⚠️ NOTE

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.

📝 Topic 18 Summary: Composer Autoloader Optimization

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
📌 THE RULE: Always use --classmap-authoritative in production. Add APCu for even better performance. Never deploy with development autoloader settings — you're wasting 10-15ms per request for no reason.
NEXT TOPIC PREVIEW

Topic 19: Database Proxy (ProxySQL) — Connection pooling for MySQL. How to eliminate TCP handshake overhead and reuse database connections across requests.