How to Delete All Keys in Valkey and Redis: FLUSHALL, FLUSHDB, and Clearing Cache Safely in Java
Two commands clear a Valkey or Redis instance. FLUSHDB removes every key from the database you're currently connected to. FLUSHALL removes every key from every database on the node.
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> FLUSHALL
OK
Both are instant, both are irreversible, and both propagate to your replicas. This guide covers the difference, the ASYNC modifier you should almost always be using, what happens in a cluster, how to stop someone running these by accident — and what to do in the minutes after somebody already has.
FLUSHALL vs FLUSHDB
Valkey and Redis support multiple logical databases on a single node, numbered 0 through 15 by default and selected with SELECT. They share one process, one memory pool, and one configuration — they are namespaces, not isolated instances.
| FLUSHDB | FLUSHALL | |
|---|---|---|
| Scope | Currently selected database | All databases on the node |
| Affects other databases | No | Yes |
| Cluster mode | Same as FLUSHALL | Same as FLUSHDB |
| Replicated to replicas | Yes | Yes |
| Reversible | No | No |
In practice most deployments only ever use database 0, which makes the two commands functionally identical and explains why they're so often confused. The distinction only matters if you've deliberately partitioned work across databases — say, 0 for sessions and 1 for a job queue — in which case reaching for FLUSHALL when you meant FLUSHDB destroys data you never intended to touch.
In cluster mode the distinction disappears entirely. Redis Cluster supports only database 0, so FLUSHDB and FLUSHALL do exactly the same thing on any given node.
The ASYNC Modifier
By default, these commands free memory synchronously. The server walks every key, releases it, and only then replies — blocking the single command thread for the whole operation. On a large keyspace, that is a multi-second stall during which nothing else runs.
Since Redis 4.0 you can hand the work to a background thread:
FLUSHALL ASYNC
FLUSHDB ASYNC
The keyspace becomes empty immediately; memory is reclaimed behind the scenes. Clients see a fast reply and the server stays responsive.
Since Redis 6.2 the lazyfree-lazy-user-flush directive controls the default, so you can make ASYNC the standard behaviour without changing calling code:
lazyfree-lazy-user-flush yes
The rule is simple: on anything but a trivially small dataset, use ASYNC. The synchronous form has no advantage other than knowing precisely when the memory came back.
What FLUSHALL Does and Doesn't Do
It deletes keys — and your RDB file. Configuration, ACL users, replication topology, client connections, and Lua functions all survive. But the persistence file does not: FLUSHALL clears the RDB, aborts any in-progress snapshot, and writes an empty one if save is configured. That single behaviour is what makes accidental flushes so hard to recover from, and it's covered in detail below.
It replicates. FLUSHALL is a write command, so it propagates down the replication stream to every replica. This is the detail that turns a mistake into an incident: replicas are not a backup, and they will be empty within milliseconds of the primary. Anyone reasoning that "we have three replicas, we're fine" has misunderstood what replication protects against.
An async flush only removes what existed when it was issued. Keys written during an asynchronous FLUSHALL are unaffected, so a busy instance won't come back completely empty — which can make the blast radius confusing to assess after the fact.
It may not return memory to the operating system. The keys are gone and the memory is free from the allocator's perspective, but resident set size can stay high because of fragmentation. MEMORY PURGE helps on jemalloc builds. If you were flushing specifically to reduce RSS, check INFO memory rather than assuming.
Clearing a Cluster
FLUSHALL clears the node you sent it to. In a cluster, the keyspace is divided across multiple masters by hash slot, so one command leaves the rest of your data exactly where it was.
The command-line workaround fans the command out:
redis-cli --cluster call 127.0.0.1:7000 FLUSHALL ASYNC
Doing this from application code means discovering the current set of masters, opening a connection to each, issuing the command per node, and coping with a failover midway through. It is the same per-node problem that makes listing keys across a cluster awkward, and it's the reason a client that understands cluster topology is worth having.
Safer Alternatives to a Full Flush
Most of the time somebody reaches for FLUSHALL, a narrower tool would have done the job with less risk.
Swap a rebuilt database into place. SWAPDB atomically exchanges two databases in O(1):
# Build the new cache in db 1, then swap it in
127.0.0.1:6379> SWAPDB 0 1
OK
Clients reading from database 0 see the new dataset instantly, with no window in which the cache is empty. The old data now sits in database 1, where you can inspect it or flush it at leisure — which also means the swap is trivially reversible. For a scheduled cache rebuild this is strictly better than flushing and repopulating.
This one is standalone-only. Redis Cluster supports just database 0, so there is no second database to swap with — and Redisson's swapdb() issues the command to a single node rather than fanning out. If you're running a cluster, reach for pattern-scoped deletion or versioned namespaces instead.
Delete only what's stale. If you can express the obsolete data as a key pattern, scan and unlink it rather than clearing everything. See the companion guide on finding keys by pattern for the mechanics.
Let keys expire. A TTL on every cache entry means stale data removes itself and a full flush is never the answer to "this data is old". This is a cache invalidation design decision, and getting it right removes the need for the blunt instrument.
Namespace by deployment. Prefixing keys with a build or schema version (v42:user:1042) means a new release simply writes under a new prefix. The old data ages out on its own and you never flush at all.
Preventing an Accidental Flush
Neither command asks for confirmation, and both are one word long. If your production credentials can run them, eventually someone will.
Revoke the commands with ACLs. This is Redis's own recommended approach, it's precise, and it's adjustable without a restart:
ACL SETUSER app on >secret ~* +@all -@dangerous
FLUSHALL and FLUSHDB both belong to the @dangerous category, so this removes them along with the other commands no application should be issuing. Note that @dangerous is broad — it also covers INFO, CONFIG, CLUSTER, KEYS and SORT, so a blanket exclusion can break monitoring agents. If that bites, revoke the two commands explicitly instead:
ACL SETUSER app on >secret ~* +@all -flushall -flushdb
Grant them narrowly to a separate maintenance user if you need them at all.
The older approach: renaming commands in the config. You will still find this in most hardening guides:
rename-command FLUSHALL ""
rename-command FLUSHDB ""
An empty replacement name makes the command unreachable. It works, but rename-command is deprecated — redis.conf carries an explicit warning against it, and the security documentation says it may be removed in a future version, directing users to ACLs instead. Treat it as a fallback for pre-6.0 instances rather than the default choice.
Separate human and service credentials. Application users should never hold flush rights. Operators who do should be connecting through a distinct account, which makes the dangerous action deliberate rather than incidental.
Guard against pointing the wrong config at the wrong host. The most common way this happens isn't a rogue operator — it's a local development run, or a test suite fixture that calls flushAll() between cases, executing against a production endpoint because an environment variable was set wrong. Test teardown code that flushes is a loaded gun; scope it to a dedicated database or a key prefix instead.
Recovering From an Accidental FLUSHALL
There is no undo, and the recovery picture is worse than most people assume.
The critical thing to understand: FLUSHALL destroys your RDB snapshot too. Beyond emptying the databases, it clears the RDB persistence file, aborts any snapshot already in progress, and — if save points are configured — writes an empty RDB in its place. This happens as part of the command, not later at shutdown. So the intuition "my last snapshot is still on disk, I'll restore from that" is usually wrong after a FLUSHALL.
(FLUSHDB on a standalone instance does not carry this behaviour — it empties the selected database without touching the RDB file. But in cluster mode the documentation states FLUSHDB is identical to FLUSHALL, since a cluster has only database 0, so assume the RDB goes with it there too.)
First: stop writing, and do not restart the server. If AOF is your recovery path, a restart replays the flush; if any backup process is running, you want it stopped before it propagates the empty state.
If you have AOF enabled — this is your best chance. The append-only file recorded the flush as a command, so a naive restart simply replays it, but the data written before it is still in the file. Shut down without saving, copy the entire AOF directory somewhere safe, and remove the flush command before restarting:
redis-cli SHUTDOWN NOSAVE
Two complications. On Redis 7 and later the AOF is multi-part — a base file plus incrementals, tracked by a manifest in the appenddirname directory — so you need to locate the incremental containing the flush rather than editing a single log. And an automatic rewrite triggered after the flush will compact the file down to the current, empty state, permanently discarding the history. Speed genuinely matters here.
If you rely on RDB alone. Your on-box dump.rdb has likely already been cleared or replaced with an empty file. Recovery then depends entirely on an off-box copy — a backup shipped to object storage, a filesystem snapshot, or an RDB pulled from a replica that was disconnected before the flush propagated. Check those before assuming the data is gone, and check them without restarting the server.
If you have neither. The data is gone. Replicas were wiped by the same replicated command, and there is nothing local to restore from.
The honest summary: recovery is a function of decisions made before the incident, and RDB-on-the-same-box is not one of them. If this scenario is unacceptable for your workload, enable AOF with appendfsync everysec, ship snapshots off the box on a schedule, and verify that a restore actually works.
Clearing Keys From Java
A low-level client exposes the raw commands and leaves cluster fan-out to you — meaning a flush across a sharded deployment becomes a loop over discovered masters, with the failover handling that implies.
Redisson exposes them through the RKeys interface:
RedissonClient redisson = Redisson.create(config);
RKeys keys = redisson.getKeys();
keys.flushdb(); // current database, blocking
keys.flushall(); // all databases, blocking
keys.flushdbParallel(); // background, non-blocking — Redis 4.0+
keys.flushallParallel(); // background, non-blocking — Redis 4.0+
The Parallel variants map to the ASYNC modifier discussed above, and are what you should reach for by default.
One naming subtlety worth internalising: in Redisson, Parallel and Async mean different things on different axes. Parallel describes what the server does — freeing memory on a background thread. Async describes what the client does — returning an RFuture instead of blocking your thread. They combine:
| Method | Blocks your thread | Blocks the server |
|---|---|---|
flushall() | Yes | Yes |
flushallParallel() | Yes | No |
flushallAsync() | No | Yes |
flushallParallelAsync() | No | No |
For most production use, flushallParallelAsync() is the combination you want. The same four exist for flushdb. See our guide to non-blocking Valkey and Redis in Java for how the async API fits into a reactive stack.
Supporting Operations
long before = keys.count(); // DBSIZE, summed across all masters
keys.swapdb(0, 1); // atomic swap — the safe rebuild
keys.move("user:1042", 1); // relocate a key before flushing
keys.delete("user:1042", "cart:1042");
keys.unlink("session:a7f3"); // background memory reclaim
keys.deleteByPattern("session:*"); // scoped bulk delete
deleteByPattern() and unlinkByPattern() are the targeted alternative to a flush — though note they execute non-atomically in cluster mode, a consequence of Lua scripts being confined to a single hash slot.
Because RKeys operates across the whole keyspace, flushallParallel() reaches every master in a cluster without any per-node connection code on your side.
Production Checklist
-
Revoke
FLUSHALLandFLUSHDBin production with ACLs.rename-commandalso works but is deprecated. -
Use
ASYNC— orlazyfree-lazy-user-flush yes— on any non-trivial keyspace. - Remember that replicas are wiped too. Replication is not backup.
-
Prefer
SWAPDBfor scheduled cache rebuilds; it's atomic and reversible. - Prefer pattern-scoped deletion when you can express what's stale.
- Never flush in test teardown against a shared endpoint — scope to a dedicated database or prefix.
-
If a flush happens by accident, stop writes and don't restart. AOF is your recovery path —
FLUSHALLwill already have cleared the on-box RDB. - Verify your restore path works before you need it.
FAQ
How Do I Flush All Data From Redis?
Run FLUSHALL to clear every database on the node, or FLUSHDB for just the current one. Add ASYNC to avoid blocking the server. In Java with Redisson, redisson.getKeys().flushallParallel().
How Do I Clear All the Cache in Redis?
FLUSHALL ASYNC clears everything. If only part of the cache is stale, scanning and unlinking by key pattern is safer, and SWAPDB lets you swap in a rebuilt cache with no empty window.
How Do I Flush a Redis Container?
Execute the command inside the container: docker exec -it <container> redis-cli FLUSHALL ASYNC. If the container has no persistent volume, recreating it achieves the same thing.
What Is the DISCARD Command in Redis?
DISCARD is unrelated to flushing — it aborts a transaction opened with MULTI, throwing away the queued commands before they run. See our guide to Redis transactions.
What's the Difference Between FLUSHALL and FLUSHDB?
FLUSHDB clears the currently selected database; FLUSHALL clears all of them on that node. In cluster mode, where only database 0 exists, they're equivalent.
Can I Undo a FLUSHALL?
Not directly, and RDB usually won't save you: FLUSHALL clears the persistence file and writes an empty one if save is configured. Realistic recovery means an AOF containing the pre-flush history, or an off-box backup. Stop writes and avoid restarting the server before securing a copy.