- 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
What Happens Inside a PHP Request: From Apache to Your Laravel Controller
About Post
Here's something that surprises developers coming to PHP from Node or Java: every single request, your Laravel app is built from scratch. The container, the config, the service providers, the routes. Built, used once, thrown away. Then built again for the next request.
That sounds wasteful. It's also one of the reasons PHP is so hard to break, and it explains most of the performance advice you've ever been given about Laravel.
Let's follow one request, GET /api/contracts/42, from the moment it reaches the server to the moment your controller runs, and back.
Stop 1: Apache decides who handles it
Apache receives the request and matches it to a virtual host by domain name. The vhost's DocumentRoot points at Laravel's public/ folder, which is why nothing else in your project is reachable from the web.
If the URL matches a real file, like /build/app.css, Apache serves it directly and PHP never wakes up. If not, the rewrite rules in public/.htaccess send the request to index.php. That's how one PHP file handles every route in your app: the "front controller" pattern.
Stop 2: the hand-off to PHP
Apache doesn't run your PHP code itself. There are two common ways it hands the work over:
- mod_php embeds PHP inside each Apache process. Simple, common on older setups and local stacks, but every Apache process carries PHP's memory even when it's just serving an image.
- PHP-FPM runs PHP as its own pool of worker processes. Apache (or Nginx) passes PHP requests to it over FastCGI. This is the standard for production today.
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.4-fpm.sock|fcgi://localhost"
</FilesMatch>
The detail that matters in production: each FPM worker handles one request at a time. If pm.max_children allows 20 workers and 20 slow requests are running, request 21 waits in line. When a site "randomly" slows down under load, a full FPM pool is one of the first things I check. Slow external API calls inside requests are a common cause: the worker just sits there, waiting.
Stop 3: PHP compiles your code (unless OPcache already did)
PHP is interpreted, but not line by line. For each file it loads, PHP parses the source and compiles it into opcodes, low-level instructions for the Zend engine. Then it executes them.
A Laravel request touches a lot of files: your code, the framework, and everything in vendor/. Compiling all of that on every request would be painful. That's what OPcache is for: it keeps the compiled opcodes in shared memory, so after the first request, PHP skips the compile step entirely.
Two practical notes:
- In production you can set
opcache.validate_timestamps=0so PHP stops checking whether files changed. Faster, but you must reload PHP-FPM after each deploy, or the server keeps running the old code. - The JIT that arrived in PHP 8.0 helps CPU-heavy work. For a typical web app that mostly waits on the database, OPcache is the big win.
Stop 4: Laravel boots
Now public/index.php runs. In Laravel 12 it's short (simplified here):
<?php
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
require $maintenance; // maintenance mode, before anything else loads
}
require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$app->handleRequest(Request::capture());
Request::capture() wraps PHP's raw superglobals ($_GET, $_POST, $_SERVER) into a request object. Then the HTTP kernel runs its bootstrappers: load the environment, load config, set up error handling, register facades, then register and boot every service provider.
This is where the "rebuilt every request" cost lives. It's also why the classic production commands matter: php artisan config:cache replaces dozens of config files with one, route:cache skips building the route list, and php artisan optimize does the common caches in one go.
Stop 5: middleware, the onion
The request now passes through global middleware: trusting proxies, handling CORS, checking maintenance mode, trimming strings, turning empty strings into null. Think of middleware as layers of an onion. The request goes in through each layer, and the response comes back out through the same layers in reverse.
Stop 6: the router
The router finds the route matching GET /api/contracts/{contract}, then runs that route's middleware: the api group, authentication, rate limiting. Route model binding turns 42 into a Contract model, or a 404 if it doesn't exist.
Stop 7: finally, your controller
Laravel's service container builds your controller and injects its dependencies. If the method type-hints a Form Request, validation runs before your method body does. Your code queries the database, maybe dispatches a job, and returns something: a model, an array, a view or a resource.
Whatever you return gets converted into a proper response (arrays and models become JSON), travels back out through the middleware onion, and is sent to the client.
Stop 8: terminate, then forget everything
After the response is sent, terminable middleware gets a chance to run. Then PHP releases the request's objects and memory. The next request starts from a clean slate.
This is the "shared-nothing" model, and it's underrated. A memory leak can't build up over days. One request can't accidentally see another user's data left in a static variable. A crash affects one request, not the whole server.
What this means in practice: enable OPcache, cache config and routes on every deploy, keep service providers' boot() methods light, and size your FPM pool for your slowest requests, not your average ones.
And if booting every time is too slow?
That's what Laravel Octane is for. It boots the app once and keeps it in memory, serving many requests with FrankenPHP, Swoole or RoadRunner. It can be much faster, but you give up shared-nothing: static properties and singletons now survive between requests, and you have to write code with that in mind. For most apps, a well-tuned FPM setup with OPcache is plenty.
The official request lifecycle docs are a short, worthwhile read if you want the framework's own version of this tour.
Which stop on this trip has caused you the most trouble in production? My vote goes to Stop 2: a full FPM pool looks exactly like "the server is slow" until you check.

Be first to comment it...