<?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: Mahmudur Rahman</title>
    <description>The latest articles on DEV Community by Mahmudur Rahman (@mahmud007).</description>
    <link>https://dev.to/mahmud007</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F722410%2F07191028-f218-469e-87a0-dbeeb6f2e4b3.jpeg</url>
      <title>DEV Community: Mahmudur Rahman</title>
      <link>https://dev.to/mahmud007</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mahmud007"/>
    <language>en</language>
    <item>
      <title>🎉 Goodbye asyncHandler: Native Async Support in Express 5</title>
      <dc:creator>Mahmudur Rahman</dc:creator>
      <pubDate>Wed, 14 May 2025 09:44:20 +0000</pubDate>
      <link>https://dev.to/mahmud007/goodbye-asynchandler-native-async-support-in-express-5-2o9p</link>
      <guid>https://dev.to/mahmud007/goodbye-asynchandler-native-async-support-in-express-5-2o9p</guid>
      <description>&lt;p&gt;Express has long been a staple in the Node.js ecosystem, powering thousands of APIs and web applications. However, until recently, handling asynchronous route logic in Express has always felt a bit clunky — particularly when it comes to error handling in async functions.&lt;/p&gt;

&lt;p&gt;But good news: Express 5 finally brings first-class support for async/await with native promise error handling! That means you can now write clean, modern async route handlers without wrappers like asyncHandler().&lt;br&gt;
In this post, we’ll walk through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤯 The problem in Express 4&lt;/li&gt;
&lt;li&gt;✅ The solution in Express 5&lt;/li&gt;
&lt;li&gt;🛠️ Migration tips&lt;/li&gt;
&lt;li&gt;🧪 Real-world example&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🤯 The Problem in Express 4&lt;/strong&gt;&lt;br&gt;
In Express 4, writing async handlers directly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/users', async (req, res) =&amp;gt; {
  const users = await getUsersFromDb(); // what if this throws?
  res.json(users);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;would result in an unhandled promise rejection if getUsersFromDb() throws or rejects.&lt;/p&gt;

&lt;p&gt;Why? Because Express 4 does not understand that async functions return promises. It doesn’t await them or catch their rejections automatically.&lt;br&gt;
&lt;strong&gt;Workaround: Using asyncHandler()&lt;/strong&gt;&lt;br&gt;
To deal with this, most devs used a helper like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const asyncHandler = fn =&amp;gt; (req, res, next) =&amp;gt; {
  Promise.resolve(fn(req, res, next)).catch(next);
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you’d wrap every route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/users', asyncHandler(async (req, res) =&amp;gt; {
  const users = await getUsersFromDb();
  res.json(users);
}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clunky, right?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ The Fix in Express 5&lt;/strong&gt;&lt;br&gt;
In Express 5, this boilerplate is no longer needed. You can now write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/users', async (req, res) =&amp;gt; {
  const users = await getUsersFromDb(); // if this throws, Express 5 will catch it
  res.json(users);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉 Express 5 automatically awaits promises and forwards errors to the error handler!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧪 Real-World Example&lt;/strong&gt;&lt;br&gt;
Let’s say you have this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/profile', async (req, res) =&amp;gt; {
  const user = await findUserById(req.query.id);
  if (!user) throw new Error('User not found');
  res.json(user);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If anything throws (like a DB error), Express 5 will automatically send it to your error middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use((err, req, res, next) =&amp;gt; {
  console.error(err);
  res.status(500).json({ message: err.message });
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more asyncHandler. No more accidental unhandled rejections.&lt;br&gt;
&lt;strong&gt;🛠️ Migration Tips&lt;/strong&gt;&lt;br&gt;
If you're upgrading from Express 4 to 5:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove asyncHandler() wrappers — just use async route functions directly.&lt;/li&gt;
&lt;li&gt;Double-check your error middleware — Express 5 continues to use the (err, req, res, next) signature.&lt;/li&gt;
&lt;li&gt;Update your dependencies — install the latest Express version:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express@next

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;⚠️ At the time of writing, Express 5 is in beta (&lt;a href="mailto:express@5.0.0-beta.x"&gt;express@5.0.0-beta.x&lt;/a&gt;). Keep an eye on the official changelog for production readiness.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use(async (req, res, next) =&amp;gt; {
  const isValid = await validateToken(req.headers.authorization);
  if (!isValid) throw new Error('Unauthorized');
  next();
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, no try/catch needed — Express 5 has your back.&lt;br&gt;
&lt;strong&gt;🧾 Summary&lt;/strong&gt;&lt;br&gt;
✅ Express 5 brings native async/await support&lt;br&gt;
✅ No need for async wrappers&lt;br&gt;
✅ Clean, modern error handling&lt;br&gt;
✅ Works in both routes and middleware&lt;br&gt;
✅ Big win for developer experience!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📚 References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://expressjs.com/en/guide/error-handling.html" rel="noopener noreferrer"&gt;Express.js Error Handling Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://expressjs.com/en/api.html" rel="noopener noreferrer"&gt;Express 5.x API Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//What's%20New%20in%20Express.js%20v5.0"&gt;What's New in Express.js v5.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.toExpress%20Error%20Handling%20Patterns"&gt;Express Error Handling Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.toHandling%20Errors%20with%20Async/Await%20in%20Express"&gt;Handling Errors with Async/Await in Express&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add Basic Error Handling to an Express 5 App&lt;br&gt;
&lt;strong&gt;🙌 Conclusion&lt;/strong&gt;&lt;br&gt;
Express 5 may not seem flashy at first glance, but this feature alone dramatically simplifies writing clean, maintainable APIs with modern JavaScript. If you’ve been juggling asyncHandler utilities in Express 4, it's time to celebrate and simplify.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;br&gt;
✍️ Follow me on &lt;a href="https://dev.to/mahmud007"&gt;Dev.to&lt;/a&gt; or &lt;a href="https://github.com/Mahmud-007" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; for more Node.js tips, architecture guides, and backend tutorials.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Billions of Username Lookups Have Handled</title>
      <dc:creator>Mahmudur Rahman</dc:creator>
      <pubDate>Thu, 10 Apr 2025 14:04:11 +0000</pubDate>
      <link>https://dev.to/mahmud007/how-billions-of-username-lookups-have-handled-3imb</link>
      <guid>https://dev.to/mahmud007/how-billions-of-username-lookups-have-handled-3imb</guid>
      <description>&lt;p&gt;When you sign up for a new app and see a message like "This username is already taken," it feels like a tiny inconvenience. But behind the scenes, this simple check is a massive engineering challenge, especially when dealing with billions of users.&lt;/p&gt;

&lt;p&gt;So how do companies like Google, Amazon, and Meta check username availability instantly without hammering their databases? Let’s dive into the smart strategies and data structures they use to make this process lightning-fast and scalable.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Redis Hashmaps: Speedy In-Memory Lookups&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Redis hashmaps are a favorite for exact match lookups. In this structure, each username is stored as a field with a lightweight value like a user ID. A query checks whether the username exists in this in-memory store — delivering results in microseconds.&lt;/p&gt;

&lt;p&gt;However, memory is finite, so Redis hashmaps are typically used to cache only frequently accessed or recent usernames.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Tries: Perfect for Prefix Matching&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you need autocomplete or want to suggest alternative usernames, tries (prefix trees) are a better choice. Tries store characters as paths, allowing searches to scale with the length of the string rather than the total dataset size. They also naturally support prefix queries.&lt;/p&gt;

&lt;p&gt;To optimize memory, systems often use compressed tries like Radix Trees or limit tries to hot or recently entered usernames.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. B+ Trees: Efficient Ordered Lookups&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;B+ trees are common in relational databases for indexing. They support fast, sorted lookups in O(log n) time and are ideal for queries that need range or alphabetical order, like finding the next available username.&lt;br&gt;
Here's how:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ordered Traversal: B+ trees store data in a sorted order and keep all values in the leaf nodes linked together. This allows the system to perform fast range queries and in-order traversal.&lt;/li&gt;
&lt;li&gt;Next Best Option: If a desired username (e.g., alex) is taken, the system can quickly traverse to the next lexicographically available usernames (like alex1, alex_, alex123, etc.) without scanning the entire dataset.&lt;/li&gt;
&lt;li&gt;Prefix Search: B+ trees can also support partial matches. For example, to suggest usernames starting with john, the system can navigate directly to the leaf node where entries like john1, john_doe, or johnny reside.&lt;/li&gt;
&lt;li&gt;Efficient Suggestions: Since B+ trees maintain balance and logarithmic lookup times, even on massive datasets, they’re a great fit for generating sorted and relevant suggestions quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Databases like MySQL, MongoDB, and Google Cloud Spanner use B+ trees (or similar structures) to power high-performance queries over massive datasets.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Bloom Filters: The First Line of Defense&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Bloom filters are a probabilistic, memory-efficient way to check if a username might exist. If a Bloom filter says a name isn’t present, you can be sure it’s not. If it might be present, you do a deeper check in the database.&lt;/p&gt;

&lt;p&gt;They use very little memory (e.g., 1.2 GB for 1 billion usernames with 1% false positives), making them perfect for large-scale systems. Systems like Cassandra use them to avoid unnecessary disk lookups.&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.amazonaws.com%2Fuploads%2Farticles%2F77535v7p58m19wr30q37.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.amazonaws.com%2Fuploads%2Farticles%2F77535v7p58m19wr30q37.png" alt="Complexity Analysis" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of Layering: System Architecture in Action
&lt;/h2&gt;

&lt;p&gt;In practice, companies combine all these tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load Balancing: Global (DNS-based like AWS Route 53) and local (like NGINX or AWS ELB) load balancers route requests efficiently.&lt;/li&gt;
&lt;li&gt;Bloom Filters: Fast, in-memory filters weed out usernames that definitely don’t exist.&lt;/li&gt;
&lt;li&gt;Caches (Redis/Memcached): Recently checked usernames are stored here for instant access.&lt;/li&gt;
&lt;li&gt;Distributed Databases (Cassandra/DynamoDB): If all else fails, the system queries the authoritative source.&lt;/li&gt;
&lt;/ul&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.amazonaws.com%2Fuploads%2Farticles%2Fevc3scp6kjntr0obr3ei.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.amazonaws.com%2Fuploads%2Farticles%2Fevc3scp6kjntr0obr3ei.png" alt="Combined workflow" width="800" height="313"&gt;&lt;/a&gt;&lt;br&gt;
This tiered architecture minimizes latency, distributes load, and scales effortlessly across billions of users.&lt;/p&gt;

&lt;p&gt;What seems like a simple check — "Is this username taken?" — is powered by a beautiful mix of computer science and engineering. From Bloom filters and tries to Redis caches and distributed databases, every component plays a role in delivering a seamless user experience.&lt;/p&gt;

&lt;p&gt;Next time you pick a username, remember the complex machinery behind that instant response.&lt;/p&gt;

&lt;p&gt;Inspired by a brilliant system design breakdown on &lt;a href="https://www.youtube.com/watch?v=_l5Q5kKHtR8" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;. Want to dive deeper into similar topics? Let me know what you'd like to explore next!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
