Cache Implementation Plan
Overview
This folder contains comprehensive documentation for implementing an advanced caching system with cross-server cache invalidation between the content management server and API server.
Documents
0-OCTOBER-CMS-ARTIFACTS-REPORT.md
Summary: Analysis of October CMS plugin artifacts remaining in the codebase.
Key Findings:
- 19 references to
imc.gapnamespace (all functional with view namespace) - Mail templates migrated to Laravel Blade
- Config reference fixed (
config('services.recaptcha.secret')) - Vue component paths accessible via .htaccess
- Status: ✅ All issues resolved
1-API-SERVER-IMPLEMENTATION.md
Summary: Implementation guide for the API server (api.testing.getubetter.com).
Key Features:
- Enhanced
GapCacheclass with Redis pattern-based cache clearing - Cache invalidation API endpoints (clear by pattern, model, or batch)
- Pulse configuration for slow query (>200ms) and endpoint (>500ms) tracking
- Custom middleware for detailed slow request logging
- Response caching strategies with TTL optimization
Implementation Phases:
- Enhanced GapCache (Week 1)
- Cache Management API (Week 1)
- Performance Monitoring (Week 2)
- Response Caching (Week 2-3)
- Testing & Documentation (Week 3)
Performance Targets:
- Average response time: <100ms (cached)
- Slow endpoints: <500ms (uncached)
- Cache hit ratio: >80%
2-CONTENT-SERVER-IMPLEMENTATION.md
Summary: Implementation guide for the content management server (testing.getubetter.com).
Key Features:
- Model observers with trait
InvalidatesCacheOnChange - Async job queue for cache invalidation (non-blocking)
- HTTP client service for cross-server communication
- Configurable model-to-cache-pattern mappings
- Rollback plan for safety
Models to Observe:
- Webform
- Pathway
- Condition
- Smodule
- Gatewaypage
- Organisation
Implementation Phases:
- Configuration (Day 1)
- Service Layer (Day 2)
- Job & Queue (Day 3)
- Observers (Day 4-5)
- Testing (Day 6-7)
- Monitoring (Ongoing)
Critical Notes:
- ⚠️ Content server is IN PRODUCTION USE
- All changes must be backward compatible
- Thorough testing required before deployment
- Rollback plan ready
Quick Start
API Server Setup
# 1. Verify testing_logs database exists
mysql -u main -p'DevIMC2013!@' -e "SHOW DATABASES LIKE 'testing_logs';"
# 2. Check migrations ran
mysql -u main -p'DevIMC2013!@' testing_logs -e "SHOW TABLES;"
# 3. Verify Pulse configuration
grep "PULSE_" /var/www/api.testing/.env
# 4. Access Pulse dashboard
curl -H "Authorization: Bearer {JWT_TOKEN}" https://api.testing.getubetter.com/pulse
Content Server Setup (NOT DONE YET)
# 1. Add configuration to .env
vim /var/www/testing/.env
# Add CACHE_INVALIDATION_* variables
# 2. Create CacheInvalidationService class
# See 2-CONTENT-SERVER-IMPLEMENTATION.md Section 3
# 3. Create InvalidateApiCache job
# See 2-CONTENT-SERVER-IMPLEMENTATION.md Section 4
# 4. Add trait to models
# See 2-CONTENT-SERVER-IMPLEMENTATION.md Section 5
# 5. Test with a single model first
# Update a Webform and check logs
Architecture Diagram
┌─────────────────────────────────────────────────────────────┐
│ Content Management Server │
│ (testing.getubetter.com) │
│ Laravel 9 + October CMS │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. User Updates Content (Webform, Pathway, etc.) │
│ ↓ │
│ 2. Model Observer Fires (InvalidatesCacheOnChange trait) │
│ ↓ │
│ 3. Async Job Dispatched (InvalidateApiCache) │
│ ↓ │
│ 4. HTTP POST to API Server │
│ POST /api/admin/cache/clear-model │
│ {"model": "webform", "id": 123} │
│ │
└─────────────────────┬───────────────────────────────────────┘
│
│ HTTP/HTTPS
│
┌─────────────────────▼───────────────────────────────────────┐
│ API Server │
│ (api.testing.getubetter.com) │
│ Laravel 12 + Octane │
├─────────────────────────────────────────────────────────────┤
│ │
│ 5. CacheManagementController receives request │
│ ↓ │
│ 6. GapCache::deletePattern("webform:123") │
│ ↓ │
│ 7. Redis SCAN for matching keys │
│ ↓ │
│ 8. Delete matched cache keys │
│ ↓ │
│ 9. Return success response │
│ {"success": true, "keys_deleted": 8} │
│ │
│ Meanwhile: │
│ - Pulse tracks slow queries (>200ms) │
│ - Pulse tracks slow endpoints (>500ms) │
│ - Middleware logs detailed slow request data │
│ - All logged to testing_logs database │
│ │
└─────────────────────────────────────────────────────────────┘
Cache Key Patterns
Webforms
webform:{id}- Single webform datawebform:*- All webforms
Pathways
pathway:{id}:*- All pathway-related cachepathway_gateways_{id}pathway_labels_{id}pathway_timeline_intervals_{id}pathway_textboxes_{id}
Accesscodes
accesscode:{id}:*- All accesscode cacheaccesscode_today_attr_{id}accesscode_helpsections_{id}accesscode_feedbackzone_{id}accesscode_pathway_smodules_{id}accesscode_appointments_{id}accesscode_programs_{id}accesscode_diary_{id}accesscode_visitedpages_{id}accesscode_painhistory_{id}accesscode_completed_gateways_{id}
Conditions
condition_labels_{id}condition_infozones_{id}condition_smodules_{id}
Database Structure
Main Database: testing_api (MySQL)
- Application data (users, pathways, webforms, etc.)
- Session data
- Queue jobs
Logs Database: testing_logs (MySQL)
- Telescope entries (debugging)
- Pulse metrics (performance)
- Request history
- Slow query logs
- Exception logs
Cache: Redis
- Cache prefix:
testing_api_ - Pattern-based keys for easy clearing
- TTL varies by data type (5 min to 30 days)
Performance Monitoring
Pulse Dashboard Metrics
- Slow Queries: >200ms
- Slow Requests: >500ms
- User Requests: Track which users trigger slow operations
- Exceptions: All errors with stack traces
- Cache: Hit/miss ratios
Custom Slow Request Logging
Middleware logs additional context for requests >500ms:
- Full URL and query params
- User ID and IP
- Request body size
- Response status
- Memory peak usage
- Timestamp
Security
API Authentication
- JWT token required for cache management endpoints
- Admin role required
- Rate limiting recommended
Logging
- All cache invalidation attempts logged
- Failed attempts logged with reason
- User context included when available
Monitoring & Alerts
What to Monitor
- Queue Length: Should be <100 most of the time
- Failed Jobs: Should be rare, investigate immediately
- Cache Hit Ratio: Target >80%
- API Response Times: Target <500ms for 95th percentile
- Redis Memory: Monitor for excessive growth
Where to Look
- Pulse Dashboard: https://api.testing.getubetter.com/pulse
- Telescope Dashboard: https://api.testing.getubetter.com/telescope
- Logs:
/var/www/api.testing/storage/logs/ - Redis:
redis-cli INFO stats
Troubleshooting
Cache Not Clearing
- Check content server logs:
tail -f /var/www/testing/storage/logs/system.log - Check queue worker:
systemctl status laravel-queue-cache-invalidation - Check API server logs:
tail -f /var/www/api.testing/storage/logs/laravel.log - Test manually:
curl -X POST https://api.testing.getubetter.com/api/admin/cache/clear-pattern -H "Authorization: Bearer {TOKEN}" -d '{"pattern":"webform:*"}'
Slow Queries Not Showing
- Verify Pulse enabled:
grep "PULSE_SLOW_QUERIES" /var/www/api.testing/.env - Check threshold: Should be 200 (ms)
- Access Pulse dashboard: https://api.testing.getubetter.com/pulse
- Check testing_logs database:
mysql -u main -p testing_logs -e "SELECT COUNT(*) FROM pulse_entries;"
Queue Not Processing
- Check worker status:
systemctl status laravel-queue-cache-invalidation - Check for stuck jobs:
php artisan queue:failed - Restart worker:
systemctl restart laravel-queue-cache-invalidation - Monitor in real-time:
php artisan queue:work redis --queue=cache-invalidation -vvv
Testing Checklist
API Server Tests
- Pattern-based cache clearing works
- Batch clearing works
- Health endpoint returns correct info
- Authentication required for endpoints
- Slow queries appear in Pulse (>200ms)
- Slow requests appear in Pulse (>500ms)
- Middleware logs slow requests
Content Server Tests (when implemented)
- Observer fires on model create
- Observer fires on model update
- Observer fires on model delete
- Job dispatched to queue
- Job processes successfully
- HTTP request reaches API server
- Cache cleared on API server
- No blocking during content save
Next Steps
Immediate (Completed ✅)
- ✅ Create testing_logs database
- ✅ Configure Telescope/Pulse for separate DB
- ✅ Add Pulse slow query/request tracking
- ✅ Add NHS and Recaptcha configuration
- ✅ Fix October CMS artifact references
- ✅ Document implementation plans
Short Term (This Week)
- Implement enhanced GapCache on API server
- Create CacheManagementController
- Add cache management routes
- Test pattern-based cache clearing
- Create TrackSlowRequests middleware
Medium Term (Next 1-2 Weeks)
- Implement CacheInvalidationService on content server
- Create InvalidateApiCache job
- Add InvalidatesCacheOnChange trait
- Apply trait to models (one by one)
- Test cross-server cache invalidation
- Set up queue worker service
Long Term (Next Month)
- Identify and cache expensive endpoints
- Optimize cache TTLs based on usage
- Performance benchmarking
- Documentation for team
- Monitoring dashboard setup
Resources
Documentation
Internal Docs
Contact
For questions or issues with this implementation:
- Review this documentation
- Check logs (see Monitoring & Alerts section)
- Test endpoints manually (see Troubleshooting section)
- Review Pulse/Telescope dashboards
Last Updated: January 14, 2026 Status: Documentation Complete, Implementation Pending