A prefix match
A single star crosses colons, because Redis keys have no path structure
user:1000:profile user:1000:session admin:1:profile cache:user:1000
Enter a pattern and paste keys to test it against. Matching uses a direct port of Redis's own matcher, so the answer is what KEYS or SCAN MATCH would actually return rather than what a shell or a JavaScript glob library would.
Matched with Redis's own stringmatchlen, ported directly. Not minimatch, and not a regex.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Match. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
A single star crosses colons, because Redis keys have no path structure
user:1000:profile user:1000:session admin:1:profile cache:user:1000
The pattern that walks the entire keyspace and blocks the server while it does
user:1000:profile session:abc cache:xyz
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
Redis collapses consecutive stars, so `**` is exactly `*`. Redis keys have no path structure for a recursive star to descend.
Instead:Use a single `*`, which already crosses colons.
Redis has no brace expansion; those are five literal characters. In cluster mode braces mean a hash tag, so the pattern can accidentally interact with routing.
Instead:Run two SCAN calls, or use a character class if the alternatives are single characters.
KEYS walks the entire keyspace in one blocking operation. On a large instance that is a stall for every other client, caused by a command that looks read-only and harmless.
Instead:SCAN with MATCH, which returns a cursor and does bounded work per call.
Almost every glob library you might reach for behaves differently from Redis in at least one way that matters. These are the differences that change a result.
Redis collapses consecutive stars, so a** is exactly a*. There is no recursive-descent star because Redis keys have no path structure: the colons in user:1000:profile are a naming convention, not syntax the matcher knows anything about. A single * already crosses them.
{a,b} matches those five literal characters. Redis has no brace expansion at all. In cluster mode braces mean a hash tag, which decides routing and is an entirely separate mechanism, so a pattern written with shell habits can accidentally interact with slot selection.
The pattern [abc is not rejected. Redis walks to the end of the pattern and the class still matches its members, so [abc matches a. Nothing reports this, and the pattern quietly means something other than it looks like.
? matches exactly one byte, not one character, so it does not match a multi-byte character like é: that needs two. A range like [a-z] compares byte values. Any pattern relying on non-ASCII behaviour is fragile, and a reversed range like [z-a] is silently swapped rather than rejected.
KEYS walks the entire keyspace in one blocking operation. On a large instance that is a visible stall for every other client, and it is the classic way to cause an incident with a read-only command. SCAN with MATCH does bounded work per call and returns a cursor. The filtering happens after the scan, so a MATCH that excludes almost everything still costs a full traversal, just spread out.
It matches the keys you paste. It does not know your keyspace, so it cannot tell you how many keys a pattern would return or how long the scan would take. A pattern that looks selective here can still traverse millions of keys on a real instance.