So far in our series, we've set up a high-performance environment with Laravel Octane and Swoole, and we've explored the power of concurrency to run tasks in parallel. These are huge steps, but to build a truly robust and scalable application, we need to master two more areas: advanced data management and observability.
In this article, we'll cover three critical topics:
- Supercharging with the Octane Cache: A blazing-fast, in-memory cache exclusive to Swoole.
- Database Optimization Essentials: Fundamental techniques to prevent your database from becoming a bottleneck.
- Monitoring Your App: An introduction to the tools that give you visibility into your application's health and performance.
Let's get started.
1. Supercharging with the Octane Cache
When using Octane with Swoole, you gain access to an incredibly fast caching driver: Cache::store('octane')
. This isn't just another cache; it's a high-performance, in-memory cache powered by Swoole Tables, capable of handling up to 2 million read/write operations per second.
It's important to understand that this cache is volatile. This means the data is shared across all of Octane's workers, providing incredible speed, but it's lost whenever the server is restarted. It's perfect for caching data that is expensive to compute but can be easily regenerated.
Current Setup Review
Looking at our current codebase, we have two controllers demonstrating the difference between sequential and concurrent execution:
ShowSequentialDashboardController
- runs queries one after anotherShowConcurrentDashboardController
- runs queries in parallel usingOctane::concurrently()
Both controllers currently return simple timing information. Let's enhance them with caching capabilities.
Practical Example: Caching Concurrent Queries with remember()
Let's create a new controller that demonstrates caching with Laravel's remember()
method. This method is brilliant: it checks if a key exists in the cache. If it does, it returns the value. If not, it executes a closure to get the value, stores it in the cache, and then returns it.
First, let's create a new controller for cached dashboard operations:
<?php
namespace App\Http\Controllers;
use App\Models\Event;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Laravel\Octane\Facades\Octane;
use Laravel\Octane\Exceptions\TaskTimeoutException;
use Exception;
class ShowCachedDashboardController extends Controller
{
/**
* Handle the incoming request with caching.
*/
public function __invoke(Request $request)
{
$time = hrtime(true);
try {
// We wrap our entire concurrent operation in a cache block.
[$count, $eventsInfo, $eventsWarning, $eventsAlert] =
Cache::store('octane')->remember(
key: 'dashboard-events-cache', // A unique key for our cache item
ttl: 20, // Time-to-live in seconds
callback: function () {
// This function only runs if the cache is empty or expired.
return Octane::concurrently([
fn() => Event::query()->count(),
fn() => Event::query()->ofType('INFO')->get(),
fn() => Event::query()->ofType('WARNING')->get(),
fn() => Event::query()->ofType('ALERT')->get(),
]);
}
);
} catch (Exception $e) {
// Handle potential exceptions from the cache or concurrent tasks
return 'Error: '.$e->getMessage();
}
$time = (hrtime(true) - $time) / 1_000_000;
return "Fetched from cache in {$time}ms. Count: {$count}, Info: {$eventsInfo->count()}, Warning: {$eventsWarning->count()}, Alert: {$eventsAlert->count()}";
}
}
The first time you load the page associated with this controller, it will run the concurrent queries and take about a second. But for the next 20 seconds, every subsequent page load will be almost instantaneous because the results are being served directly from memory.
A Quick Tip on Cache Configuration: If you ever encounter a Value is too large error when caching, it means you're trying to store more data than the cache is configured to handle. You can easily fix this by increasing the bytes value in your
config/octane.php
file under the cache key. Currently, it's set to 10,000 bytes with 1,000 rows.
2. The Cache-First Architecture with Octane::tick()
The remember()
method is great, but we can take our caching strategy a step further with a powerful, Swoole-only feature: Octane::tick()
. This function allows you to execute a task asynchronously at a regular interval, completely independent of any user requests.
This enables a powerful cache-first architecture. The idea is simple:
- A background ticker is responsible for fetching expensive data and warming the cache.
- Your controllers only ever read data from the cache.
This decouples your user's request from the latency of your data sources. The user experience is always fast because they never have to wait for a slow API or database query.
Why Cache-First Architecture Matters
Traditional request-response cycles look like this:
User Request → Database Query → Processing → Response (slow)
Cache-first architecture transforms this into:
Background: Ticker → Database Query → Cache Storage
User Request → Cache Read → Response (lightning fast!)
Key Benefits:
- Predictable Performance: Users always get consistent, fast responses
- Reduced Database Load: Expensive queries run only when needed, not on every request
- Better Scalability: Can handle thousands of concurrent users without performance degradation
- Improved UX: No waiting for slow queries or external API calls
Step-by-Step Implementation
Step 1: Create the Ticker in a Service Provider
The best place to define a ticker is in the boot()
method of a service provider, like AppServiceProvider
. Let's create a ticker that refreshes our dashboard data every 60 seconds.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
use Laravel\Octane\Facades\Octane;
use App\Models\Event;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
// Only register tickers when using Octane
if (class_exists('Laravel\Octane\Facades\Octane')) {
$this->registerDashboardTicker();
}
}
private function registerDashboardTicker(): void
{
Octane::tick('cache-dashboard-query', function () {
Log::info('Refreshing dashboard cache...');
try {
$result = Octane::concurrently([
'count' => fn() => Event::query()->count(),
'eventsInfo' => fn() => Event::query()->ofType('INFO')->get(),
'eventsWarning' => fn() => Event::query()->ofType('WARNING')->get(),
'eventsAlert' => fn() => Event::query()->ofType('ALERT')->get(),
]);
Cache::store('octane')->put('dashboard-tick-cache', $result, 300); // 5-minute TTL
Log::info('Dashboard cache refreshed successfully');
} catch (Exception $e) {
Log::error('Failed to refresh dashboard cache: ' . $e->getMessage());
}
})
->seconds(60) // Run this task every 60 seconds
->immediate(); // Also run it immediately when the server starts
}
}
Understanding the Ticker Configuration:
->seconds(60)
: The ticker runs every 60 seconds. Choose this interval based on:- How fresh your data needs to be
- How expensive your queries are
- Your server resources
->immediate()
: Runs the ticker immediately when the server starts, ensuring the cache is warm from the beginning- TTL of 300 seconds: Cache lives for 5 minutes, providing a safety buffer if the ticker fails
Advanced Ticker Patterns
1. Multiple Tickers for Different Data:
// In AppServiceProvider.php
Octane::tick('cache-user-stats', function () {
// Update user statistics every 5 minutes
})->seconds(300)->immediate();
Octane::tick('cache-live-data', function () {
// Update live data every 30 seconds
})->seconds(30)->immediate();
2. Error Handling and Fallbacks:
Octane::tick('cache-dashboard-query', function () {
try {
$result = Octane::concurrently([...]);
Cache::store('octane')->put('dashboard-tick-cache', $result, 300);
// Store a "last updated" timestamp
Cache::store('octane')->put('dashboard-last-updated', now(), 300);
} catch (Exception $e) {
Log::error('Ticker failed: ' . $e->getMessage());
// Keep old cache alive longer if refresh fails
Cache::store('octane')->put('dashboard-cache-error', true, 60);
}
});
3. Conditional Ticker Logic:
Octane::tick('smart-cache-refresh', function () {
// Only run expensive operations during low-traffic hours
if (now()->hour >= 2 && now()->hour <= 6) {
// Run expensive data aggregation
$heavyData = performExpensiveCalculation();
Cache::store('octane')->put('heavy-data', $heavyData, 3600);
}
// Always refresh lightweight data
$lightData = Event::query()->count();
Cache::store('octane')->put('light-data', $lightData, 300);
})->seconds(120);
#### Step 2: Create a Controller to Read from the Tick Cache
Now, let's create a controller that reads from our tick-warmed cache:
```php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class ShowTickCachedDashboardController extends Controller
{
/**
* Handle the incoming request using tick-warmed cache.
*/
public function __invoke(Request $request)
{
$time = hrtime(true);
$result = Cache::store('octane')->get('dashboard-tick-cache');
$time = (hrtime(true) - $time) / 1_000_000;
// Provide helpful feedback if cache isn't warmed
if (!$result) {
return "Cache not yet warmed. Please warm it by visiting: /test-ticker";
}
return "Fetched from tick cache in {$time}ms. Count: {$result['count']}, Info: {$result['eventsInfo']->count()}, Warning: {$result['eventsWarning']->count()}, Alert: {$result['eventsAlert']->count()}";
}
}
This controller is incredibly simple and fast because it only reads from the pre-warmed cache—no database queries at all!
With this pattern, your response times can drop to just a few milliseconds, as the heavy lifting is always handled in the background.
Step 3: Manual Cache Warming (Alternative Approach)
While the automatic ticker is ideal for production, during development with Docker and Laravel Sail, you might need to manually warm the cache. We've included practical approaches for this:
Via Test Route (for quick testing):
// Add to routes/web.php
Route::get('/test-ticker', function () {
try {
$result = \Laravel\Octane\Facades\Octane::concurrently([
'count' => fn() => \App\Models\Event::query()->count(),
'eventsInfo' => fn() => \App\Models\Event::query()->ofType('INFO')->get(),
'eventsWarning' => fn() => \App\Models\Event::query()->ofType('WARNING')->get(),
'eventsAlert' => fn() => \App\Models\Event::query()->ofType('ALERT')->get(),
]);
\Illuminate\Support\Facades\Cache::store('octane')->put('dashboard-tick-cache', $result, 300);
return 'Manually triggered ticker logic. Cache warmed successfully!';
} catch (Exception $e) {
return 'Error: ' . $e->getMessage();
}
});
Via Artisan Command (for development workflow):
./vendor/bin/sail artisan dashboard:warm-cache
The command approach is particularly useful during development and can be integrated into deployment scripts or scheduled tasks.
3. Database Optimization Essentials
Even the fastest application server will be crippled by a slow database. Here are some fundamental optimizations every developer should know.
Database Indexing
Looking at our current Event
model and migration, we can see that our queries filter by type
and sort by date
. The current migration in database/migrations/2025_07_14_140014_create_events_table.php
already has an index on user_id
, but we need additional indexes for performance optimization.
Without proper database indexes, your database has to perform a full table scan to find data, which is like reading a book from cover to cover to find one word. An index is like the book's index page—it allows the database to jump directly to the data it needs.
In our dashboard example, our Event
model's ofType
scope filters by type and sorts by date. These are perfect candidates for indexes.
How to Create Additional Indexes:
- Create a new migration:
./vendor/bin/sail artisan make:migration add_indexes_to_events_table
- Define the indexes in the migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('events', function (Blueprint $table) {
$table->index('type');
$table->index('date');
$table->index('description');
// Composite index for type + date queries (most efficient for our ofType scope)
$table->index(['type', 'date']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('events', function (Blueprint $table) {
$table->dropIndex(['events_type_index']);
$table->dropIndex(['events_date_index']);
$table->dropIndex(['events_description_index']);
$table->dropIndex(['events_type_date_index']);
});
}
};
- Run the migration:
./vendor/bin/sail artisan migrate
Adding these indexes can dramatically reduce query times, often turning a multi-second query into one that runs in milliseconds.
Preventing N+1 Queries with Eager Loading
The N+1 query problem is one of the most common performance pitfalls in Laravel. It happens when you loop through a model and access a related model inside the loop.
The Problem (N+1 Queries):
<?php
// This runs 1 query to get all events...
$events = Event::all();
foreach ($events as $event) {
// ...and then N additional queries to get the user for each event.
echo $event->user->name;
}
The Solution (Eager Loading):
By using the with()
method, you can tell Eloquent to fetch all the related models in a single, additional query.
<?php
// This runs only 2 queries, regardless of the number of events.
$events = Event::with('user')->get();
foreach ($events as $event) {
echo $event->user->name;
}
To implement this in our Event model, we need to define the relationship. Let's update our Event model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Event extends Model
{
use HasFactory;
/**
* Get the user that owns the event.
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
/**
* This simulates a complex, time-consuming query.
*/
public function scopeOfType(Builder $query, string $type)
{
sleep(1); // Simulate a 1-second query time
return $query->where('type', $type)
->orderBy('date', 'desc')
->limit(5);
}
}
This simple change from Event::all()
to Event::with('user')->get()
can reduce hundreds of queries to just two.
4. Monitoring & Profiling Your High-Performance App
With a high-performance application, you need the right tools to see what's going on under the hood. Here's a quick guide to the essential monitoring tools for a junior developer.
Laravel Telescope (The Local X-Ray)
Telescope is your best friend for local development. It gives you a beautiful dashboard to inspect incoming requests, database queries, exceptions, queued jobs, and much more. It's perfect for debugging a specific feature and understanding what your application is doing on a request-by-request basis.
Installation:
./vendor/bin/sail composer require laravel/telescope --dev
./vendor/bin/sail artisan telescope:install
./vendor/bin/sail artisan migrate
Laravel Horizon (The Queue Control Tower)
If you're using Redis for your queues (which you should be!), Horizon is an indispensable dashboard for monitoring your queues. It shows you job throughput, runtimes, failures, and worker status, giving you complete control over your background processes.
Installation:
./vendor/bin/sail composer require laravel/horizon
./vendor/bin/sail artisan horizon:install
Swoole Metrics (The Engine Vitals)
For advanced diagnostics, Swoole provides a low-level stats()
method to get raw metrics about the server itself, such as active connections, memory usage, and total requests.
You can create a simple route to view these stats:
<?php
// In routes/web.php
Route::get('/swoole-stats', function () {
if (app()->bound('swoole.server')) {
$server = app('swoole.server');
return response()->json($server->stats());
}
return response()->json(['error' => 'Swoole server not available']);
});
Performance Testing Routes
To test our optimizations, add these routes to routes/web.php
:
<?php
// Performance comparison routes
Route::get('/dashboard-cached', ShowCachedDashboardController::class)
->name('dashboard.cached');
Route::get('/dashboard-tick-cached', ShowTickCachedDashboardController::class)
->name('dashboard.tick-cached');
// Manual cache warming route for testing
Route::get('/test-ticker', function () {
try {
$result = \Laravel\Octane\Facades\Octane::concurrently([
'count' => fn() => \App\Models\Event::query()->count(),
'eventsInfo' => fn() => \App\Models\Event::query()->ofType('INFO')->get(),
'eventsWarning' => fn() => \App\Models\Event::query()->ofType('WARNING')->get(),
'eventsAlert' => fn() => \App\Models\Event::query()->ofType('ALERT')->get(),
]);
\Illuminate\Support\Facades\Cache::store('octane')->put('dashboard-tick-cache', $result, 300);
return 'Manually triggered ticker logic. Cache warmed successfully!';
} catch (Exception $e) {
return 'Error: ' . $e->getMessage();
}
});
What's Next?
We've now covered the complete spectrum of high-performance Laravel development:
- Octane Cache: Ultra-fast, in-memory caching with
Cache::store('octane')
- Cache Strategies: Both reactive (
remember()
) and proactive (tick()
) approaches - Database Indexes: Proper indexing strategies for faster queries
- Eager Loading: Preventing N+1 query problems with
with()
- Monitoring Tools: Telescope, Horizon, and Swoole stats for comprehensive observability
Key Performance Achievements:
- From 3+ seconds (sequential) to <1ms (tick-cached)
- 300x+ performance improvement with proper caching strategies
- Consistent sub-millisecond response times with cache-first architecture
Real-World Applications
These techniques aren't just academic—they solve real problems:
- E-commerce dashboards loading instantly instead of timing out
- Analytics reports pre-computed in background for immediate viewing
- API endpoints serving thousands of requests per second
- User interfaces that feel snappy and responsive
In our final article, we'll tackle deploying our high-performance Laravel application to a production environment with proper configuration, monitoring, and scaling strategies.
Testing Your Implementation
To see the performance differences, follow this step-by-step testing sequence:
Step 1: Test Sequential vs Concurrent
- Visit
/dashboard-sequential
to see sequential execution (~3+ seconds) - Visit
/dashboard-concurrent
to see concurrent execution (~1 second)
Step 2: Test Caching Benefits
- Visit
/dashboard-cached
to see cached concurrent execution (first load ~1 second) - Immediately visit
/dashboard-cached
again (should be <5ms - cached!)
Step 3: Test Cache-First Architecture
- Warm the tick cache by visiting
/test-ticker
first - Visit
/dashboard-tick-cached
to see tick-warmed cache execution (consistently <2ms)
Expected Performance Results:
- Sequential: ~3+ seconds (baseline)
- Concurrent: ~1 second (3x improvement)
- Cached (first load): ~1 second, then <5ms on subsequent loads within 20 seconds
- Tick-cached: Consistently <2ms (after warming with 5-minute cache duration)
Pro Tip for Students:
Try refreshing the cached route multiple times quickly - you'll see the dramatic difference between cache hits and misses when the TTL expires!
Advanced Performance Strategies Beyond Octane
1. Database Query Optimization
Eager Loading to Prevent N+1 Queries:
// ❌ Bad: N+1 query problem
$events = Event::query()->ofType('INFO')->get();
foreach ($events as $event) {
echo $event->user->name; // This triggers a query for each event
}
// ✅ Good: Eager loading
$events = Event::query()->ofType('INFO')->with('user')->get();
foreach ($events as $event) {
echo $event->user->name; // No additional queries
}
Advanced Database Indexing:
// In your migration
Schema::table('events', function (Blueprint $table) {
$table->index(['type', 'created_at']); // Composite index for filtered queries
$table->index('user_id'); // Foreign key index
$table->index('description'); // For full-text searches
// Partial index for specific conditions (PostgreSQL)
$table->index('status')->where('status', '!=', 'archived');
});
2. Advanced Caching Strategies
Cache Tags for Organized Invalidation:
// Tag related data together
Cache::tags(['user', 'events'])->put('user-events-' . $userId, $events, 3600);
// Invalidate all user-related cache when data changes
Cache::tags(['user'])->flush();
Cache Locks to Prevent Cache Stampede:
public function getExpensiveData()
{
return Cache::lock('expensive-calculation', 10)->get(function () {
return Cache::remember('expensive-data', 3600, function () {
return performExpensiveCalculation();
});
});
}
3. Memory and Resource Management
Memory-Efficient Data Processing:
// ❌ Memory intensive: Loads all records at once
$allEvents = Event::all();
// ✅ Memory efficient: Process in chunks
Event::chunk(1000, function ($events) {
foreach ($events as $event) {
// Process each event without memory overflow
}
});
Background Job Processing:
// Offload heavy tasks to queues
ProcessAnalyticsJob::dispatch($analyticsData)
->onQueue('analytics')
->delay(now()->addMinutes(5));
Production Monitoring and Metrics
Application Performance Monitoring (APM)
Laravel Telescope Integration:
composer require laravel/telescope
php artisan telescope:install
php artisan migrate
Custom Performance Tracking:
use Illuminate\Support\Facades\Log;
class DashboardController extends Controller
{
public function index()
{
$startTime = microtime(true);
// Your application logic here
$result = $this->getDashboardData();
$executionTime = (microtime(true) - $startTime) * 1000; // Convert to milliseconds
Log::info('Dashboard performance', [
'execution_time_ms' => round($executionTime, 2),
'cache_hit' => $result['cache_hit'] ?? false,
'memory_usage_mb' => round(memory_get_usage() / 1024 / 1024, 2)
]);
return response()->json($result);
}
}
Key Performance Indicators (KPIs) to Monitor
- Response Time: Target < 200ms for cached responses
- Throughput: Requests per second your application can handle
- Memory Usage: Monitor for memory leaks in long-running processes
- Cache Hit Ratio: Aim for > 90% for frequently accessed data
- Database Query Count: Minimize queries per request
- Error Rate: Keep below 0.1% for production applications
Real-World Production Considerations
Deployment Strategies
Health Checks for Load Balancers:
// routes/web.php
Route::get('/health', function () {
return response()->json([
'status' => 'healthy',
'octane' => extension_loaded('swoole'),
'cache' => Cache::store('octane')->get('health-check', 'ok'),
'database' => DB::connection()->getPdo() ? 'connected' : 'disconnected',
'memory_usage' => round(memory_get_usage() / 1024 / 1024, 2) . 'MB',
'timestamp' => now()->toISOString()
]);
});
Environment-Specific Configurations:
// config/octane.php - Production optimizations
return [
'workers' => env('OCTANE_WORKERS', 4), // Set based on CPU cores
'task_workers' => env('OCTANE_TASK_WORKERS', 6),
'max_requests' => 1000, // Restart workers after X requests
'cache' => [
'rows' => 1000, // Increase for production
'bytes' => 10000,
],
'tables' => [
'example:1000', // Swoole table for shared data
],
];
Scaling Strategies
Horizontal Scaling with Multiple Instances:
# docker-compose.prod.yml
version: "3.8"
services:
app-1:
build: .
environment:
- OCTANE_WORKERS=4
ports:
- "8001:8000"
app-2:
build: .
environment:
- OCTANE_WORKERS=4
ports:
- "8002:8000"
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
Redis for Shared Cache Across Instances:
// config/cache.php
'stores' => [
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
'lock_connection' => 'default',
],
],
Conclusion: Your High-Performance Laravel Journey
Throughout this comprehensive guide, we've transformed a simple Laravel application from basic sequential queries to a high-performance, cache-optimized powerhouse. Here's what we accomplished:
Performance Transformation Summary
Strategy | Response Time | Improvement Factor |
---|---|---|
Sequential Queries | ~3+ seconds | Baseline |
Concurrent Queries | ~1 second | 3x faster |
Cache + Concurrent | <5ms | 600x faster |
Tick Cache (Cache-First) | <1ms | 3000x faster |
Key Learning Outcomes for Junior Developers
🎯 Technical Skills Gained:
- Octane Integration: Understanding how to properly set up and configure Laravel Octane with Swoole
- Concurrent Programming: Using
Octane::concurrently()
for parallel database operations - Advanced Caching: Implementing both reactive (
remember()
) and proactive (tick()
) caching strategies - Database Optimization: Creating indexes and preventing N+1 queries
- Performance Monitoring: Setting up proper metrics and logging
🔧 Development Best Practices:
- Always measure before optimizing
- Understand your bottlenecks through profiling
- Choose the right caching strategy for your use case
- Monitor performance continuously in production
- Think about the entire request lifecycle
Next Steps in Your Learning Journey
- Experiment with Your Own Projects: Apply these concepts to real applications
- Explore Advanced Swoole Features: Dive into coroutines, connection pooling, and async I/O
- Study Production Systems: Learn about load balancing, auto-scaling, and monitoring
- Contribute to Open Source: Share your optimizations with the Laravel community
Real-World Impact
These performance improvements aren't just numbers—they translate to:
- Better User Experience: Sub-second page loads keep users engaged
- Reduced Infrastructure Costs: Handle more traffic with fewer servers
- Improved SEO Rankings: Faster sites rank higher in search results
- Higher Conversion Rates: Every 100ms improvement can increase conversions
Final Thoughts
High-performance web applications are built through understanding, measurement, and incremental improvement. The techniques you've learned here—from basic concurrent queries to sophisticated cache-first architectures—form the foundation of modern, scalable web applications.
Remember: Performance optimization is a journey, not a destination. Keep learning, keep measuring, and keep improving!
Happy coding, and may your applications be fast and your databases be optimized! 🚀
This post is part of our High-Performance Laravel series for junior developers. Follow us for more advanced Laravel techniques, performance tips, and best practices.
Works cited
- What Is Laravel Octane? - How It Works & Benchmarks - Redberry International, accessed July 13, 2025, https://redberry.international/what-is-octane-in-laravel-things-to-know/
- Upgrading Web App Performance With Laravel Octane Features - Pattem Digital, accessed July 13, 2025, https://pattemdigital.com/insight/laravel-octane-for-your-web-apps/
- Free Performance + Extra features for Laravel using Octane and Swoole | AriaieBOY Blog, accessed July 13, 2025, https://ariaieboy.ir/blog/10-free-performance-using-laravel-octane-and-swoole/
- High Performance with Laravel Octane - Roberto Butti, accessed July 13, 2025, https://subscription.packtpub.com
- Laravel Octane - What It Is, Why It Matters & Getting Started - RunCloud, accessed July 13, 2025, https://runcloud.io/blog/laravel-octane
- A Quick Guide on using Laravel Octane to Scale Your App - Bacancy Technology, accessed July 13, 2025, https://www.bacancytechnology.com/blog/laravel-octane
- Laravel with(): How to Solve the N+1 Problem with Eager Loading Relationships | Fajarwz, accessed July 13, 2025, https://fajarwz.com/blog/laravel-with-how-to-solve-the-n+1-problem-with-eager-loading-relationships/
- Preventing N+1 issues globally in Laravel using Auto Eager Loading - Amit Merchant, accessed July 13, 2025, https://www.amitmerchant.com/laravel-auto-eager-loading/
- How to Force Eager Loading and Prevent N+1 Issues in Laravel - Ash Allen Design, accessed July 13, 2025, https://ashallendesign.co.uk/blog/how-to-force-eager-loading-and-prevent-n-1-issues-in-laravel
- N+1 Query Problem in Laravel: Causes, Effects, and Solutions | by Moumen Alisawe, accessed July 13, 2025, https://medium.com/@moumenalisawe/n-1-query-problem-in-laravel-causes-effects-and-solutions-740cefa44306
- Using Laravel Octane for High-Performance Applications - 200OK Solutions, accessed July 13, 2025, https://200oksolutions.com/blog/using-laravel-octane-high-performance-applications/
- Laravel Telescope - Laravel 12.x - The PHP Framework For Web Artisans, accessed July 13, 2025, https://laravel.com/docs/12.x/telescope
- How to Set up and Configure Telescope in Laravel - Interserver Tips, accessed July 13, 2025, https://www.interserver.net/tips/kb/how-to-set-up-and-configure-telescope-in-laravel/
- Laravel 12 Telescope: Installation & Configuration Tutorial - YouTube, accessed July 13, 2025, https://www.youtube.com/watch?v=HiLqvouwkYs
- Setup and Configure Telescope in Laravel - YouTube, accessed July 13, 2025, https://www.youtube.com/watch?v=nsLNLDsjcxo
- Laravel Horizon - Laravel 12.x - The PHP Framework For Web Artisans, accessed July 13, 2025, https://laravel.com/docs/12.x/horizon