Redis is a popular in-memory key-value store known for its speed and flexibility. As a developer, you may often need to know the total number of keys stored in your Redis instances for monitoring and debugging purposes. This guide will demonstrate multiple methods to count keys in Redis.
Introduction to Redis Keyspaces
Before we jump into the key counting methods, let‘s first understand Redis keyspaces.
Redis stores data in databases that are isolated keyspaces. By default, there are 16 databases numbered 0 to 15. You can switch between these databases using the SELECT
command. For example:
127.0.0.1:6379> SELECT 5
OK
127.0.0.1:6379[5]>
This switches to database 5.
Each database has its own separate keyspace with no relation to other databases. So keys in database 0 are completely separate from keys in database 5.
This is an important distinction to understand before counting keys in Redis. When you count keys, you are counting keys in the currently selected database only.
Count Keys using DBSIZE
The simplest way to count total keys is using the DBSIZE
command:
127.0.0.1:6379> DBSIZE
(integer) 100
DBSIZE
returns the total number of keys in the currently selected database. It‘s extremely fast since Redis just returns an integer without having to scan the keyspace.
Keep in mind this counts all key types – strings, hashes, lists, sets, sorted sets, streams, etc.
To count keys in a specific database:
127.0.0.1:6379> SELECT 5
OK
127.0.0.1:6379[5]> DBSIZE
(integer) 302
So database 5 contains 302 keys. The DBSIZE
result is instant since it‘s not actually counting, just returning a pre-calculated integer value.
One thing to note about DBSIZE
is that expired keys which have not yet been evicted will still be counted in the total. So you may see a discrepancy between DBSIZE
and actual in-use keys. We‘ll discuss how to analyze memory breakdowns later on.
Count Keys using KEYS
The KEYS
command can match keys based on a pattern and return all matching keys. To get total keys, we can use the *
wildcard which matches everything:
127.0.0.1:6379> KEYS *
1) "key1"
2) "key2"
3) "foo"
...
It‘s important to note that KEYS
actually scans and returns every single key, so it can get slow in large databases.
For example, this can take seconds or even minutes on databases with millions of keys:
127.0.0.1:6379> KEYS *
... hangs ...
To count total keys with KEYS
, you would have to do:
127.0.0.1:6379> KEYS * | GREP -c .
(integer) 100302
The pipe to GREP -c
counts lines returned by KEYS *
. This gives the total key count but can get slow on huge databases.
In most cases, it‘s better to use DBSIZE
unless you specifically need to retrieve all keys for something.
One other danger of KEYS
is that since it blocks the server while processing, it can cause availability issues in production environments. On Redis Cluster, this is not as much of an issue since queries go to different nodes, but standalone Redis can be blocked fully until KEYS
completes.
So avoid executing blocking KEYS
queries in production scenarios.
Count Key Types
Sometimes you may want to count specific key types like hashes, lists or sorted sets.
This returns all hash key names:
127.0.0.1:6379> KEYS h*
1) "hash1"
2) "somehash"
3) "user:1000:hash"
We can combine this with GREP -c
to count:
127.0.0.1:6379> KEYS h* | GREP -c .
(integer) 200
There are 200 hash keys in this database. This can be done for lists, sets, sorted sets etc.
Understanding cardinalities of your different data types helps analyze storage breakdowns and utilization more effectively.
For example, here‘s a sample keyspace breakdown:
Type | Count | Avg Size | Total | % Memory |
---|---|---|---|---|
Hash | 200 | 512 KB | 102 GB | 38% |
List | 100 | 128 KB | 12 GB | 5% |
Set | 1500 | 64 KB | 96 GB | 36% |
String | 500 | 4 KB | 2 GB | 1% |
Sorted Set | 50 | 256 KB | 12 GB | 5% |
Stream | 10 | 1 MB | 10 GB | 4% |
Total | 2360 | 256 KB | 234 GB | 100% |
Having output like above helps identify keys taking up excess memory that could use eviction or other policies applied.
Using SCAN for Counting Keys
If KEYS
is too slow on massive databases, Redis provides cursor based iteration using SCAN
.
Basic syntax is:
127.0.0.1:6379> SCAN 0 MATCH * COUNT 1000
This iterates through the keyspace 1000 keys at a time, matching all keys.
We have to iterate the entire database to count keys:
127.0.0.1:6379> SCAN 0 MATCH * COUNT 1000
1) "536"
2) 1) "key:453"
2) "key:23"
3) "key:9092"
...
127.0.0.1:6379> SCAN 536 MATCH * COUNT 1000
...
The first integer returned by SCAN is a cursor to the next iteration. We repeat SCAN using this cursor until the cursor returns 0, indicating end of database.
To count keys, we have to increment a counter each SCAN and add up totals from each. This requires code instead of a simple command.
Most Redis client libraries have SCAN wrappers that handle the iteration automatically.
For example, in Python:
import redis
r = redis.Redis()
cursors = ‘0‘
count = 0
while cursors != 0:
cursors, keys = r.scan(cursors=cursors, match=‘*‘, count=1000)
count += len(keys)
print(count)
This performs incremental counting using SCAN behind the scenes.
Similar wrappers are available in most languages. But even with SCAN, counting keys has more overhead than a simple DBSIZE
call. Use SCAN when you need to retrieve large keysets that don‘t fit in memory or avoid blocking.
Key Information using INFO
The INFO
command provides tons of insight into a Redis server. We can use it to get keyspace information also.
This returns information for the currently selected database:
127.0.0.1:6379> INFO keyspace
# Keyspace
db0:keys=36000,expires=190,avg_ttl=1528044
The important bits here are:
- keys=36000 – Total number of keys
- expires=190 – Number of keys with expiration set
- avg_ttl=1528044 – Average TTL of keys with expiration
So there are 36000 total keys, out of which 190 keys have expiration set.
This provides useful insight into keys without having to crawl the entire keyspace.
We can also use INFO memory
to understand storage breakdown between data types:
# Memory
used_memory:497393864
used_memory_human:474.42M
used_memory_rss:549178368
used_memory_peak:X
used_memory_peak_human:X
used_memory_lua:35840
mem_fragmentation_ratio:1.10
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
# Memory by key type
hash_type:251
stream_type:3
set_type:2
zset_type:1
list_type:1
string_type:2
This provides storage used by hashes, lists, sets etc. Useful for deeper analysis.
Other Tips for Counting Keys
Here are some additional tips when counting keys in Redis:
- Enabling RDB / AOF persistence provides exact key counts on restarts for database reconstruction.
- Client side caching of counts can help avoid heavy server side counting.
- Some Redis GUI tools like RedisInsight provide ways to visualize or count keys.
- Key namespaces can help categorize subsets of keys for easier analysis.
- Exporting metrics to Prometheus lets you graph and query keyspaces.
Performance Comparison
In general for counting keys, the performance profile looks like:
Method | Relative Speed | Use Case |
---|---|---|
DBSIZE | Fastest | Simple total count |
INFO | Fast | When data breakdown needed without full scan |
SCAN + Client | Moderate | Retrieving large keysets without blocking |
KEYS | Slow | Avoid in production, can block/crash Redis |
So in most cases DBSIZE
should be enough to get total keys. For more complex cases, consider using SCAN
, INFO
or other approaches outlined earlier.
Conclusion
Counting keys is a vital part of managing Redis. We covered different ways to get total keys:
- Use
DBSIZE
when you just need total keys - Retrieve entire keysets with
KEYS *
(avoid in production) - Incrementally count keys with
SCAN
in client code - Gain insights into memory utilization with
INFO memory
andINFO keyspace
Understanding the performance tradeoffs allows selecting the right approach. DBSIZE
works great in most cases due to its speed and simplicity.
Analyzing your keyspaces and memory utilization over time helps identify areas to optimize and improve Redis efficiency. Both counts of total keys as well as drilling into breakdowns across data types provide valuable insights.
Hopefully this provides you a good overview of counting keys in Redis! Let me know if you have any other questions.