<?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: Yadab Sutradhar</title>
    <description>The latest articles on DEV Community by Yadab Sutradhar (@yadab_sutradhar).</description>
    <link>https://dev.to/yadab_sutradhar</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%2F2668333%2Fe1e50845-6eb7-45e3-ab9b-39733e380ae4.png</url>
      <title>DEV Community: Yadab Sutradhar</title>
      <link>https://dev.to/yadab_sutradhar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yadab_sutradhar"/>
    <language>en</language>
    <item>
      <title>Building an ML-Powered Notification Router on AWS: A Production Architecture Guide</title>
      <dc:creator>Yadab Sutradhar</dc:creator>
      <pubDate>Wed, 08 Apr 2026 06:20:56 +0000</pubDate>
      <link>https://dev.to/yadab_sutradhar/building-an-ml-powered-notification-router-on-aws-a-production-architecture-guide-42fm</link>
      <guid>https://dev.to/yadab_sutradhar/building-an-ml-powered-notification-router-on-aws-a-production-architecture-guide-42fm</guid>
      <description>&lt;p&gt;Author Bio: ML Engineer specializing in real-time ML systems and serverless architectures on AWS. Built production notification routing systems, processing millions of events daily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;The Problem&lt;/li&gt;
&lt;li&gt;Solution Architecture&lt;/li&gt;
&lt;li&gt;Core Components&lt;/li&gt;
&lt;li&gt;ML Pipeline&lt;/li&gt;
&lt;li&gt;Implementation&lt;/li&gt;
&lt;li&gt;Lessons Learned&lt;/li&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;What’s Next&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Sending notifications at the wrong time is like knocking on someone’s door at 3 AM.&lt;/p&gt;

&lt;p&gt;Even if the message is important — timing matters.&lt;/p&gt;

&lt;p&gt;In this article, I’ll walk you through building a production-grade, ML-powered notification routing engine that predicts the optimal send time for each user based on their historical engagement patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We’ll Build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Real-time ML inference system using Amazon SageMaker&lt;/li&gt;
&lt;li&gt;Event-driven architecture processing millions of events&lt;/li&gt;
&lt;li&gt;Automated ML training pipeline with feedback loops&lt;/li&gt;
&lt;li&gt;Infrastructure as Code using AWS CDK&lt;/li&gt;
&lt;li&gt;Cost-optimized serverless system&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AWS Lambda (Java 21 + SnapStart)&lt;/li&gt;
&lt;li&gt;Amazon SageMaker (XGBoost)&lt;/li&gt;
&lt;li&gt;AWS Glue (PySpark ETL)&lt;/li&gt;
&lt;li&gt;Amazon Kinesis Data Streams&lt;/li&gt;
&lt;li&gt;DynamoDB&lt;/li&gt;
&lt;li&gt;EventBridge Scheduler&lt;/li&gt;
&lt;li&gt;AWS CDK (TypeScript)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Notification Fatigue
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Business Challenge
&lt;/h3&gt;

&lt;p&gt;Modern applications send billions of notifications daily.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50–70% of notifications go unread&lt;/li&gt;
&lt;li&gt;User churn increases by 30% due to notification fatigue&lt;/li&gt;
&lt;li&gt;Engagement rates vary 5–10x depending on timing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Traditional Approaches
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;“Send at 9 AM local time”&lt;/li&gt;
&lt;li&gt;“Send when user was last active”&lt;/li&gt;
&lt;li&gt;“Batch and send at fixed intervals”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These approaches fail to account for individual user behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Real-time prediction (&amp;lt;500ms latency)&lt;/li&gt;
&lt;li&gt;Personalized decision per user&lt;/li&gt;
&lt;li&gt;Scale to millions of events&lt;/li&gt;
&lt;li&gt;Continuous learning via feedback&lt;/li&gt;
&lt;li&gt;Cost optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  System Flows
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Event Ingestion (real-time)&lt;/li&gt;
&lt;li&gt;Decision &amp;amp; Scheduling (real-time)&lt;/li&gt;
&lt;li&gt;ML Training Pipeline (batch, daily)&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%2Fbvatwxvj0wyla7vx2ngk.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%2Fbvatwxvj0wyla7vx2ngk.png" alt="ML Smart Notification Routing Engine Complete Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Principles
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Event-Driven &amp;amp; Decoupled
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Kinesis for streaming&lt;/li&gt;
&lt;li&gt;Services communicate via events&lt;/li&gt;
&lt;li&gt;Independent scaling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Serverless-First
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lambda for compute&lt;/li&gt;
&lt;li&gt;DynamoDB for storage&lt;/li&gt;
&lt;li&gt;No infrastructure management&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ML Feedback Loop
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Delivery outcomes feed training&lt;/li&gt;
&lt;li&gt;Daily retraining&lt;/li&gt;
&lt;li&gt;Continuous improvement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Event Ingestion (Control Plane)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accepts user events (clicks, sends, etc.)&lt;/li&gt;
&lt;li&gt;Streams data to Kinesis&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Decisions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Partition by userId → ordered processing&lt;/li&gt;
&lt;li&gt;Async processing → low latency&lt;/li&gt;
&lt;li&gt;SnapStart → reduced cold start&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Event Processing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Stores raw data in S3 (data lake)&lt;/li&gt;
&lt;li&gt;Updates DynamoDB user profiles&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Decisions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Dual writes (S3 + DynamoDB)&lt;/li&gt;
&lt;li&gt;Atomic counters&lt;/li&gt;
&lt;li&gt;Partitioned storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Decision Service (Real-Time ML)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Predicts optimal send time&lt;/li&gt;
&lt;li&gt;Calls SageMaker endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Flow:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fetch user profile&lt;/li&gt;
&lt;li&gt;Evaluate each hour in time window&lt;/li&gt;
&lt;li&gt;Score each candidate time&lt;/li&gt;
&lt;li&gt;Select best hour&lt;/li&gt;
&lt;li&gt;Schedule notification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  ML Pipeline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  End-to-End Flow
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;S3 Raw → Glue ETL → Features → SageMaker Training → Model → Endpoint&lt;br&gt;
↑____________________________________________________________↓&lt;br&gt;
………………………..Feedback Loop (Clicks, Opens)…………………….&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Feature Engineering
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hour of day&lt;/li&gt;
&lt;li&gt;Click rate (last 7 days)&lt;/li&gt;
&lt;li&gt;Number of sends per hour&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Model Choice: XGBoost
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fast inference (&amp;lt;50ms)&lt;/li&gt;
&lt;li&gt;Excellent for tabular data&lt;/li&gt;
&lt;li&gt;Built-in SageMaker support&lt;/li&gt;
&lt;li&gt;Handles overfitting well&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Orchestration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;EventBridge → daily trigger&lt;/li&gt;
&lt;li&gt;Step Functions → workflow&lt;/li&gt;
&lt;li&gt;Glue → feature generation&lt;/li&gt;
&lt;li&gt;SageMaker → training&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;
&lt;h3&gt;
  
  
  Implementation Highlights
&lt;/h3&gt;
&lt;h2&gt;
  
  
  DynamoDB (Single Table Design)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USER#user_12345"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PROFILE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lastSeenAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"counters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"events"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1523&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"notifications_sent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"notifications_clicked"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single read operation&lt;/li&gt;
&lt;li&gt;Atomic updates&lt;/li&gt;
&lt;li&gt;Cost-efficient&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Infrastructure as Code (CDK)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Version-controlled infrastructure&lt;/li&gt;
&lt;li&gt;Reproducible deployments&lt;/li&gt;
&lt;li&gt;Type-safe configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;
&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Feature Mismatch
&lt;/h3&gt;

&lt;p&gt;Training features ≠ inference features → model breaks&lt;/p&gt;

&lt;p&gt;👉 Always keep features consistent&lt;/p&gt;
&lt;h3&gt;
  
  
  Data Format Issues
&lt;/h3&gt;

&lt;p&gt;CSV vs Parquet mismatch → failed training&lt;/p&gt;

&lt;p&gt;👉 Standardize data formats&lt;/p&gt;
&lt;h3&gt;
  
  
  Wrong Event Types
&lt;/h3&gt;

&lt;p&gt;Incorrect filters → zero training data&lt;/p&gt;

&lt;p&gt;👉 Validate data pipelines&lt;/p&gt;

&lt;p&gt;[NOTE: Actively updating this part]&lt;/p&gt;
&lt;h3&gt;
  
  
  SageMaker Mode Confusion
&lt;/h3&gt;

&lt;p&gt;Mixing built-in + custom training → broken setup&lt;/p&gt;

&lt;p&gt;👉 Choose one approach&lt;/p&gt;
&lt;h3&gt;
  
  
  Time Window Bugs
&lt;/h3&gt;

&lt;p&gt;Using all-time data instead of last 7 days&lt;/p&gt;

&lt;p&gt;👉 Always explicitly filter time windows&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;
&lt;h2&gt;
  
  
  Performance &amp;amp; Cost
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;API latency (p50): 180ms&lt;/li&gt;
&lt;li&gt;Inference latency: 45ms&lt;/li&gt;
&lt;li&gt;Throughput: 5,000 events/sec&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Cost
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Under Estimation(1M events/day)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;
&lt;h2&gt;
  
  
  Optimizations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lambda SnapStart&lt;/li&gt;
&lt;li&gt;DynamoDB on-demand&lt;/li&gt;
&lt;li&gt;S3 intelligent tiering&lt;/li&gt;
&lt;li&gt;Small SageMaker instances&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...&lt;/p&gt;
&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multi-Armed Bandits (better optimization)&lt;/li&gt;
&lt;li&gt;Multi-channel prediction (email vs SMS vs push)&lt;/li&gt;
&lt;li&gt;A/B testing framework&lt;/li&gt;
&lt;li&gt;Feature Store integration&lt;/li&gt;
&lt;li&gt;Model monitoring &amp;amp; drift detection&lt;/li&gt;
&lt;li&gt;AutoML integration&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building ML systems is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;10% modeling and 90% engineering&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The real challenges are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data pipelines&lt;/li&gt;
&lt;li&gt;Feature consistency&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Feedback loops&lt;/li&gt;
&lt;li&gt;Production debugging&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use event-driven architecture&lt;/li&gt;
&lt;li&gt;Keep training and inference features aligned&lt;/li&gt;
&lt;li&gt;Prefer managed ML services&lt;/li&gt;
&lt;li&gt;Use Infrastructure as Code&lt;/li&gt;
&lt;li&gt;Optimize costs early&lt;/li&gt;
&lt;li&gt;Always implement feedback loops&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;Have you built similar systems?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What challenges did you face?&lt;/li&gt;
&lt;li&gt;How do you ensure feature consistency?&lt;/li&gt;
&lt;li&gt;Let’s discuss 👇&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Yadab-Sd" rel="noopener noreferrer"&gt;
        Yadab-Sd
      &lt;/a&gt; / &lt;a href="https://github.com/Yadab-Sd/smart-notification-routing-engine" rel="noopener noreferrer"&gt;
        smart-notification-routing-engine
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Smart Notification Routing Engine&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ML-Powered Intelligent Notification Delivery System with Real-Time Optimization&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://aws.amazon.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bbde0f927baad6fe359bca2db93b5c73f25119c4d1c20f1103a85bfa2e10558d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4157532d436c6f75642532304e61746976652d6f72616e67653f6c6f676f3d616d617a6f6e2d617773" alt="AWS"&gt;&lt;/a&gt;
&lt;a href="https://openjdk.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/25cd21cb8d26b2420f704784d8eab3dd87d2fbcbdb5b6468a5c1b717d6170997/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4a6176612d32312d626c75653f6c6f676f3d6f70656e6a646b" alt="Java"&gt;&lt;/a&gt;
&lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d717c4c3cabacd00006931699eedabb519b521941d1dfafaf87cdb308ae6a96d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547970655363726970742d352e782d626c75653f6c6f676f3d74797065736372697074" alt="TypeScript"&gt;&lt;/a&gt;
&lt;a href="https://www.python.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e5eecfe4ec6b155a7983d7ff645f47c9d9a3b4aea51000246ba907c24cd8b2ab/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31302d677265656e3f6c6f676f3d707974686f6e" alt="Python"&gt;&lt;/a&gt;
&lt;a href="https://aws.amazon.com/sagemaker/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/03c6a531f1532442840ad871e6b87ee77d461241cc8f576399ddbf8c3305dcc8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d4c2d415753253230536167654d616b65722d627269676874677265656e" alt="SageMaker"&gt;&lt;/a&gt;
&lt;a href="https://github.com/Yadab-Sd/smart-notification-routing-engine" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/667361307776210b564a007f69a84f226e380d5080f2930be0473e40816c2621/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5374617475732d416374697665253230446576656c6f706d656e742d626c7565" alt="Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Project Status&lt;/strong&gt;: 🚧 Active Development - Core infrastructure and ML pipeline implemented. Performance benchmarking and production validation in progress.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;A &lt;strong&gt;production-grade, enterprise-scale notification routing engine&lt;/strong&gt; designed to leverage machine learning for optimizing message delivery timing and channel selection. This system addresses the critical problem of notification fatigue by intelligently predicting when users are most likely to engage with notifications, with projected &lt;strong&gt;engagement rate improvements of 40-60%&lt;/strong&gt; compared to traditional uniform delivery strategies.&lt;/p&gt;
&lt;p&gt;Built entirely on AWS serverless architecture, the system processes millions of events, trains ML models nightly, and serves real-time predictions with sub-second latency—all while maintaining strict security, observability, and cost optimization standards.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Key Capabilities&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🤖 ML-Driven Send-Time Optimization&lt;/strong&gt;: XGBoost models predict optimal delivery windows per user&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📊 Real-Time Feature Engineering&lt;/strong&gt;: Apache Spark ETL pipelines transform raw events into ML features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⚡ Sub-Second&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yadab-Sd/smart-notification-routing-engine" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #AWS #MachineLearning #SageMaker #Serverless #MLOps #XGBoost #EventDriven #CDK&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>mlops</category>
      <category>aws</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>Email Sender Service</title>
      <dc:creator>Yadab Sutradhar</dc:creator>
      <pubDate>Sun, 26 Jan 2025 02:52:43 +0000</pubDate>
      <link>https://dev.to/yadab_sutradhar/email-sender-service-gg1</link>
      <guid>https://dev.to/yadab_sutradhar/email-sender-service-gg1</guid>
      <description>&lt;p&gt;&lt;a href="https://www.npmjs.com/package/job-email-sender" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; &lt;a href="https://github.com/Yadab-Sd/job-email-sender" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📧 Description
&lt;/h2&gt;

&lt;p&gt;A simple Node.js application that sends emails using the &lt;code&gt;nodemailer&lt;/code&gt; package. This service ensures smooth email delivery with minimal setup.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lightweight and customizable codebase.&lt;/li&gt;
&lt;li&gt;Designed to be beginner-friendly.&lt;/li&gt;
&lt;li&gt;Easy to configure.&lt;/li&gt;
&lt;li&gt;Helpful for job seekers to send emails to hiring managers and recruiters with bulk/batch for free!&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🛠️ Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before starting, make sure you have the following installed on your system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; (v18 or higher)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt; or &lt;strong&gt;yarn&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 - Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;job-email-sender
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add job-email-sender
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 - Configuration
&lt;/h3&gt;

&lt;p&gt;Add this code to your program file-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-email-service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Example- `gmail`, `yahoo` etc.&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-email@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// your email address (sender/from)&lt;/span&gt;
  &lt;span class="na"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-email-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// your app password for your email account&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-display-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notes:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Replace placeholders like &lt;code&gt;your-email@example.com&lt;/code&gt;, &lt;code&gt;your-display-name&lt;/code&gt;, with your actual details.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;gmail&lt;/code&gt;, &lt;code&gt;yahoo&lt;/code&gt; etc. in &lt;code&gt;service&lt;/code&gt; placeholder. Whereever is your actual email account in.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;pass&lt;/code&gt;, this is not your email login password. It is a app password which can be collected from your email account. For details follow-&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Enable App Passwords:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Yahoo : Follow &lt;a href="https://help.yahoo.com/kb/SLN15241.html" rel="noopener noreferrer"&gt;instructions&lt;/a&gt; to get app password for yahoo mail.&lt;/p&gt;

&lt;p&gt;Gmail : Follow &lt;a href="https://knowledge.workspace.google.com/kb/how-to-create-app-passwords-000009237" rel="noopener noreferrer"&gt;Google App Password&lt;/a&gt; to get app password.&lt;/p&gt;

&lt;p&gt;Other Services : Follow their own instructions to get app password.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 3 - Apply
&lt;/h3&gt;

&lt;p&gt;For JavaScript Users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EmailSender&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;job-email-sender&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For TypeScript Users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;EmailSender&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;job-email-sender&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Construct &amp;amp; send&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailSender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EmailSender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emailConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;receiver-name@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Don&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello ${name}, this is your email content!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// you can add html here. Example - 'Hello ${name}, &amp;lt;p&amp;gt;&amp;lt;b&amp;gt;this&amp;lt;/b&amp;gt; is a test email!&amp;lt;/p&amp;gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is Your Email subject&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;emailSender&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendEmails&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[!Note] Remember !&lt;br&gt;
This package is primarily for backend usage only. Because it is node.js based and that doesn't run on browser.&lt;br&gt;
If you want to use this on frontend (browser), you need to run your frontend on server (server-side rendering) using express.&lt;/p&gt;

&lt;p&gt;[!Note]&lt;br&gt;
Managing attachments - Coming soon...&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>javascript</category>
      <category>recruiting</category>
      <category>jobsearching</category>
      <category>bulkemail</category>
    </item>
  </channel>
</rss>
