{
  "schema_version": 2,
  "id": "develop/clients/rust/prob",
  "title": "Probabilistic data types",
  "url": "https://redis.io/docs/latest/develop/clients/rust/prob/",
  "summary": "Learn how to use Bloom filter set membership and HyperLogLog approximate cardinality with redis-rs.",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-09T11:06:34+01:00",
  "page_type": "content",
  "content_hash": "d06881bb9583e1bf5c3eedb98fedc7e9da11ac1fe90f9bc2e8b61c483f2fc587",
  "sections": [
    {
      "id": "set-membership",
      "title": "Set membership",
      "role": "content",
      "text": "A [Bloom filter](https://redis.io/docs/latest/develop/data-types/probabilistic/bloom-filter)\nlets you track whether or not a particular item has been added to a set.\nInstead of storing the items themselves, like a\n[set](https://redis.io/docs/latest/develop/data-types/sets), a Bloom filter records the\npresence or absence of the\n[hash value](https://en.wikipedia.org/wiki/Hash_function) of each item. This\ngives a very compact representation of the set's membership with a fixed memory\nsize, regardless of how many items you add. Note that there is an asymmetry\nbetween presence and absence of items in the set: if an item is reported as\nabsent, then it is definitely absent, but if it is reported as present, then\nthere is a small chance it may really be absent.\n\nThe `redis-rs` command traits provide high-level `bf_add`, `bf_madd`,\n`bf_exists`, and `bf_mexists` methods, among others. The following example adds\nsome names to a Bloom filter representing a list of users and then checks for\nthe presence or absence of users in the list.\n\nSet membership: Use Bloom filter to efficiently track item presence with minimal memory overhead\n\n**Difficulty:** Beginner\n\n**Available in:** Rust (Asynchronous), Rust (Synchronous)\n\n##### Rust (Asynchronous)\n\n[code example]\n\n##### Rust (Synchronous)\n\n[code example]"
    },
    {
      "id": "set-cardinality",
      "title": "Set cardinality",
      "role": "content",
      "text": "A HyperLogLog object calculates the approximate cardinality of a set. As you add\nitems, the HyperLogLog tracks the number of distinct set members, but it doesn't\nlet you retrieve those members or test whether a specific item was added.\n\nYou can also merge two or more HyperLogLogs to find the approximate cardinality\nof the [union](https://en.wikipedia.org/wiki/Union_(set_theory)) of the sets\nthey represent.\n\nSet cardinality: Estimate distinct item count using HyperLogLog with minimal memory usage\n\n**Difficulty:** Beginner\n\n**Available in:** Rust (Asynchronous), Rust (Synchronous)\n\n##### Rust (Asynchronous)\n\n[code example]\n\n##### Rust (Synchronous)\n\n[code example]\n\n\n\nThe main benefit that HyperLogLogs offer is their very low memory usage. They\ncan count up to 2^64 items with less than 1% standard error using a maximum\n12KB of memory."
    },
    {
      "id": "more-information",
      "title": "More information",
      "role": "content",
      "text": "See the following pages to learn more:\n\n- [HyperLogLog](https://redis.io/docs/latest/develop/data-types/probabilistic/hyperloglogs)\n- [`redis-rs` command trait](https://docs.rs/redis/latest/redis/trait.Commands.html)\n- [`redis-rs` async command trait](https://docs.rs/redis/latest/redis/trait.AsyncCommands.html)"
    }
  ],
  "examples": [
    {
      "id": "set-membership-ex0",
      "language": "rust",
      "code": "let res1: Vec<bool> = r\n            .bf_madd(\n                \"recorded_users\",\n                &[\"andy\", \"cameron\", \"david\", \"michelle\"],\n            )\n            .await\n            .expect(\"Failed to add users to Bloom filter\");\n        println!(\"{res1:?}\"); // >>> [true, true, true, true]\n\n        let res2: bool = r\n            .bf_exists(\"recorded_users\", \"cameron\")\n            .await\n            .expect(\"Failed to check Bloom filter\");\n        println!(\"{res2}\"); // >>> true\n\n        let res3: bool = r\n            .bf_exists(\"recorded_users\", \"kaitlyn\")\n            .await\n            .expect(\"Failed to check Bloom filter\");\n        println!(\"{res3}\"); // >>> false",
      "section_id": "set-membership"
    },
    {
      "id": "set-membership-ex1",
      "language": "rust",
      "code": "let res1: Vec<bool> = r\n            .bf_madd(\n                \"recorded_users\",\n                &[\"andy\", \"cameron\", \"david\", \"michelle\"],\n            )\n            .expect(\"Failed to add users to Bloom filter\");\n        println!(\"{res1:?}\"); // >>> [true, true, true, true]\n\n        let res2: bool = r\n            .bf_exists(\"recorded_users\", \"cameron\")\n            .expect(\"Failed to check Bloom filter\");\n        println!(\"{res2}\"); // >>> true\n\n        let res3: bool = r\n            .bf_exists(\"recorded_users\", \"kaitlyn\")\n            .expect(\"Failed to check Bloom filter\");\n        println!(\"{res3}\"); // >>> false",
      "section_id": "set-membership"
    },
    {
      "id": "set-cardinality-ex0",
      "language": "rust",
      "code": "let group1_added: bool = r\n            .pfadd(\"group:1\", &[\"andy\", \"cameron\", \"david\"])\n            .await\n            .expect(\"Failed to add items to group:1\");\n        println!(\"{group1_added}\"); // >>> true\n\n        let group1: usize = r.pfcount(\"group:1\").await.expect(\"Failed to count group:1\");\n        println!(\"{group1}\"); // >>> 3\n\n        let group2_added: bool = r\n            .pfadd(\"group:2\", &[\"kaitlyn\", \"michelle\", \"paolo\", \"rachel\"])\n            .await\n            .expect(\"Failed to add items to group:2\");\n        println!(\"{group2_added}\"); // >>> true\n\n        let group2: usize = r.pfcount(\"group:2\").await.expect(\"Failed to count group:2\");\n        println!(\"{group2}\"); // >>> 4\n\n        let _: () = r\n            .pfmerge(\"both_groups\", &[\"group:1\", \"group:2\"])\n            .await\n            .expect(\"Failed to merge HyperLogLogs\");\n        println!(\"OK\"); // >>> OK\n\n        let both_groups: usize = r\n            .pfcount(\"both_groups\")\n            .await\n            .expect(\"Failed to count both_groups\");\n        println!(\"{both_groups}\"); // >>> 7",
      "section_id": "set-cardinality"
    },
    {
      "id": "set-cardinality-ex1",
      "language": "rust",
      "code": "let group1_added: bool = r\n            .pfadd(\"group:1\", &[\"andy\", \"cameron\", \"david\"])\n            .expect(\"Failed to add items to group:1\");\n        println!(\"{group1_added}\"); // >>> true\n\n        let group1: usize = r.pfcount(\"group:1\").expect(\"Failed to count group:1\");\n        println!(\"{group1}\"); // >>> 3\n\n        let group2_added: bool = r\n            .pfadd(\"group:2\", &[\"kaitlyn\", \"michelle\", \"paolo\", \"rachel\"])\n            .expect(\"Failed to add items to group:2\");\n        println!(\"{group2_added}\"); // >>> true\n\n        let group2: usize = r.pfcount(\"group:2\").expect(\"Failed to count group:2\");\n        println!(\"{group2}\"); // >>> 4\n\n        let _: () = r\n            .pfmerge(\"both_groups\", &[\"group:1\", \"group:2\"])\n            .expect(\"Failed to merge HyperLogLogs\");\n        println!(\"OK\"); // >>> OK\n\n        let both_groups: usize = r\n            .pfcount(\"both_groups\")\n            .expect(\"Failed to count both_groups\");\n        println!(\"{both_groups}\"); // >>> 7",
      "section_id": "set-cardinality"
    }
  ]
}
