Client Area

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

ByDomain India Team·DomainIndia Engineering
6 min readPublished 20 Apr 2026Updated 23 Jun 2026157 views

In this article

  • 1The four caching layers
  • 2Layer 1 — OPcache (PHP)
  • 3Layer 2 — APCu
  • 4Layer 3 — Redis or Memcached
  • 5Redis — use cases

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.enableOpcache.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 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 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 statskeyspace_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