# System Page Caching - Database-Backed Status Cache ## Problem The admin system page (`/admin/system.php`) runs expensive operations on every load: - `systemctl` subprocess calls (~4 checks × ~100ms each) - `curl` HTTP self-check (~200-500ms) - `disk_total_space()`/`disk_free_space()` (fast but unnecessary per-request) - Log file `tail` + `filesize` + `filemtime` (I/O bound) - Nginx config file reading ## Solution: `system_cache` table + background refresh - [x] **Add `system_cache` table** to schema: `CREATE TABLE system_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at INTEGER NOT NULL)` - [x] **Add migration** `storage/migrations/007_system_cache.sql` - [x] **Add `SystemCache` class** (`src/SystemCache.php`) with methods: - `get(string $key, int $maxAgeSec = 60): ?array` - `set(string $key, array $data): void` - `isStale(string $key, int $maxAgeSec = 60): bool` - [x] **Refactor `system.php` status section**: 1. Check `SystemCache::get('system_status', 120)` — 2-minute TTL 2. If cache hit → render from cache, show “mis en cache il y a X sec” label 3. If cache miss → run checks, store in cache, render 4. Add `?refresh=1` GET param to force-bypass cache - [x] **Refactor `system.php` log sections** — avoid re-reading on every tab switch; only read the active tab’s log - [x] **Cache disk info** separately with 5-minute TTL: `SystemCache::get('disk_info', 300)` - [x] **Cache PHP info** separately with 1-hour TTL: `SystemCache::get('php_info', 3600)` ## Notes - Log caching deliberately omitted: `tail` output is inherently real-time and caching even 30s would show stale data during the moments it matters most (deploys, errors). The existing tab guard already ensures only the active log file is read. - nginx config could be cached but `file()` on a small static config file is negligible; not worth the added complexity. - A future improvement could stream log tabs via `fetch()` to avoid full-page reloads on tab switch.