Search code examples
memoryredisredis-cli

Get the redis key-value size in memory


I'm trying to get the size of a key-value or just a key or just a value in redis.

Using debug object key command returns the serialized size of a key-value if it were to be written to disk and not the actual amount of bytes it is using in memory.

This can be confirmed by checking the source code (based from this Redis: Show database size/size for keys)

https://github.com/antirez/redis/blob/4082c38a60eedd524c78ef48c1b241105f4ddc50/src/debug.c#L337-L343

https://github.com/antirez/redis/blob/4082c38a60eedd524c78ef48c1b241105f4ddc50/src/rdb.c#L663-L671

looking at the source code:

/* Save a string object as [len][data] on disk. If the object is a string
 * representation of an integer value we try to save it in a special form */
ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) {
  int enclen;
  ssize_t n, nwritten = 0;

  /* Try integer encoding */
  if (len <= 11) {
    unsigned char buf[5];
    if ((enclen = rdbTryIntegerEncoding((char*)s,len,buf)) > 0) {
      if (rdbWriteRaw(rdb,buf,enclen) == -1) return -1;
      return enclen;
    }
  }

  /* Try LZF compression - under 20 bytes it's unable to compress even
   * aaaaaaaaaaaaaaaaaa so skip it */
  if (server.rdb_compression && len > 20) {
    n = rdbSaveLzfStringObject(rdb,s,len);
    if (n == -1) return -1;
    if (n > 0) return n;
    /* Return value of 0 means data can't be compressed, save the old way */
  }

  /* Store verbatim */
  if ((n = rdbSaveLen(rdb,len)) == -1) return -1;
  nwritten += n;
  if (len > 0) {
    if (rdbWriteRaw(rdb,s,len) == -1) return -1;
    nwritten += len;
  }
  return nwritten;
}

And confirm through redis-cli:

127.0.0.1:6379> set a aaaaaaaaaaaaaaaaaaa
OK
127.0.0.1:6379> debug object a
Value at:0x7f985822f168 refcount:1 encoding:embstr serializedlength:20 lru:11611136 lru_seconds_idle:2
127.0.0.1:6379> set a aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
OK
127.0.0.1:6379> debug object a
Value at:0x7f985827c428 refcount:1 encoding:embstr serializedlength:12 lru:11611147 lru_seconds_idle:1

All the different CLI tools are reporting the serialized size of the object and not the memory size which is the interesting and important one.


Solution

  • As of Redis v4, the MEMORY USAGE command does a much better job at guessing the footprint of a key and its value.