check-caching-strategy

Analyzes PHP code for caching opportunities and issues. Detects missing cache, cache invalidation problems, over-caching, repeated expensive operations.

dykyi-roman/awesome-claude-code7 installsMITSynced Aug 22

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: check-caching-strategy
description: Analyzes PHP code for caching opportunities and issues. Detects missing cache, cache invalidation problems, over-caching, repeated expensive operations.
license: MIT
---

# Caching Strategy Analysis

Analyze PHP code for caching opportunities and issues.

## Detection Patterns

### 1. Missing Cache Opportunities

```php
// CACHEABLE: Repeated expensive computation
public function getExchangeRate(string $currency): float
{
    return $this->api->fetchRate($currency); // API call each time
}

// CACHEABLE: Repeated database query
public function getSettings(): array
{
    return $this->repository->findAll(); // Same query repeatedly
}

// CACHEABLE: Configuration that rarely changes
public function getFeatureFlags(): array
{
    return $this->configLoader->load(); // File read each request
}
```

### 2. Cache Invalidation Issues

```php
// STALE DATA: No invalidation
$cache->set('user_' . $id, $user, 3600);
// Later: user updated but cache not cleared

// STALE DATA: Time-based only
$cache->set('products', $products, 86400);
// Products change but cache lives for 24h

// RACE CONDITION: Invalidate before update
$this->cache->delete('user_' . $id);
$this->repository->update($user);
// Another request may cache old data between these lines
```

### 3. Over-Caching

```php
// OVER-CACHED: User-specific data with long TTL
$cache->set('user_dashboard_' . $userId, $data, 86400);
// User dashboard may need fresh data

// OVER-CACHED: Rapidly changing data
$cache->set('stock_count_' . $productId, $count, 3600);
// Stock changes frequently

// OVER-CACHED: Huge cache entries
$cache->set('all_products', $allProducts); // 10MB cache entry
```

### 4. Cache Stampede

```php
// STAMPEDE: Many requests rebuild cache simultaneously
public function getData(): array
{
    $data = $this->cache->get('key');
    if (!$data) {
        $data = $this->expensiveOperation(); // All concurrent requests hit this
        $this->cache->set('key', $data, 3600);
    }
    return $data;
}

// FIXED: Lock during rebuild
public function getData(): array
{
    $data = $this->cache->get('key');
    if (!$data) {
        $lock = $this->lockFactory->createLock('key_rebuild');
        if ($lock->acquire()) {
            $data = $this->expensiveOperation();
            $this->cache->set('key', $data, 3600);
            $lock->release();
        } else {
            $data = $this->cache->get('key'); // Wait for other process
        }
    }
    return $data;
}
```

### 5. Wrong Cache Key

```php
// BAD: Missing important parameters
$cache->get('user_data'); // Same for all users?

// BAD: Too specific
$cache->get('user_' . $id . '_' . $requestId); // Never hits

// BAD: Collision risk
$cache->get(md5($query)); // Different queries may collide

// GOOD: Meaningful, unique key
$cache->get(sprintf('user:%d:profile:v1', $userId));
```

### 6. Cache Storage Issues

```php
// PROBLEM: Storing large objects
$cache->set('report', $largeReport); // 50MB serialized

// PROBLEM: Storing non-serializable
$cache->set('connection', $pdoConnection); // Can't serialize

// PROBLEM: Storing closures
$cache->set('callback', function() { }); // Fails
```

### 7. TTL Issues

```php
// TOO SHORT: Cache overhead exceeds benefit
$cache->set('data', $data, 1); // 1 second TTL

// TOO LONG: Stale data risk
$cache->set('exchange_rates', $rates, 604800); // 1 week

// NO TTL: Memory leak risk
$cache->set('data', $data); // Never expires

// FIXED: Appropriate TTL
$cache->set('exchange_rates', $rates, 300); // 5 minutes
```

### 8. Cache Warming

```php
// COLD START: First request is slow
// No warming strategy, first user waits

// BETTER: Warm cache on deploy/schedule
public function warmCache(): void
{
    $this->cache->set('config', $this->loadConfig());
    $this->cache->set('categories', $this->loadCategories());
}
```

## Grep Patterns

```bash
# API calls without cache
Grep: "->request\(|->get\(|->fetch\(" --glob "**/*.php"

# Repository calls that could be cached
Grep: "Repository->find|Repository->get" --glob "**/*.php"

# Cache operations
Grep: "->cache->|Cache::|redis->|memcache" --glob "**/*.php"

# Missing TTL
Grep: "->set\([^,]+,[^,]+\)\s*;" --glob "**/*.php"
```

## Caching Patterns

### Read-Through Cache

```php
public function get(string $key, callable $loader, int $ttl = 3600): mixed
{
    $value = $this->cache->get($key);
    if ($value === null) {
        $value = $loader();
        $this->cache->set($key, $value, $ttl);
    }
    return $value;
}
```

### Write-Through Cache

```php
public function update(Entity $entity): void
{
    $this->repository->save($entity);
    $this->cache->set('entity:' . $entity->getId(), $entity);
}
```

### Cache-Aside with Locking

```php
public function getWithLock(string $key, callable $loader): mixed
{
    $value = $this->cache->get($key);
    if ($value !== null) {
        return $value;
    }

    $lock = $this->lockFactory->createLock($key);
    if ($lock->acquire()) {
        try {
            $value = $loader();
            $this->cache->set($key, $value);
        } finally {
            $lock->release();
        }
    } else {
        usleep(100000);
        return $this->getWithLock($key, $loader);
    }
    return $value;
}
```

## Severity Classification

| Pattern | Severity |
|---------|----------|
| Cache stampede risk | πŸ”΄ Critical |
| Missing invalidation | 🟠 Major |
| Missing cache for hot path | 🟠 Major |
| Wrong cache key | 🟠 Major |
| Overly long TTL | 🟑 Minor |
| Over-caching user data | 🟑 Minor |

## Output Format

```markdown
### Caching Issue: [Description]

**Severity:** πŸ”΄/🟠/🟑
**Location:** `file.php:line`
**Type:** [Missing Cache|Invalidation|Stampede|...]

**Issue:**
[Description of the caching problem]

**Code:**
```php
// Current code
```

**Fix:**
```php
// With proper caching
```

**Expected Improvement:**
Response time: 500ms β†’ 5ms (on cache hit)
Database load: 1000 QPS β†’ 100 QPS
```

## When This Is Acceptable

- **Premature caching** β€” Adding cache before proving a performance bottleneck exists creates complexity without benefit
- **Frequently changing data** β€” Data that changes on every request (e.g., real-time prices) shouldn't be cached
- **Development environment** β€” Missing cache in dev/test environments is intentional

### False Positive Indicators
- Code is in early development stage without performance profiling
- Data has TTL < 1 second or changes per-request
- Cache is disabled by environment configuration (dev/test)

More Performance skills

seo-audit

coreyhaines31/marketingskills

When the user wants to audit, review, or diagnose SEO issues on their site. Also use when the user mentions "SEO audit," "technical SEO," "why am I not ranking," "SEO issues," "on-page SEO," "meta tags review," "SEO health check," "my traffic dropped," "lost rankings," "not showing up in Google," "site isn't ranking," "Google update hit me," "page speed," "core web vitals," "crawl errors," or "indexing issues." Use this even if the user just says something vague like "my SEO is bad" or "help with SEO" β€” start with an audit. For building pages at scale to target keywords, see programmatic-seo. For adding structured data, see schema. For AI search optimization, see ai-seo.

195.1k

competitor-profiling

coreyhaines31/marketingskills

When the user wants to research, profile, or analyze competitors from their URLs. Also use when the user mentions 'competitor profile,' 'competitor research,' 'competitor analysis,' 'profile this competitor,' 'analyze competitor,' 'competitive intelligence,' 'competitor deep dive,' 'who are my competitors,' 'competitor landscape,' 'competitor dossier,' 'competitive audit,' or 'research these competitors.' Input is a list of competitor URLs. Output is structured competitor profile markdown files. For creating comparison/alternative pages from profiles, see competitors. For sales-specific battle cards, see sales-enablement.

65.8k

vercel-optimize

vercel-labs/agent-skills

Use for Vercel cost and performance optimization on deployed projects, especially Next.js, SvelteKit, Nuxt, and limited Astro apps. Collect Vercel metrics, usage, project config, and code scan results first; investigate only metric-backed candidates; produce ranked recommendations grounded in verified files and version-aware Vercel/framework docs. Trigger for Vercel bill reduction, slow or expensive routes, caching opportunities, Function Invocations, Build Minutes, Fast Data Transfer, Core Web Vitals, Bot Management, Fluid compute, or cost breakdown requests.

59.3k

← All Performance skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free Β· No signup Β· No trial clock

SEE THE DIRECTORY