Performance Optimization & Caching
Optimize PHP application performance. Learn OPcache, Redis/Memcached integration, profiling, and efficient database query structures.
Downloaded from PrepIQ (https://prepiq.online)
Q1. What is OPcache and how does it improve PHP performance?
OPcache is a built-in PHP extension that stores precompiled script bytecode in shared memory, eliminating the need to parse and compile PHP files on every request.
With OPcache: Request → Check shared memory for cached bytecode → Execute directly (skip parse/compile)
; php.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0 ; disable in production for max speedEnabling OPcache typically gives a significant performance boost (often 2-3x) with essentially no code changes required.
Q2. What is the N+1 query problem and how do you fix it?
The N+1 problem occurs when fetching a list of records triggers one additional query per record to load related data, instead of one combined query.
$posts = Post::all(); // 1 query
foreach ($posts as $post) {
echo $post->author->name; // 1 query PER post = N queries
}Total: 1 + N queries
Fix with eager loading:
$posts = Post::with('author')->get(); // 2 queries total| Posts count | Without eager loading | With eager loading |
|---|---|---|
| 100 | 101 queries | 2 queries |
Q3. What caching strategies are available in PHP applications?
| Caching type | What it stores | Tool examples |
|---|---|---|
| Opcode caching | Compiled PHP bytecode | OPcache |
| Data/object caching | Query results, computed values | Redis, Memcached |
| Full-page caching | Entire rendered HTML response | Varnish, CDN edge cache |
| Fragment caching | Parts of a page (e.g. sidebar) | Blade @cache, application logic |
// Laravel example - cache expensive query for 1 hour
$products = Cache::remember('featured_products', 3600, function () {
return Product::where('featured', true)->get();
});The right strategy depends on how often data changes - full-page caching suits mostly-static content, while data caching suits frequently-read but rarely-written data.
Q4. How do you use Redis or Memcached for caching in PHP?
Both are in-memory key-value stores used to cache data that's expensive to compute or fetch repeatedly, avoiding hitting the database on every request.
// Laravel with Redis (config/cache.php: 'default' => 'redis')
Cache::put('user:' . $id, $userData, 600); // store for 10 min
$user = Cache::get('user:' . $id);
// Raw Redis client
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->set('user:1', json_encode($userData));
$redis->expire('user:1', 600);| Aspect | Redis | Memcached |
|---|---|---|
| Data structures | Strings, lists, sets, hashes, sorted sets | Simple key-value only |
| Persistence | Optional disk persistence | Memory-only, no persistence |
| Best for | Caching + queues + pub/sub | Simple, high-throughput caching |
Q5. How do you optimize slow database queries in PHP applications?
| Technique | How it helps |
|---|---|
| Add indexes on frequently queried columns | Avoids full table scans |
| Select only needed columns | Reduces data transfer, avoids SELECT * |
| Use EXPLAIN to analyze queries | Shows whether indexes are actually used |
| Eager load relationships | Avoids N+1 problem |
| Paginate large result sets | Avoids loading thousands of rows at once |
// Analyzing a slow query
EXPLAIN SELECT * FROM orders WHERE customer_id = 5 AND status = 'pending';
// Adding a composite index
CREATE INDEX idx_customer_status ON orders (customer_id, status);
// Selecting only needed columns
$users = User::select('id', 'name', 'email')->get();
Q6. What is lazy loading vs eager loading and when should you use each?
| Approach | Behavior | Best when |
|---|---|---|
| Lazy loading | Related data loaded only when accessed | Related data isn't always needed |
| Eager loading | Related data loaded upfront in one query | You know you'll need related data for every record |
// Lazy loading (default) - triggers query when accessed
$post = Post::find(1);
echo $post->author->name; // separate query fired here
// Eager loading - loads relationship upfront
$posts = Post::with('author')->get();
foreach ($posts as $post) {
echo $post->author->name; // no extra queries
}Rule of thumb: if you're looping over a collection and accessing a relationship inside the loop, eager load it to avoid N+1 queries.
Q7. How do you profile a PHP application to find performance bottlenecks?
| Tool | Purpose |
|---|---|
| Xdebug profiler | Function-level call graphs and timing |
| Blackfire | Production-safe profiling with visual call graphs |
| Laravel Telescope / Debugbar | Query counts, timing, memory per request |
| New Relic / Datadog APM | Application-wide monitoring in production |
// Basic manual timing
$start = microtime(true);
$result = expensiveOperation();
$duration = microtime(true) - $start;
error_log("Operation took: {$duration}s");
// Memory usage
echo memory_get_peak_usage(true) / 1024 / 1024 . ' MB';Q8. How does autoloading with Composer affect PHP performance, and how do you optimize it?
Composer's default autoloader (PSR-4) resolves class names to file paths dynamically. In production, this can be optimized into a fast, precomputed lookup.
# Development - flexible but slower
composer dump-autoload
# Production - optimized classmap, much faster
composer dump-autoload --optimize
# or during install/update
composer install --optimize-autoloader --no-dev| Mode | How it resolves classes |
|---|---|
| Default | Runtime PSR-4 namespace-to-path logic |
| Optimized (--optimize) | Precomputed classmap array, direct lookup |
The --optimize-autoloader flag is a standard part of production deployment scripts alongside opcache and config caching.
Q9. What is the difference between horizontal and vertical scaling for PHP applications?
| Scaling type | How it works | Trade-offs |
|---|---|---|
| Vertical scaling | Add more CPU/RAM to a single server | Simple but has a hardware ceiling; single point of failure |
| Horizontal scaling | Add more servers behind a load balancer | More complex (needs shared session/cache) but scales further and improves redundancy |
Sessions moved to Redis/database (not local files) → Uploaded files stored in shared storage (S3, not local disk) → Load balancer distributes requests across app servers → Database often needs read replicas
Most production PHP setups use horizontal scaling for the application layer combined with vertical scaling on the database layer.
Q10. What are common PHP coding practices that hurt performance, and how do you avoid them?
| Anti-pattern | Better approach |
|---|---|
| Queries inside loops | Batch fetch before the loop / eager loading |
| Loading entire large files into memory | Stream with fopen()/fgets() or generators |
| Using count() inside a loop condition repeatedly | Store count in a variable before the loop |
| Overusing regular expressions for simple checks | Use native string functions (str_contains, str_starts_with) |
// Bad - recalculates count() every iteration
for ($i = 0; $i < count($items); $i++) { ... }
// Good
$total = count($items);
for ($i = 0; $i < $total; $i++) { ... }
// Bad - loads whole file
$data = file_get_contents('huge.csv');
// Good - streams line by line
$handle = fopen('huge.csv', 'r');
while (($line = fgets($handle)) !== false) {
// process line
}
fclose($handle);
Performance Optimization & Caching
Optimize PHP application performance. Learn OPcache, Redis/Memcached integration, profiling, and efficient database query structures.
What is OPcache and how does it improve PHP performance?
OPcache is a built-in PHP extension that stores precompiled script bytecode in shared memory, eliminating the...
What is the N+1 query problem and how do you fix it?
The N+1 problem occurs when fetching a list of records triggers one additional query per record to load relate...
What caching strategies are available in PHP applications?
Caching typeWhat it storesTool examplesOpcode cachingCompiled PHP bytecodeOPcacheData/object cachingQuery resu...
How do you use Redis or Memcached for caching in PHP?
Both are in-memory key-value stores used to cache data that's expensive to compute or fetch repeatedly, avoidi...
How do you optimize slow database queries in PHP applications?
TechniqueHow it helpsAdd indexes on frequently queried columnsAvoids full table scansSelect only needed column...
What is lazy loading vs eager loading and when should you use each?
ApproachBehaviorBest whenLazy loadingRelated data loaded only when accessedRelated data isn't always neededEag...
How do you profile a PHP application to find performance bottlenecks?
ToolPurposeXdebug profilerFunction-level call graphs and timingBlackfireProduction-safe profiling with visual...
How does autoloading with Composer affect PHP performance, and how do you optimize it?
Composer's default autoloader (PSR-4) resolves class names to file paths dynamically. In production, this can...
What is the difference between horizontal and vertical scaling for PHP applications?
Scaling typeHow it worksTrade-offsVertical scalingAdd more CPU/RAM to a single serverSimple but has a hardware...
What are common PHP coding practices that hurt performance, and how do you avoid them?
Anti-patternBetter approachQueries inside loopsBatch fetch before the loop / eager loadingLoading entire large...