Client Area

Server-Side Caching on DomainIndia: Redis, Memcached, Varnish, and OPcache

ByDomain India Team·DomainIndia Engineering
6 min read24 Apr 20263 views
# Server-Side Caching on DomainIndia: Redis, Memcached, Varnish, and OPcache
TL;DR
Caching turns a 500ms database query into a 1ms memory lookup. This guide covers the four server-side caching layers you should understand — OPcache (PHP bytecode), Memcached/Redis (data cache), Varnish (HTTP response cache) — and when to use each on DomainIndia hosting.
## The four caching layers Your web stack has four places to cache, from fastest to slowest:
LayerCachesRead timeWhere
OPcachePHP bytecode<0.01 msBuilt into PHP, on every plan
APCuPHP user data (in-process)<0.1 msPHP extension, usually enabled
Redis / MemcachedAny data (across processes)0.5–1 msSeparate process, shared
Varnish / CloudflareFull HTTP responses5–20 ms (cache hit)In front of your app
Use all of them together for a well-tuned stack. ## Layer 1 — OPcache (PHP) PHP compiles every file to bytecode on every request. OPcache stores the compiled version in memory so PHP skips parsing. **Impact:** 2–3× speedup on PHP apps. Non-negotiable on production. On DomainIndia cPanel/DirectAdmin, OPcache is **enabled by default** on PHP 7.4+. Verify via `php -i | grep opcache.enable` → `Opcache.enable => On`. Tuning (in cPanel → MultiPHP INI Editor, or `.user.ini`): ```ini opcache.enable=1 opcache.memory_consumption=256 ; MB — more = more files cached opcache.max_accelerated_files=20000 ; number of PHP files opcache.validate_timestamps=1 ; check file changes (set 0 in production + release restart) opcache.revalidate_freq=2 ; seconds between checks opcache.jit=1255 ; PHP 8+ JIT (tracing mode) opcache.jit_buffer_size=64M ``` For Laravel/Symfony deployments: run `php artisan opcache:clear` (or similar) in deploy hook — otherwise OPcache serves old bytecode. See our [PHP OPcache Configuration article](https://domainindia.com/support/kb/php-opcache-guide) for deep details. ## Layer 2 — APCu In-memory key-value cache local to each PHP process. Good for small hot data — feature flags, config arrays, rate-limit counters. ```php apcu_store('flag_new_checkout', true, 300); // 300s TTL if (apcu_fetch('flag_new_checkout')) { /* new checkout */ } ``` Limits: - Not shared across servers / across PHP-FPM pools cleanly - Cleared on PHP-FPM reload - Memory bound per-process For shared-across-server caching, use Redis/Memcached instead. ## Layer 3 — Redis or Memcached External in-memory store. Multi-process, multi-server, persistent (Redis). **On DomainIndia hosting:**
PlanRedis available?Memcached available?
Shared cPanelYes (local socket, shared instance)Yes
Shared DirectAdminAsk supportYes
VPSInstall yourself (1 command)Install yourself
App PlatformAdd Redis as a service
### Redis — use cases - Session storage (Laravel/Rails/PHP sessions) - Queue backend (Laravel Queues, Sidekiq, BullMQ) - Rate limiting (atomic INCR with expiry) - Full-page cache - Real-time features (pub/sub) - Leaderboards (sorted sets) Redis is the modern default — richer data types, persistence, pub/sub. Memcached is strict key-value only but slightly faster for pure lookups. ### Redis example — PHP ```php $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $cached = $redis->get('user:42:profile'); if (!$cached) { $profile = expensiveQuery(); $redis->setex('user:42:profile', 300, json_encode($profile)); return $profile; } return json_decode($cached, true); ``` ### Redis example — Node.js ```javascript import { createClient } from 'redis'; const redis = createClient(); await redis.connect(); const cached = await redis.get(`user:${id}:profile`); if (cached) return JSON.parse(cached); const profile = await db.user.findUnique({ where: { id } }); await redis.setEx(`user:${id}:profile`, 300, JSON.stringify(profile)); return profile; ``` ### Install Redis on VPS ```bash # AlmaLinux / Rocky sudo dnf install -y redis sudo systemctl enable --now redis redis-cli ping # expect PONG # Enable persistence (AOF) sudo sed -i 's/^appendonly no/appendonly yes/' /etc/redis/redis.conf sudo systemctl restart redis ``` ## Layer 4 — Varnish / HTTP cache Varnish sits in front of your app, caches full HTTP responses based on `Cache-Control` headers. Far less common in 2026 — Cloudflare/Fastly cover this with less operational burden. **On shared hosting:** Varnish isn't available. Use [Cloudflare's edge cache](https://domainindia.com/support/kb/category/dev-cloudflare) instead — same result, zero config. **On VPS:** Varnish is fine if you have specific needs (custom VCL rules, no Cloudflare dependency). Setup: ```bash sudo dnf install -y varnish # Edit /etc/varnish/default.vcl — proxy to your app on port 8080 sudo systemctl enable --now varnish ``` For most users: skip Varnish. Let Cloudflare handle HTTP-layer caching. Focus on Redis/OPcache. ## Cache invalidation strategies "There are only two hard things in Computer Science: cache invalidation and naming things." Three patterns: **1. TTL-only (easy, eventually stale)** - Set a short TTL (30–300s) - Accept stale reads for that window **2. Explicit invalidation (correct, more code)** - When data changes, delete cache key - Example: on `updateUser(42)`, `redis.del('user:42:profile')` **3. Tags (elegant, complex)** - Tag cached entries: `user:42:profile` tagged with `user:42` - On change, invalidate all entries with tag `user:42` - Laravel Cache supports this natively (`Cache::tags(['users'])->put(...)`) For most apps: TTL-only for read-heavy data (feeds, product catalogs), explicit invalidation for user-specific (profile, cart). ## Measuring cache effectiveness Without measurement, you're guessing. **Redis:** `redis-cli INFO stats` → `keyspace_hits` vs `keyspace_misses`. Ratio tells you hit rate. **Cloudflare:** Dashboard → Analytics → Cache. Look for CF-Cache-Status: HIT ratio. **App-level:** log cache HIT/MISS to your logger. Aggregate in Grafana. Good targets: - Redis hit rate > 80% - Cloudflare HTML cache hit > 50% (for cacheable pages) - OPcache hit rate > 99% ## Common pitfalls ## FAQ
Q Redis or Memcached — which?

Redis, almost always. Richer data types, persistence, pub/sub. Memcached only if you have a specific reason (pure-simplicity key-value, legacy systems).

Q Can I use Redis on shared hosting?

On our cPanel shared plans, yes — a shared Redis instance is available via Unix socket. Check with support for connection string. For DirectAdmin, confirm with our support team.

Q Do I need Varnish if I'm on Cloudflare?

No. Cloudflare's edge cache does everything Varnish does + free DDoS + global CDN. Varnish is only for special cases (custom VCL rules, on-prem requirements).

Q How do I cache database query results in Laravel?

Cache::remember('users.active', 300, fn() => User::where('active', true)->get()). Laravel picks Redis automatically if configured.

Q Cache everything vs cache nothing — where to start?

Measure slowest endpoints first (application logs or APM). Cache the top 3 slowest reads. Iterate. Premature caching adds complexity without measurable gain.

Need Redis / Memcached at scale? VPS with root access gives you full control. View VPS plans

Was this article helpful?

Your feedback helps us improve our documentation

Still need help? Submit a support ticket