orchestra/optimize
Orchestra Optimize is a Laravel package from the Orchestra Platform ecosystem that provides Artisan commands and helpers for caching configuration, routes, views, and compiled classes. It helps speed up production deployments and reduce bootstrap overhead.
Check your framework version before anything else. orchestra/optimize v3.3.0 is a Laravel 5.3 compatibility release. Its entire purpose is to bundle Laravel's own cache-warming Artisan calls (config:cache, route:cache, view:cache/view:clear, cache:clear) behind a single optimize command plus a matching optimize:clear. If composer show laravel/framework reports anything ≥ 5.4, use the framework's native optimize / optimize:clear. This package is only a defensible dependency on a legacy 5.3 codebase that already runs Orchestra components.
Pin the version in the same PR as the install.
composer require "orchestra/optimize:^3.3" --update-with-dependencies
On 5.1/5.2, ^3.3 will drag the framework forward — use the 3.2.x line there. Commit the resulting composer.lock.
Register the provider manually — Laravel 5.3 has no package auto-discovery.
// config/app.php
'providers' => [
// ...
Orchestra\Optimize\OptimizeServiceProvider::class,
],
Read the registration before assuming the contract. The command signature is the contract of this package. The documentation is contradictory — the release note says "Update compiles list", the description talks about config/route/view caching — so verify your install:
php artisan list | grep -i optim
php artisan help optimize
php artisan help optimize:clear
Note specifically whether it registers optimize or overrides the framework's built-in one. Two commands with the same signature is the first landmine.
Read the source in this order: OptimizeServiceProvider::boot() (that is where the sub-command list is hardcoded) → the command class it registers. Publish config if any exists:
php artisan vendor:publish --provider="Orchestra\Optimize\OptimizeServiceProvider"
First use case to validate is the clear-then-warm deploy sequence on staging:
php artisan optimize:clear
php artisan optimize
Then hit three representative pages: one with @foreach/@include Blade, one resolved via a named route, one reading an env-backed config value (config('services.x.key')). Each exercises a different cache you just rebuilt. If all three pass, the package behaves.
Treat it as one line in a deploy pipeline, never as architecture. The package has no runtime footprint — it runs at deploy time and exits. The correct mental model is "a named alias for a shell one-liner," which frames every subsequent decision.
Canonical deploy sequence — clear before warm, always:
#!/usr/bin/env bash
set -euo pipefail
php artisan down --message="Deploying" || true
composer install --no-dev --optimize-autoloader --no-interaction
php artisan migrate --force
# Clear stale artifacts FIRST — warming on top of stale caches is the classic outage
php artisan optimize:clear
php artisan optimize
php artisan up
If the package's clear command is missing or behaves oddly on your version, substitute the explicit form and keep the ordering — that ordering is the pattern worth copying even if you drop the dependency:
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan config:cache
php artisan route:cache
Wrap it rather than sprinkle it. When the pipeline needs extra steps (warm an application cache, ping a healthcheck, touch a release marker), delegate instead of editing vendor:
// app/Console/Commands/DeployOptimize.php
class DeployOptimize extends Command
{
protected $signature = 'deploy:optimize';
public function handle()
{
$this->call('optimize:clear');
$this->call('optimize');
$this->call('app:warm-cache'); // your domain-specific warm-up
$this->info('Optimized.');
}
}
This confines the package to a single swappable file when you migrate off 5.3.
Pipeline integration points that actually matter:
optimize that runs the clear-then-warm pair. Make it idempotent — running it twice in a row must yield a working app. Test that explicitly; it's the cheapest correctness check you have.env() call inside a config file fails in CI rather than in production. Highest-value habit with this package.optimize at container build time only if config is fully baked into the image. If you inject env vars at runtime, cache at container start instead — otherwise config:cache freezes build-time env values into the artifact.Local development: do not run optimize on your dev machine. config:cache on a developer box means every .env edit silently stops working until someone remembers config:clear. Keep optimization to staging/production and document that next to the install instructions in the README.
config:cache breaks env() calls outside config files. This is the number-one post-optimize outage and is not package-specific — the package just makes it easier to trigger. Any env('FOO') in a controller, model, or service provider returns null once config is cached. Audit before adopting:
grep -rn "env(" app/ --include="*.php"
Everything found should live in config/*.php and be read back via config().
route:cache fails on closures. Any Route::get('/', function () {...}) in routes/ throws during caching — Laravel 5.3's serializer cannot compile closures. That failure is at least honest, but if you run with -q you'll deploy a partly optimized app. Never use -q on the first deploy pass.
view:cache may not exist on your version. Older lines shipped only view:clear; views compile lazily on first render. So "optimize" on 5.3 may mean "clear compiled views, let them rebuild on traffic," not "pre-warm." Check php artisan list rather than assuming the warm step touches views at all — and if it doesn't, expect the first few requests after deploy to be slower.
storage/framework/views permissions bite after optimization. If view:clear wipes the directory and the web user can't write to it, every page 500s with a confusing file_put_contents error. Verify ownership pre-deploy. Never chmod 777 your way out — set group ownership and g+s on the directory.
The documentation ambiguity is real; resolve it with a code read. The release note "Update compiles list" is undefined anywhere in the description. If it turns out to touch Blade compilation output or a cache manifest, deployed artifacts can differ from what you tested. Read the v3.3.0 diff (it's small) and confirm what "compiles list" means before it reaches production. If the answer is unclear, treat it as a no.
Command signature collisions. If both the framework and this package register optimize, php artisan optimize resolves to whichever the kernel registers last. Check php artisan help optimize and read the class name it prints. A silent switch mid-project is a nasty surprise during an incident.
Rolling deploys: clear-then-warm is per-instance, and instances disagree. Instance A may be serving cleared caches while instance B still has warm ones. Not the package's fault, but it's where incidents surface. Prefer a shared cache store with versioned keys, or accept a brief inconsistency window and serialize deploys behind a load balancer.
OpCache will happily serve stale compiled PHP. After config:cache, the cached config is a new file — but if you deploy via symlink and OpCache has validate_timestamps=0, FPM keeps executing old bytecode. Reload PHP-FPM as part of the deploy, every time.
Debugging checklist when "optimize ran but behaviour is stale":
ls -la bootstrap/cache/ # config.php, routes.php present and freshly timestamped?
php artisan tinker --execute="dump(config('app.env'));" # cached config matches reality?
php artisan route:list | head # routes parsed from the cached file?
ls -la storage/framework/views/ # compiled views regenerated?
Ninety percent of "the optimize didn't work" reports are one of: wrong .env cached, OpCache, or permissions on storage/framework/views.
Extension points are thin, and that's the point. The service provider's command list is the only real seam. If you need different behaviour, subclass the command and rebind it in your own provider rather than patching vendor — and write down the exit plan at the same time as the adoption plan. When you move to Laravel 5.5+, delete the dependency, drop the provider line, and swap your deploy script to the framework's optimize:clear && optimize. That migration is an afternoon's work if you kept the package confined to one command class and one pipeline step.
How can I help you explore Laravel packages today?