Bloom Filter in Express.js (With Real Example and Dry Run Explained)

🧠 What is a Bloom Filter?

A Bloom Filter is a probabilistic data structure used to test whether an element might be present in a set. It’s fast, lightweight, and extremely memory-efficient.

However, it can return false positives (saying “exists” when it doesn’t) but never false negatives (it will never miss an existing element).

Think of it like a quick “maybe checker” — if it says something doesn’t exist, it’s 100% true; if it says something exists, it probably does.


⚙️ Why Use a Bloom Filter in Backend Development

In backend systems, especially user-heavy applications like eCommerce sites, you often need to check for duplicates — usernames, emails, or product IDs.

A typical solution might look like:

SELECT * FROM users WHERE username = 'nilesh';

But that means querying your database every time — which becomes slow as data grows.

A Bloom Filter avoids this by:

  • Storing tiny bit flags (0 or 1) in memory.
  • Using hash functions to check if an entry might already exist.
  • Giving O(1) constant-time lookups.

Result: fewer DB reads, faster user registration, and better performance.


🛒 Your Real eCommerce Use Case

You built an Express.js eCommerce website, where users register with unique usernames.

During registration:

  1. You validate the form (ensure username is alphanumeric).
  2. Then, before hitting the database, you check your Bloom Filter.
  3. If the Bloom Filter says “probably exists,” you reject the registration.
  4. If it says “not found,” you allow registration and add the username to the Bloom Filter.

This saves you unnecessary DB lookups while ensuring speed and scalability.


🧱 Implementing a Basic Bloom Filter in Express.js (Functional Approach)

You didn’t use class-based syntax — you wrote a clean, minimal function-based implementation, perfect for beginners.

Let’s go step-by-step 👇


Step 1: Setup Express.js Project

Run the following commands:

mkdir bloom-filter-demo
cd bloom-filter-demo
npm init -y
npm install express body-parser crypto

Create a file called server.js.


Step 2: Create a Simple Bloom Filter

Here’s a minimal Bloom Filter using plain functions and an array.

const crypto = require("crypto");

// Step 1: Initialize filter
const FILTER_SIZE = 200; 
const bloom = new Array(FILTER_SIZE).fill(0);

// Step 2: Hash function
function getHash(value, seed) {
  const hash = crypto.createHash("md5").update(value + seed).digest("hex");
  return parseInt(hash, 16) % FILTER_SIZE;
}

// Step 3: Add to filter
function addToBloomFilter(value) {
  const positions = [getHash(value, 1), getHash(value, 2), getHash(value, 3)];
  positions.forEach((pos) => (bloom[pos] = 1));
}

// Step 4: Check existence
function mightExist(value) {
  const positions = [getHash(value, 1), getHash(value, 2), getHash(value, 3)];
  return positions.every((pos) => bloom[pos] === 1);
}

Step 3: Integrate Bloom Filter with Express.js

Now connect it to your registration logic.

const express = require("express");
const bodyParser = require("body-parser");

const app = express();
app.use(bodyParser.json());

// Temporary storage
const users = [];

app.post("/register", (req, res) => {
  const { username } = req.body;

  // Validate username (alphanumeric)
  if (!/^[a-z0-9]+$/i.test(username)) {
    return res.status(400).json({ message: "Username must be alphanumeric." });
  }

  // Check Bloom Filter
  if (mightExist(username)) {
    return res.status(400).json({ message: "Username probably exists!" });
  }

  // Otherwise, register and add to Bloom Filter
  users.push(username);
  addToBloomFilter(username);

  return res.status(201).json({ message: "User registered successfully!" });
});

app.listen(3000, () => console.log("✅ Server running on port 3000"));

🧮 Dry Run Example – Username: “nileshblogtech”

Let’s manually simulate how this works step-by-step:


Step 1: User tries to register with username “nileshblogtech”

  • The code calls mightExist("nileshblogtech")
  • Initially, the Bloom Filter is empty (all 0’s).
  • It calculates three hash positions using seeds 1, 2, and 3.

Let’s say (for demonstration):

getHash("nileshblogtech", 1) → 83
getHash("nileshblogtech", 2) → 141
getHash("nileshblogtech", 3) → 27

Now we check these positions:

  • bloom[83] = 0
  • bloom[141] = 0
  • bloom[27] = 0

Since at least one of them is 0, it means:

“Username definitely does not exist.”

Bloom Filter in Express.js (with Real Example) – A Simple Yet Powerful Way to Prevent Duplicate Usernames
Bloom Filter in Express.js (with Real Example) – A Simple Yet Powerful Way to Prevent Duplicate Usernames

✅ Registration proceeds.


Step 2: Adding “nileshblogtech” to Bloom Filter

Now we call addToBloomFilter("nileshblogtech").

It marks these same 3 positions:

bloom[83] = 1
bloom[141] = 1
bloom[27] = 1

Now, the Bloom Filter remembers “something” exists in those slots.


Step 3: User tries again with “nileshblogtech”

When the same username is submitted again:

  • mightExist("nileshblogtech") checks the same positions:
bloom[83] = 1
bloom[141] = 1
bloom[27] = 1

All are 1, so it returns:

“Probably exists!”

⚠️ Registration is rejected with message:

{
  "message": "Username probably exists!"
}

Step 4: What if another username like “nilesh123” tries to register?

If the hash positions are, say:

bloom[83] = 1
bloom[90] = 0
bloom[150] = 0

Because not all bits are 1, it correctly says:

“Username definitely doesn’t exist.”

And allows registration.


🔍 Testing Your Setup

Now run your app:

node server.js

Then test with Postman or curl:

✅ First registration

POST http://localhost:3000/register
Content-Type: application/json

{
  "username": "nileshblogtech"
}

Response:

{
  "message": "User registered successfully!"
}

⚠️ Second registration

POST http://localhost:3000/register
Content-Type: application/json

{
  "username": "nileshblogtech"
}

Response:

{
  "message": "Username probably exists!"
}

🧩 Advantages of Using Bloom Filter in Express.js

AdvantageDescription
Instant LookupChecks duplicates in O(1) time.
💾 Memory EfficientUses bits, not actual objects.
🚀 ScalableWorks well even for millions of entries.
🧱 Less DB LoadReduces redundant DB queries during registration.

⚠️ Limitations of This Basic Implementation

LimitationDescription
⚠️ False PositivesMight occasionally block a unique username.
No DeletionOnce a username is added, it can’t be removed.
⚙️ Static SizeYou need to choose filter size wisely.

🧠 How to Improve This Further

Here are some ways you can evolve your setup:

  1. Use Redis for Shared Filter:
    Store your Bloom Filter in Redis to share across multiple backend instances.
  2. Rebuild Periodically:
    Refresh your filter daily or weekly to remove “stale” false positives.
  3. Use Counting Bloom Filters:
    These allow deletions by maintaining counts instead of simple bits.
  4. Use Libraries:
    Try bloom-filters or bloomfilter.js for optimized, production-ready versions.

FAQs – Bloom Filter in Express.js

1. What happens if my Bloom Filter gets full?
You’ll see more false positives. You can increase its size or reinitialize it.

2. Can Bloom Filters replace databases?
No. They are a pre-check layer, not a replacement for real storage.

3. Why multiple hash functions?
Multiple hashes reduce collision chances and improve accuracy.

4. Is it safe to rely on Bloom Filter for uniqueness?
It’s safe for performance checks but you should still verify in the database for final confirmation.

5. Can I store this Bloom Filter in Redis or MongoDB?
Yes — you can serialize the bit array and store it anywhere.

6. What’s the ideal size for 10,000 users?
Roughly 10× that number in bits (around 100,000 bits) is a good start.


🏁 Conclusion

You’ve now built a simple yet effective Bloom Filter in Express.js — no classes, no extra dependencies, just smart use of hashing and arrays.

This implementation:

  • Checks usernames instantly.
  • Prevents duplicate entries.
  • Reduces database load.

Your dry run for “nileshblogtech” clearly shows how Bloom Filters mark and identify potential duplicates — making them perfect for backend optimization in real-world apps like eCommerce platforms.

5 thoughts on “Bloom Filter in Express.js (With Real Example and Dry Run Explained)”

  1. This is super helpful! I was struggling with optimizing my registration flow in Node.js. Your example using plain functions instead of classes made it way easier to follow.

  2. One small question — what happens if two different usernames hash to the same bit positions? Wouldn’t that cause issues?

  3. Loved this! I tried the same setup with Redis for shared memory and it worked perfectly across my load-balanced servers. Thanks for the inspiration 🙌

  4. Just curious — why did you choose MD5 for hashing? Would using SHA256 or something else change the result?

  5. Thanks for this detailed post. Do you plan to cover Counting Bloom Filters next? I think that’d be useful for systems where data can be deleted.

Comments are closed.

Scroll to Top