Most slow websites are slow because they redo the same work on every request. Caching stores the result once and serves it many times; the question is which layer to cache at, and which layers your hosting actually gives you.
Caching turns a 500 ms database query into a 1 ms memory lookup. This guide covers the server-side caching layers you should understand: OPcache (PHP bytecode), APCu (in-process data), Redis or Memcached (shared data cache) and an HTTP response cache (Varnish, nginx or Cloudflare), and which of them you can use on Domain India shared hosting, the App Platform or a VPS.
The four caching layers
Your web stack has four places to cache, from fastest to slowest:
| Layer | Caches | Read time | On Domain India |
|---|---|---|---|
| OPcache | PHP bytecode | <0.01 ms | On for cPanel sites; DirectAdmin on every PHP version except 8.3 |
| APCu | PHP user data (in-process) | <0.1 ms | Not installed on cPanel or DirectAdmin hosting; install it on a VPS |
| Redis / Memcached | Any data (across processes) | 0.5–1 ms | Not on shared hosting or the App Platform; install it on a VPS |
| HTTP cache (nginx, Varnish, Cloudflare) | Full HTTP responses | 5–20 ms (cache hit) | cPanel runs an nginx caching proxy; Cloudflare works with any plan |
On a VPS you can combine all of them. On shared hosting you get OPcache and the HTTP layer; data caching happens in your app's database or files.
Layer 1: OPcache (PHP)
Without OPcache, PHP reads and compiles your scripts on every request. OPcache stores the compiled version in memory so PHP skips that work.
Impact: typically a large speedup for PHP apps. It is essential in production.
On our cPanel servers OPcache is enabled for websites. On our DirectAdmin servers it is enabled for every PHP version except PHP 8.3 (measured 20 September 2026); on Webuzo, check your own site. To check, put <?php var_dump(ini_get('opcache.enable')); in a temporary file, open it in the browser, then delete it. (phpinfo() is disabled on cPanel.)
On shared hosting, OPcache memory and file-count settings are server-wide and can't be changed from your account. On a VPS you control them, for example in /etc/php.d/10-opcache.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 + reload on deploy)
opcache.revalidate_freq=2 ; seconds between checks
opcache.jit=1255 ; PHP 8+ JIT (tracing mode)
opcache.jit_buffer_size=64MIf you set validate_timestamps=0, clear OPcache on every deploy by reloading PHP-FPM or calling opcache_reset() from a web request; otherwise OPcache keeps serving the old code. Running php -r "opcache_reset();" over SSH clears only the command-line cache, not your website's.
See our PHP OPcache guide for the details.
Layer 2: APCu
APCu is an in-memory key-value cache local to one PHP-FPM pool. It suits small hot data: feature flags, config arrays, rate-limit counters.
APCu is not installed on Domain India cPanel or DirectAdmin hosting. On your own VPS, install it from your OS packages (for example php-apcu) and use it like this:
apcu_store('flag_new_checkout', true, 300); // 300 s TTL
if (apcu_fetch('flag_new_checkout')) { /* new checkout */ }Limits:
- Not shared across servers or across PHP-FPM pools
- Cleared when PHP-FPM restarts
- Bounded by the memory you give it
For caching shared across processes or servers, use Redis or Memcached instead.
Layer 3: Redis or Memcached
An external in-memory store: multi-process, multi-server, and persistent in Redis's case.
On Domain India:
| Where your app runs | Redis | Memcached |
|---|---|---|
| Shared hosting (cPanel, DirectAdmin, Webuzo) | Not available | Not available |
| App Platform | No Redis add-on (PostgreSQL is included) | Not available |
| VPS | Install yourself | Install yourself |
On shared hosting, use your framework's database or file cache (for example Laravel's database driver) and a page caching plugin for WordPress, such as WP Super Cache or W3 Total Cache. For Redis or Memcached, use a VPS; it is self-managed, so you install and secure them yourself. See Redis and Memcached setup.
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 a strict key-value store, fine where an app already uses it.
Redis example: 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
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 a VPS
# AlmaLinux / Rocky 9 (on AlmaLinux 10, install "valkey" instead)
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 redisKeep Redis bound to 127.0.0.1, set a password and never open port 6379 to the internet.
Layer 4: HTTP response cache (nginx, Varnish, Cloudflare)
An HTTP cache sits in front of your app and stores full responses, guided by Cache-Control headers.
On Domain India cPanel hosting: our cPanel servers run nginx in front of Apache as a caching proxy. It can keep 200, 301 and 302 responses for up to 120 minutes, and can serve a stored copy while Apache returns an error (measured 22 September 2026). If a change doesn't show, add ?t= with a new value to the URL to check it. You can't configure this cache from your account.
Varnish isn't available on shared hosting. On a VPS it's an option when you need custom VCL rules:
sudo dnf install -y varnish
# Edit /etc/varnish/default.vcl to proxy to your app on port 8080
sudo systemctl enable --now varnishCloudflare works in front of any plan. It caches static files by default; HTML is cached only if you add a cache rule for it. See our Cloudflare, CDN and edge articles.
For most sites: skip Varnish, let the cPanel proxy or Cloudflare handle the HTTP layer, and focus on OPcache and your app's own caching.
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–300 s)
- Accept stale reads for that window
2. Explicit invalidation (correct, more code)
- When data changes, delete the cache key
- Example: on
updateUser(42),redis.del('user:42:profile')
3. Tags (elegant, more complex)
- Tag cached entries:
user:42:profiletagged withuser:42 - On change, invalidate every entry with tag
user:42 - Laravel supports this with the Redis and Memcached drivers (
Cache::tags(['users'])->put(...))
For most apps: TTL-only for read-heavy data (feeds, product catalogues), explicit invalidation for user-specific data (profile, cart).
Measuring cache effectiveness
Without measurement, you're guessing.
Redis: redis-cli INFO stats → keyspace_hits vs keyspace_misses. The ratio is your hit rate.
OPcache: opcache_get_status() from a web request shows hits, misses and whether the cache is full.
Cloudflare: Dashboard → Analytics → Cache, or the CF-Cache-Status response header.
App-level: log cache HIT/MISS and aggregate it in your monitoring tool.
Good targets:
- Redis hit rate > 80%
- Cloudflare HTML cache hit > 50% (for cacheable pages)
- OPcache hit rate > 99%
Common pitfalls
maxmemory and maxmemory-policy allkeys-lru.validate_timestamps=0, OPcache doesn't see new files. Reload PHP-FPM or call opcache_reset() from a web request in your deploy.user_email:[email protected] exposes emails in logs and key listings. Hash the value or use an ID.myapp:user:42.FAQ
Redis or Memcached: which should I use?
Redis, almost always. It has richer data types, persistence and pub/sub. Choose Memcached only if your application already depends on it.
Can I use Redis on Domain India shared hosting?
No. Redis and Memcached are not available on Domain India shared hosting (cPanel, DirectAdmin or Webuzo), and the App Platform has no Redis add-on. Run Redis on a Domain India VPS, or use your framework's database or file cache on shared hosting.
Is OPcache enabled on Domain India hosting?
On our cPanel servers, yes. On our DirectAdmin servers it is enabled for every PHP version except PHP 8.3 (measured 20 September 2026). Check your own site with ini_get('opcache.enable') in a temporary PHP file.
Do I need Varnish if I'm on Cloudflare?
Usually not. Cloudflare's edge cache covers most HTTP caching needs once you add cache rules for your HTML. Varnish is for special cases, such as custom VCL logic on your own server.
How do I cache database query results in Laravel?
Use Cache::remember('users.active', 300, fn() => User::where('active', true)->get()). Laravel uses whichever cache store you configure: Redis on a VPS, or the database driver on shared hosting.
Where should I start: cache everything or nothing?
Measure your slowest endpoints first, from application logs or an APM tool. Cache the three slowest reads, measure again and repeat. Caching before you measure adds complexity without a clear gain.
Ready to go further? Read My website is slow for shared hosting, or choose a Domain India VPS to run Redis, Memcached or Varnish yourself.
A self-managed VPS with root access lets you install and tune every caching layer yourself.
View VPS plans