API Performance Standards
Response Time Targets
Industry Standards (Odown 2025):
- <100ms: Excellent (interactive APIs)
- 100-500ms: Acceptable (web/mobile applications)
- >500ms: Poor (requires immediate optimisation)
Business Impact:
- 100ms latency delay → 7% reduction in conversion rates (Google 2024)
- Amazon metric: 1% sales loss per extra 100ms latency
- User perception: <100ms feels instant, >500ms feels sluggish
N+1 Query Problem
What is N+1?
// BAD: N+1 query problem
$users = User::all(); // 1 query
foreach ($users as $user) {
echo $user->posts; // N queries (one per user)
}
// Total: 1 + N queries (exponential growth)
// GOOD: Eager loading
$users = User::with('posts')->get(); // 2 queries total
foreach ($users as $user) {
echo $user->posts; // No additional queries
}
// Total: 2 queries (constant)
Detection Tools:
- Laravel Debugbar: Visual query log in development
- Laravel Query Detector: Package for N+1 detection
- Prevent lazy loading:
Model::preventLazyLoading() in development
Solution Strategies:
Eager Loading:
User::with(['posts', 'comments'])->get();
Lazy Eager Loading (conditionally load relations):
$users = User::all();
if ($includeComments) {
$users->load('comments');
}
Chunking (large datasets):
User::with('posts')->chunk(100, function ($users) {
// Process 100 users at a time
});
Caching (frequently accessed data):
Cache::remember('users.all', 3600, function () {
return User::with('posts')->get();
});
Database Optimisation
Indexing:
- Index foreign keys (user_id, post_id)
- Composite indexes for multi-column queries
- Full-text indexes for search
Query Optimisation:
- Select only required columns:
User::select('id', 'name')->get()
- Use
count() instead of get()->count()
- Paginate large result sets:
User::paginate(20)
Caching Layers:
- Query result caching (Redis, Memcached)
- HTTP caching (reverse proxy, CDN)
- OPcache (PHP bytecode caching for 70% boost)
Production Configuration
Laravel Optimisations:
php artisan config:cache # Cache configuration
php artisan route:cache # Cache routes
php artisan view:cache # Cache Blade templates
php artisan event:cache # Cache events
PHP Settings:
- OPcache enabled (opcache.enable=1)
- Realpath cache (realpath_cache_size=4096K)
- Memory limit appropriate for workload
- Max execution time for background jobs