Running one Redis per VPS is a perfectly reasonable call for small-to-medium projects. The trouble starts when several apps begin sharing the same instance: one project’s users key clobbers another’s users key, and the moment someone runs FLUSHALL everyone goes down.

The fix isn’t standing up a new Redis; it’s namespace discipline.

A three-layer key scheme

In production I use this pattern:

<env>:<app>:<bounded-context>:<key>

For example:

prod:billing:invoice:42
prod:auth:session:1c2f...
staging:notify:queue:retry

Having all three layers buys you two things:

  1. Clarity when searching. With redis-cli --scan --pattern 'prod:billing:*' I can see the keys of just one project.
  2. Friction against accidental deletes. I think twice when I type redis-cli --scan --pattern 'staging:*' | xargs redis-cli DEL instead of FLUSHDB.

Don’t rely on logical DBs

Redis has logical DBs numbered 0–15, but in a word: don’t use them. Three reasons:

  • The SELECT command is scoped only to that connection — chaos in a connection pool.
  • Some libraries don’t support a DB switch inside MULTI/EXEC blocks.
  • Redis Cluster doesn’t support logical DBs at all; the day you move to a cluster, every one of your assumptions collapses.

Learning and applying a namespace prefix is the only approach.

Connection-level isolation

If you’re on Laravel, define a separate Redis connection per app in config/database.php and bake the namespace into the connection with prefix:

'redis' => [
    'billing' => [
        'host' => env('REDIS_HOST'),
        'password' => env('REDIS_PASSWORD'),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
        'prefix' => 'prod:billing:',
    ],
    'auth' => [
        // ...
        'prefix' => 'prod:auth:',
    ],
],

Now a Redis::connection('billing')->set('invoice:42', ...) call automatically writes prod:billing:invoice:42. Even if a developer forgets to write the namespace by hand, the system protects itself.

Disable the dangerous commands

In redis.conf it’s a good idea to rename or disable these commands in production:

rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command KEYS ""

KEYS matters most — the moment someone runs KEYS * on an instance with 100k+ keys, the event loop locks up for seconds. Using SCAN instead should be mandatory.

When do you drop this pattern?

Move to separate Redis instances if any one of three signals shows up:

  1. One project’s traffic measurably affects the latency of the others.
  2. One project wants persistent storage (RDB/AOF) while the others are cache-only.
  3. One project needs a different Redis version or feature.

Before any of those, hold this simple rule: writing a prefix is cheaper than starting a new process.