ArtisanPack UI
DocsSEOCaching

Caching

SEO v1.3.0

ArtisanPack UI SEO implements comprehensive caching to optimize performance. This guide covers cache configuration, usage, and management. The package...

ArtisanPack UI SEO implements comprehensive caching to optimize performance. This guide covers cache configuration, usage, and management.

Overview

The package caches:

  • SEO meta data for models
  • SEO analysis results
  • Redirect lookups
  • Sitemap content
  • Robots.txt content

Configuration

// In config/seo.php
'cache' => [
    'enabled' => true,
    'ttl' => 3600,          // 1 hour default
    'driver' => null,       // null = default driver
    'prefix' => 'seo',
],

Feature-Specific Caching

Each feature has its own cache settings:

'redirects' => [
    'cache_enabled' => true,
    'cache_ttl' => 86400,   // 24 hours
],

'sitemap' => [
    'cache_enabled' => true,
    'cache_ttl' => 3600,    // 1 hour
],

'analysis' => [
    'cache_enabled' => true,
    'cache_ttl' => 86400,   // 24 hours
],

Cache Service

Access

use ArtisanPackUI\Seo\Services\CacheService;

$cacheService = app('seo.cache');

Methods

// Get cached value
$value = $cacheService->get('meta', $model->id);

// Set cached value
$cacheService->set('meta', $model->id, $data, 3600);

// Check if cached
$exists = $cacheService->has('meta', $model->id);

// Remove from cache
$cacheService->forget('meta', $model->id);

// Clear all caches for a model
$cacheService->clearAllForModel($model);

// Clear all SEO caches
$cacheService->flush();

// Get cache key
$key = $cacheService->key('meta', $model->id);
// Returns: "seo_meta_123"

Cache Keys

The package uses structured cache keys:

Type Key Pattern Example
Meta seo_meta_{id} seo_meta_42
Analysis seo_analysis_{id} seo_analysis_42
Redirect seo_redirect_{path} seo_redirect_/old-page
Sitemap seo_sitemap_{type} seo_sitemap_standard
Robots seo_robots seo_robots

Automatic Cache Invalidation

The package automatically clears relevant caches when:

Model Events

// When model is updated
$post->update(['title' => 'New Title']);
// → Clears: seo_meta_42, seo_analysis_42

// When SEO meta is updated
$post->updateSeoMeta(['meta_title' => 'New']);
// → Clears: seo_meta_42

// When model is deleted
$post->delete();
// → Clears all related caches

Redirect Events

// When redirect is created/updated/deleted
Redirect::create([...]);
// → Clears: seo_redirect_*

Sitemap Regeneration

// When sitemap is regenerated
app('seo.sitemap')->generate();
// → Clears: seo_sitemap_*

Manual Cache Clearing

Using Service

$cacheService = app('seo.cache');

// Clear specific cache type
$cacheService->forget('meta', $post->id);
$cacheService->forget('analysis', $post->id);

// Clear all caches for model
$cacheService->clearForModel($post);

// Flush all SEO caches
$cacheService->flush();

Using Artisan

# Clear all SEO caches
php artisan seo:clear-cache

# Clear specific type
php artisan seo:clear-cache --type=redirects
php artisan seo:clear-cache --type=sitemaps
php artisan seo:clear-cache --type=analysis

Cache Drivers

'cache' => [
    'driver' => 'redis',
],

Using File Cache

'cache' => [
    'driver' => 'file',
],

Using Database Cache

'cache' => [
    'driver' => 'database',
],

Using Array (Testing)

'cache' => [
    'driver' => 'array',
],

Cache Tags

If using a driver that supports tags (Redis, Memcached):

// The package uses these tags internally
'seo:meta'
'seo:analysis'
'seo:redirects'
'seo:sitemaps'

// Clear by tag
Cache::tags('seo:meta')->flush();
Cache::tags('seo:analysis')->flush();

Warming the Cache

The package provides seo:generate-sitemap and seo:submit-sitemap commands, but cache warming is application-specific. Create a custom command to warm your SEO caches:

Custom Warm Command

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Post;

class WarmSeoCache extends Command
{
    protected $signature = 'seo:warm-cache';

    public function handle(): void
    {
        // Warm meta cache
        Post::chunk(100, function ($posts) {
            foreach ($posts as $post) {
                $post->getSeoData(); // Triggers caching
            }
        });

        // Warm sitemap cache
        app('seo.sitemap')->generate();

        // Warm analysis cache
        Post::chunk(100, function ($posts) {
            foreach ($posts as $post) {
                app('seo.analysis')->analyze($post);
            }
        });

        $this->info('SEO cache warmed.');
    }
}

On Deployment

After creating the custom command above, use it in deployment scripts:

// In a deployment script or command
Artisan::call('seo:warm-cache');

Disabling Caching

Globally

'cache' => [
    'enabled' => false,
],

Per Feature

'redirects' => [
    'cache_enabled' => false,
],

'sitemap' => [
    'cache_enabled' => false,
],

Temporarily

To bypass caching for a single operation, call the data method directly or temporarily disable caching:

// Option 1: Disable caching temporarily via config
config(['seo.cache.enabled' => false]);
$data = $post->getSeoData();
config(['seo.cache.enabled' => true]);

// Option 2: Clear cache before fetching fresh data
$cacheService->clearAllForModel($post);
$data = $post->getSeoData();

Cache Performance Tips

1. Use Redis in Production

'cache' => [
    'driver' => 'redis',
],

2. Set Appropriate TTLs

// Frequently changing data
'redirects' => [
    'cache_ttl' => 3600, // 1 hour
],

// Rarely changing data
'sitemap' => [
    'cache_ttl' => 86400, // 24 hours
],

3. Warm Cache After Bulk Operations

// After bulk import
Post::chunk(100, function ($posts) {
    foreach ($posts as $post) {
        $post->getSeoData();
    }
});

4. Use Cache Tags for Selective Clearing

// Clear only redirect cache after bulk redirect import
Cache::tags('seo:redirects')->flush();

Monitoring Cache

Cache Hit Rate

Monitor your cache hit rate to ensure effectiveness. Use Laravel's built-in cache debugging:

// Use Laravel's Cache spy in tests
Cache::spy();

// Or add custom event listeners for cache hits/misses
Event::listen('cache.hit', fn ($key) => Log::debug("Cache hit: {$key}"));
Event::listen('cache.missed', fn ($key) => Log::debug("Cache miss: {$key}"));

Cache Size

For Redis:

redis-cli info memory

Events

use ArtisanPackUI\Seo\Events\SeoCacheCleared;

Event::listen(SeoCacheCleared::class, function ($event) {
    Log::info('SEO cache cleared', [
        'model' => $event->model,
        'keys' => $event->keys,
    ]);
});

Next Steps