- Knowledge
- technology
- OOP
- Tips
- Programming
- Tips
- Tutorial
- SEO
- Ranking
- Knowledge
- Special Day
- Seo
- Bug
- Data science
- Seo
- artificial intelligence
- Machine Learning
- Robotics
- happyNewYear2021
- newYearEve
- 2021
- Automation
- Smart Home
- Career
- Best Practices
- Git
- Logging
- Web Fundamentals
- DNS
- HTTPS
- Performance
- AI Tools
- ChatGPT
- Claude
- Gemini
- Laravel
- Eloquent
- MySQL
- HTTPS
- TLS
- Web Security
- Certificates
- Developer Life
- Debugging
- Docker
- DevOps
- Transactions
- Queues
- LLMs
- AI
- AI Coding
- Developer Tools
- React Native
- Expo
- Kate PMS
- Mobile Apps
- Laravel
- Authentication
- Sanctum
- Cookies
- API Design
- Payments
- Idempotency
- DeepSeek
- Open Source AI
- LLMs
- AI News
- Git
- Version Control
- AI Coding
- Prompting
- PHP
- Checklist
- MCP
- AI Agents
- OpenAI
- Architecture
- Microservices
- Modular Monolith
- Estimation
- Developer Life
- Project Planning
- Humour
- OAuth
- OpenID Connect
- Authentication
- Embeddings
- Vector Search
- RAG
- pgvector
- OpenAI
- GPT-4.1
- Codex CLI
- Events
- Testing
- Clean Code
- Maintainability
- Code Review
- Webhooks
- API
- Security
- Claude Code
- Workflow
- AI
- LLM
- Prompt Injection
- Mobile
- React
- Networking
- TCP
- UDP
- HTTP/3
- CLAUDE.md
- AWS
- Cloud Security
- Backups
- PHPUnit
- Software Engineering
- Leadership
- Communication
- RAG
- Embeddings
- AI Engineering
- IT Infrastructure
- Networking
- Access Control
- CI/CD
- GitHub Actions
- Gemini CLI
- Claude Code
- JavaScript
- Async/Await
- Node.js
- Promises
- Security
- Cryptography
- Passwords
- MySQL
- Database
- Vibe Coding
- Software Quality
- DNS
- Code Reading
- Onboarding
- Productivity
- Background Jobs
- Developer Humour
- Estimates
- Dev Life
- JWT
- o3-mini
- DeepSeek R1
- Rate Limiting
- Kate PMS
- E-Signing
- Audit Trail
- REST
- GraphQL
- API Design
- Laravel 12
- Upgrade Guide
- Open Source
- Self-Hosting
- Task Scheduling
- Cron
- Secrets
- CORS
- PHP
- PHP-FPM
- OPcache
- GitHub Copilot
- Software Architecture
- Engineering
- TypeScript
- JavaScript
- Type Safety
- AI Security
- React Native
- Product Design
- AI Agents
- Kiro
- Queues
- Redis
- RabbitMQ
- AWS SQS
- Nginx
- Apache
- GPT-5
- gpt-oss
- Clean Code
- Architecture
- Naming
- Documentation
- Career
- ADR
- Teamwork
- Supply Chain
- Kate HRM
- HR Software
- Permissions
- System Design
- Pagination
- SSH
- Linux
- Big O
- Databases
- Laravel Boost
- MCP
- Developer Skills
- Validation
- Databases
- Indexes
- Code Quality
- Deployment
- Developer Humour
- Feature Flags
- Code Review
- Pull Requests
- Docker
- Cursor
- Authorization
- RBAC
- Gemini
- Long Context
- PHP 8.4
- Caching
- Dependency Injection
- Web Performance
- Browser
- CSS
- Database
- Migrations
- ChatGPT
- AI for Developers
- Monitoring
- On-Call
- REST
- Backend
- SQL
- NoSQL
- Database Design
- Coding Agents
- Claude 4
- API Resources
- REST API
- Load Balancing
- Scaling
- AWS
- AI Tools
- Claude
- Sora 2
- CTE
- 2FA
- TOTP
- Programming Languages
- Prompts
- Developer Workflow
- API Gateway
- APIs
- Passport
- API Auth
- Learning
- Burnout
- Developer Growth
- Web Development
- SEO
- Kate Mall
- ChatGPT Atlas
- Agent Skills
- Middleware
- Laravel 12
- Collections
- Context Window
- Monitoring
- Commit Messages
- Self Review
- Growth
- Regex
- Programming Basics
- Text Processing
- Database Design
- Normalization
- Linux
- Server Security
- Linux Foundation
- Open Standards
- Legacy Code
- Documentation
- AI Workflow
- File Uploads
- Test Data
- Hashing
- Performance
- Caching
- Enums
- Scope Creep
- Estimation
- Codex
- Gemini CLI
- Timezones
- Carbon
- Bugs
- PHP 8.5
- Gemini 3
- GPT-5.1
- Data Integrity
- Event Loop
- Async
- Opus 4.5
- AI Models
- React
- Forms
- Frontend
- Backups
- AI Images
- DALL-E
- Midjourney
- Race Conditions
- Concurrency
- Legacy Code
- Refactoring
- Senior Engineer
- Scope
- LLM
- CDN
- Web
- Sub-Agents
- Soft Deletes
- Audit Log
- Concurrency
- AI Learning
- NestJS
- AI Evals
- Policies
- SPF DKIM DMARC
- Unicode
- UTF-8
- Knowledge Graph
- Value Objects
- Technical Debt
- Feature Flags
- Laravel Pennant
- Deployment
- Copilot
- Composer
- Dependencies
- Artisan
- Automation
- AWS S3
- Object Storage
- Cloud
- Small Language Models
- Ollama
- Production
- Sessions
- HTTP
- Mentoring
- SQL
- Virtual Machines
- Web Development
- HTTP/2
- QUIC
- Web Performance
- AI Integration
- LLM API
- SOLID
- OOP
- Hosting
- Serverless
- Merge Conflicts
- Temperature
- AI Development
- Reverse Proxy
- Nginx
- Infrastructure
- Verification
- Passkeys
- WebAuthn
- Teams
- Communication
- Stakeholders
- Monorepo
- CI/CD
- Versioning
- JSON Schema
- Livewire
- Inertia
- Meetings
- Distributed Systems
- Privacy
- Full-Stack
- T-Shaped Skills
- Money
- Notifications
- Web Security
- HTTP Headers
- CSP
- Function Calling
- Load Testing
- k6
- Data Extraction
- Debugging
- WebSockets
- SSE
- Real-Time
- Laravel Reverb
- Infrastructure as Code
- Terraform
- Side Projects
- Laravel Pint
- OpenAPI
- Swagger
- UX
- Multimodal
- Jest
- Pair Programming
- APIs
- Rate Limiting
- Resilience
- Dev Humour
- Design Tokens
- JWT
- API Keys
- Sessions
- PHPStan
- Rector
- Incidents
- Reporting
- Dashboards
- Zero Trust
- IAM
- Search
- Laravel Scout
- Junior Developers
- Mentoring
- Images
- WebP
- AVIF
- Bug Reports
- Let's Encrypt
- Design Docs
- Software Design
- Observers
- Replication
- Accountability
- Data Structures
- Reliability
- LLM Memory
- Error Handling
- Payments
- Payment Gateway
- Webhooks
- PCI DSS
- Observability
- OpenTelemetry
- Personal Brand
- Writing
- Conventions
- Dates
- Scheduling
- Disaster Recovery
- Compression
- Brotli
- Deadlines
- Developer Habits
- State Machines
- Tech Roles
- UUID
- ULID
- Horizon
- Planning
- Engineering Culture
- Ownership
- Soft Skills
- Socialite
- Cost Control
- Collations
- Unicode
- Octane
- PostgreSQL
Laravel Octane: What It Is, When It Helps, and the State Leaks Nobody Warns You About
About Post
Classic PHP has the memory of a goldfish, and that's one of its best features.
Every request starts from nothing. Load the framework, register the service providers, read the config, handle the request, send the response, forget everything. The next request starts from nothing again. Nothing you did to memory in one request can possibly affect the next.
Laravel Octane removes the goldfish. Your app boots once and stays in memory, serving request after request. That makes it faster, and it also means a whole category of bugs that couldn't exist before suddenly can. Let's look at both sides.
What Octane actually does
With the usual setup (Nginx or Apache plus PHP-FPM), much of the work in a request is bootstrapping: loading classes, building the service container, registering providers, loading config and routes. OPcache helps a lot with the loading part, but the booting still happens on every request.
Octane runs your app on a long-lived application server, FrankenPHP, Swoole or RoadRunner. Each worker boots Laravel once, then keeps that booted application in memory and hands it request after request. The per-request boot cost mostly disappears.
Getting started is short:
composer require laravel/octane
php artisan octane:install # choose FrankenPHP, Swoole or RoadRunner
php artisan octane:start --workers=4 --max-requests=500
That's the easy part. The interesting part is what "stays in memory" means for code that was written assuming the goldfish.
The new rule: memory survives between requests
Under PHP-FPM, singletons and static properties live for one request. Under Octane, static properties, and any singleton resolved while the application boots, live for the lifetime of the worker: potentially hundreds of requests from different users.
Octane resets the framework's own state between requests, and gives each request a fresh copy of the container to resolve things into. But it can't know what your code tucked away in the shared parts. Here are the usual leaks.
Leak 1: a singleton that captured the request
This looks perfectly reasonable in a multi-tenant app:
// AppServiceProvider::register()
$this->app->singleton(CurrentTenant::class, function ($app) {
return new CurrentTenant($app['request']->user()?->tenant_id);
});
Under PHP-FPM, it's built fresh for every request. Under Octane, if it gets resolved while the app boots (from a service provider's boot() method, from another singleton that needs it, or because it's in Octane's warm list), it's built once per worker, with whatever request was around at that moment. Every later request on that worker shares it. Whether it happens depends on resolution order, which is exactly why it slips through testing. That isn't a performance bug. It's a data leak.
The fix is a scoped binding, which Laravel flushes at the start of every request (and every queued job):
$this->app->scoped(CurrentTenant::class, function ($app) {
return new CurrentTenant($app['request']->user()?->tenant_id);
});
More generally: don't inject the request, the container or the config repository into the constructor of anything that's a singleton. Resolve what you need at the moment you use it.
Leak 2: the static cache that never empties
class ExchangeRates
{
private static array $rates = [];
public function rate(string $currency): float
{
return self::$rates[$currency] ??= $this->fetchRate($currency);
}
}
Under PHP-FPM, that's a harmless per-request memo. Under Octane, the array lives as long as the worker. The rates are never refreshed, and if the key is something unbounded (a user ID, a search term), memory grows until the worker is recycled. Use the real cache with an expiry, or keep the memo on an object that's created per request.
Leak 3: setters on shared services
A service that lives for the whole worker (a boot-time singleton, or anything held in a static property) with a setCurrentUser() method, or a $warnings[] array that collects messages "for this request", or a flag like $this->skipNotifications = true set by one controller action. Octane resets a lot of the framework's own state for you, but it has no idea these properties exist. Whatever the last request left on that object, the next request on the same worker starts with.
The Octane rule: assume every object you didn't create inside the current request may have served someone else before. If it holds per-request or per-user data, it must be scoped, not shared.
Safety nets worth using
--max-requestsrecycles each worker after a number of requests, which caps the damage from slow memory leaks. It's a seatbelt, not a fix.php artisan octane:reloadin your deploy script. Workers hold the old code in memory, just like queue workers; without a reload, your deploy isn't live.--watchin local development, so the server restarts when files change, instead of you wondering why your edit did nothing.- Test under Octane before production. Run the app with Octane locally or in staging and use it as two different users in two browsers. Leaks like the first one tend to show up quickly that way.
- Check your packages. Most popular packages handle long-lived workers well now, but anything that keeps static state deserves a look.
When Octane helps
- High-traffic APIs where bootstrapping is a real share of each request's time, such as many small, fast requests from a mobile app.
- Apps with heavy boot costs: lots of service providers, packages and configuration.
- When you need more throughput from the same servers and you've already done the cheaper work (queries, indexes, caching).
When it doesn't (or isn't worth it yet)
- Your requests spend most of their time waiting on the database or external APIs. Octane removes boot time, not slow queries. Fix the N+1 first.
- Traffic is modest. PHP-FPM with OPcache is fast, simple and well understood. If it's comfortably handling your load, Octane adds operational complexity for a gain nobody will notice.
- The codebase leans on global or static state, especially an older one, or one with packages you can't audit. You'd be signing up for subtle cross-request bugs.
- The team hasn't worked with long-running PHP and the app handles sensitive per-user data. Get comfortable in staging first; the bugs here are security bugs.
My take
Octane is a genuinely good tool, and the speed-up is real for the right workload. But it's an optimisation with a new mental model attached, not a free upgrade. Measure where your request time actually goes, fix the cheap things first, and reach for Octane when bootstrapping is the bottleneck, with a team that knows the goldfish is gone.
The Octane documentation has a good section on dependency injection pitfalls; read it before your first deploy.
Have you run Octane in production? What was the first piece of state that surprised you by surviving between requests?

Be first to comment it...