What's Specific For Laravel
- Build-time optimization. Composer install,
php artisan config:cache,
route:cache, view:cache, and
event:cache all run in the image build. Deploy is an
image swap.
- Queue workers as platform-managed processes.
php artisan queue:work runs as a long-lived worker pod
(Redis or database driver), supervised separately from the web tier
and scaled by HPA.
- Scheduler as a Kubernetes CronJob.
php artisan schedule:run ticks every minute on the cron
pool — never coupled to your web pod's uptime.
- Per-slot external Redis for cache. Blue/green
deploys don't wipe your cache; sessions stay valid across the
cutover via shared session Redis — true zero-downtime deploys, with
no cold start and no dropped session.
- Octane-compatible. Run
laravel/octane
with Swoole or RoadRunner if you want — the runtime supports both
the classic FPM and the long-lived process model.
What synavel Gets You That Generic Laravel Hosting Doesn't
- Diagnostic report on every deploy. Slow API
endpoint after a release? We trace the request through middleware,
the controller, the Eloquent query — and name the line.
- Per-tenant MySQL with XtraBackup + binlog shipping.
14-day PITR. A bad migration rolls back to any timestamp in the
window.
- Migration classifier on every deploy. We
distinguish code-only deploys from additive schema from breaking
DDL. Breaking changes block on approval.
- MCP server for your agent. Cursor or Claude Code
can deploy, rollback, restart queue workers, and query traces
without leaving your IDE. Same tool surface our internal team uses.
What A synavel Diagnostic Looks Like
Real finding shape. Every report carries a finding ID, the evidence
trace, the exact file:line, and a recommended fix — in your stack's
idioms, not a generic dashboard widget.
N+1 in queue job — lazy-loading items per order
Evidence
trace 5b8c104: queue:work → SendDigestJob → mysql
pattern: SELECT * FROM order_items WHERE order_id = ?
fired 1,840 times per batch · 22s job runtime Code Location
app/Jobs/SendDigestJob.php:46
foreach ($orders as $order)
$order->items->sum('total'); // lazy-load per order Recommended Fix
1. Eager-load: Order::with('items')->chunk(200, ...)
2. Or aggregate: $orders->withSum('items', 'total')
Expected runtime: 22s → ~1.8s per batch