<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: zeyad daowd</title>
    <description>The latest articles on DEV Community by zeyad daowd (@zeyaddaowd).</description>
    <link>https://dev.to/zeyaddaowd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4106142%2Fbfbfbc4a-c31f-43b9-a4cf-5d4a2741fc77.jpg</url>
      <title>DEV Community: zeyad daowd</title>
      <link>https://dev.to/zeyaddaowd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zeyaddaowd"/>
    <language>en</language>
    <item>
      <title>Count-Min Sketch</title>
      <dc:creator>zeyad daowd</dc:creator>
      <pubDate>Wed, 02 Sep 2026 15:18:06 +0000</pubDate>
      <link>https://dev.to/zeyaddaowd/count-min-sketch-5a17</link>
      <guid>https://dev.to/zeyaddaowd/count-min-sketch-5a17</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Count-Min Sketch lets you estimate how many times something occurred in a massive stream, using a fixed-size matrix (~54KB) instead of a hashmap that could reach terabytes, with a small error that's bounded with high probability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Imagine the following leetcode-style problem:&lt;/p&gt;

&lt;p&gt;You have a stream of visitors to a website, each visitor can visit your website multiple times. The target is relatively simple: you need to know how many times a specific person visited your website.&lt;/p&gt;

&lt;p&gt;Looks easy - we can use a hashmap and increment the entry for the user by each visit. Lookups would be &lt;code&gt;O(1)&lt;/code&gt;, which is good, and you'd need &lt;code&gt;O(n)&lt;/code&gt; memory, where &lt;code&gt;n&lt;/code&gt; is the number of unique users - which looks good as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where it breaks
&lt;/h3&gt;

&lt;p&gt;Now imagine you are tracking post visibility for a social media application. We can just store a hashmap for each post - now the space complexity would be &lt;code&gt;O(n * m)&lt;/code&gt;, where &lt;code&gt;m&lt;/code&gt; is the number of posts.&lt;/p&gt;

&lt;p&gt;Imagine there are 1 million users and 1 million posts, and we want to keep an exact counter for every user/post pair. Even ignoring the storage required for the keys and the overhead of the hashmap itself, we'd need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 × 10^6 × 1 × 10^6 × 4 bytes = 4 × 10^12 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's more than &lt;strong&gt;3.5 terabytes&lt;/strong&gt; of memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt; hashmap storage explodes when trying to count over a lot of data. That's where Count-Min Sketch comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Count-Min Sketch
&lt;/h2&gt;

&lt;p&gt;Count-Min Sketch utilizes a fixed 2D matrix that doesn't grow with input size, with width &lt;code&gt;W&lt;/code&gt; and depth &lt;code&gt;D&lt;/code&gt;. The width and depth can be chosen by setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;w = ⌈e/ε⌉
d = ⌈ln 1/δ⌉
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;e&lt;/code&gt; = 2.718 (Euler's constant)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;δ&lt;/code&gt; = probability of failure&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ε&lt;/code&gt; = error rate&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; Count-Min Sketch is a probabilistic data structure - it doesn't provide the accurate answer (this was my first time hearing about probabilistic data structures). If you found that interesting take a look onto Hyperloglog and bloom filters&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It guarantees the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;The estimated frequency is never smaller than the true frequency.&lt;/li&gt;
&lt;li&gt;With probability at least &lt;code&gt;1 - δ&lt;/code&gt;, the estimate is at most &lt;code&gt;ε × N&lt;/code&gt; larger than the true frequency, where &lt;code&gt;N&lt;/code&gt; is the total number of observations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;true count ≤ estimated count ≤ true count + ε * N&lt;/code&gt; (with probability ≥ &lt;code&gt;1 - δ&lt;/code&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have a depth × width matrix, we'll also have some hash functions (equal to depth).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faaa3a1nl7q04rbob4v1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faaa3a1nl7q04rbob4v1m.png" alt="Empty CMS Matrix" width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For each input, we do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="mf"&gt;0.&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hash_i&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;
    &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(Each row has its own independent hash function - &lt;code&gt;hash_i&lt;/code&gt; refers to the hash function for row &lt;code&gt;i&lt;/code&gt;.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgh6yy8lfj2ilqn237xkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgh6yy8lfj2ilqn237xkv.png" alt="First Element Insertion" width="799" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After some input entries, you might have the following matrix:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9cymsb3sd6c8xwlcqhv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9cymsb3sd6c8xwlcqhv3.png" alt="CMS Lookup" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Looking up a frequency
&lt;/h3&gt;

&lt;p&gt;If you want to get the frequency of element &lt;code&gt;E1&lt;/code&gt;, you look at the hashed values:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hash function&lt;/th&gt;
&lt;th&gt;Hashed value % width&lt;/th&gt;
&lt;th&gt;Matrix entry&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hashFunction1(E1)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;matrix[0][1]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hashFunction2(E1)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;matrix[1][6]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hashFunction3(E1)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;matrix[2][3]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hashFunction4(E1)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;matrix[3][1]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result = min(3, 2, 2, 2) = 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the final frequency, you take the minimum of the values in the corresponding matrix entries: &lt;strong&gt;2&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the minimum?
&lt;/h3&gt;

&lt;p&gt;Every counter we look at contains the true count of &lt;code&gt;E1&lt;/code&gt; plus any counts added by other elements that happened to collide with it. Therefore, collisions can only make a counter larger, never smaller. Taking the minimum across the rows gives us the best estimate among the counters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why give up exact answers?
&lt;/h2&gt;

&lt;p&gt;At first, giving up exact answers might sound like a bad idea. But imagine you're trying to find the top 100 most-viewed posts out of billions of events. You probably don't care whether a post was viewed 1,002,341 or 1,002,350 times - you care that you can identify the posts being viewed a lot, without storing a counter for every possible item.&lt;/p&gt;

&lt;p&gt;That's where the tradeoff becomes useful: a tiny amount of error in exchange for much less memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example calculation for high accuracy
&lt;/h3&gt;

&lt;p&gt;For failure probability &lt;code&gt;δ = 0.01&lt;/code&gt; (confidence = 99%) and error rate &lt;code&gt;ε = 0.001&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;width ≈ &lt;strong&gt;2,718&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;depth = &lt;strong&gt;5&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;total matrix size = &lt;code&gt;5 × 2718 × 4 bytes&lt;/code&gt; = &lt;strong&gt;54,360 bytes (&amp;lt; 54 KB)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The time complexity for retrieval is &lt;code&gt;O(depth)&lt;/code&gt;, which is a constant - so basically &lt;code&gt;O(1)&lt;/code&gt; as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where is this used in the industry?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Redis&lt;/strong&gt; - Count-Min Sketch is implemented natively as part of Redis' core probabilistic data structures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network analysis&lt;/strong&gt; - tracking IP addresses to detect DDoS attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy hitters&lt;/strong&gt; - finding items that occur more than a threshold of the stream.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, next time a counting problem mentions "billions of events," you know there's a structure for exactly that.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/dsa/count-min-sketch-in-java-with-examples/" rel="noopener noreferrer"&gt;Count-Min Sketch in Java with Examples - GeeksforGeeks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Count%E2%80%93min_sketch" rel="noopener noreferrer"&gt;Count–min sketch - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/search?utf8=%E2%9C%93&amp;amp;q=count-min-sketch"&gt;Count-Min Sketch posts on dev.to&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/latest/develop/data-types/probabilistic/count-min-sketch/" rel="noopener noreferrer"&gt;Redis Docs - Count-Min Sketch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://singhajit.com/data-structures/count-min-sketch/" rel="noopener noreferrer"&gt;singhajit.com - Count-Min Sketch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
  </channel>
</rss>
