<?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: Girish bari</title>
    <description>The latest articles on DEV Community by Girish bari (@gigbee).</description>
    <link>https://dev.to/gigbee</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%2F4083493%2F488276dc-7e6e-4e22-b17b-ba485a309772.png</url>
      <title>DEV Community: Girish bari</title>
      <link>https://dev.to/gigbee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gigbee"/>
    <language>en</language>
    <item>
      <title>Tricked Claude to Design the system, Not to Code (part 1)</title>
      <dc:creator>Girish bari</dc:creator>
      <pubDate>Sat, 17 Oct 2026 11:15:12 +0000</pubDate>
      <link>https://dev.to/gigbee/tricked-claude-to-design-the-system-not-to-code-part-1-559o</link>
      <guid>https://dev.to/gigbee/tricked-claude-to-design-the-system-not-to-code-part-1-559o</guid>
      <description>&lt;p&gt;I wanted to explore automation for a few days, and I came across&lt;br&gt;
&lt;strong&gt;Minicor&lt;/strong&gt;, a company working on the problem of automating legacy&lt;br&gt;
software. The problem is simple, and I'm still figuring out whether it&lt;br&gt;
is worth solving at this level. But I learned a lot while building this&lt;br&gt;
project.&lt;/p&gt;

&lt;p&gt;Let's start.&lt;/p&gt;

&lt;p&gt;Folks who want to see and demonstration&lt;br&gt;
&lt;a href="https://github.com/Girishbari/SmartPay" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://smartpay-qtuk.onrender.com/" rel="noopener noreferrer"&gt;live link&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/Girishbari/SmartPay/blob/143cad2bfe68505530b5cd3eb4c3dcf4662451ad/README.md" rel="noopener noreferrer"&gt;watch the demo&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding the pain
&lt;/h2&gt;

&lt;p&gt;I can relate to this problem from my experience working with Tally back&lt;br&gt;
in 2018. You simply couldn't automate many scenarios easily. Tally was&lt;br&gt;
licensed software, and in practice, some people used pirated versions.&lt;br&gt;
The software generally had to be installed on a particular system, and&lt;br&gt;
there often wasn't an API available for the workflow you wanted to&lt;br&gt;
automate. Add network restrictions and other environment-specific&lt;br&gt;
limitations, and the problem becomes even harder.&lt;/p&gt;

&lt;p&gt;There may be more integration options available today, but the broader&lt;br&gt;
question remains:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we reduce manual work and make these workflows faster when the&lt;br&gt;
software wasn't designed to be automated?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's where Minicor caught my attention.&lt;/p&gt;
&lt;h2&gt;
  
  
  How I understand Minicor
&lt;/h2&gt;

&lt;p&gt;As far as I understand it, Minicor breaks the problem into a few steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; A business requests an automation for a particular scenario.&lt;/li&gt;
&lt;li&gt; Minicor understands the requirements and how a human performs that
task.&lt;/li&gt;
&lt;li&gt; It creates and tests a workflow for that scenario.&lt;/li&gt;
&lt;li&gt; Once the business approves the workflow, Minicor exposes an API.&lt;/li&gt;
&lt;li&gt; The business can call that API whenever it needs the task performed.&lt;/li&gt;
&lt;/ol&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%2Fh3fwhbhwowx0afte6iim.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%2Fh3fwhbhwowx0afte6iim.png" alt="Illustration of the legacy software automation&lt;br&gt;
workflow" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I took this idea and started building &lt;strong&gt;SmartPay&lt;/strong&gt;: an automation that&lt;br&gt;
creates an invoice on every API hit.&lt;/p&gt;

&lt;p&gt;But how would we design this for more users and more legacy systems&lt;br&gt;
while keeping the system reliable?&lt;/p&gt;

&lt;p&gt;While working through distributed-system design, I realised something&lt;br&gt;
important: before jumping into requirements and fancy features, we&lt;br&gt;
should first track the events and understand how a payload moves from&lt;br&gt;
one service to another.&lt;/p&gt;

&lt;p&gt;Here is the flow I want to design:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Business demonstrates a scenario → Engine proposes a workflow →&lt;br&gt;
Business approves it → API is exposed → Business calls the API →&lt;br&gt;
Workflow succeeds, fails, or ends in an uncertain state.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That last part is important. What happens if the system fails and we&lt;br&gt;
don't know whether the invoice was created?&lt;/p&gt;
&lt;h2&gt;
  
  
  Functional requirements
&lt;/h2&gt;

&lt;p&gt;Let's derive the requirements from the flow above.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Record scenarios and workflows.&lt;/strong&gt; We need to capture the business
process that the automation is supposed to perform.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Store workflow definitions and parameter mappings.&lt;/strong&gt; Each workflow
should define the inputs it needs and how those inputs map to the
actions being performed.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Publish workflows for business review.&lt;/strong&gt; The business should be
able to review the workflow name, parameters, outputs, and commit
step before approving it.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Expose an API for each published workflow.&lt;/strong&gt; Every API request
must be validated against that workflow's rules.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Provide a monitoring dashboard.&lt;/strong&gt; Business users should be able to
inspect runs and take action when something needs attention.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Out of scope for now:&lt;/strong&gt; AI-based repair when a screen changes, editing&lt;br&gt;
workflow steps through the UI, tenant and user management, and billing&lt;br&gt;
for the automation engine itself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Non-functional requirements
&lt;/h2&gt;

&lt;p&gt;Every non-functional requirement should support one or more of the&lt;br&gt;
functional requirements above.&lt;/p&gt;

&lt;p&gt;Before defining them, let's look at two important failure scenarios.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Graceful handling of saves
&lt;/h3&gt;

&lt;p&gt;We need to understand what happens when a workflow is interrupted while&lt;br&gt;
saving an invoice.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Uncertain outcomes
&lt;/h3&gt;

&lt;p&gt;Consider two scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The business's system stops &lt;strong&gt;before&lt;/strong&gt; the invoice is saved.&lt;/li&gt;
&lt;li&gt;  The business's system stops &lt;strong&gt;after&lt;/strong&gt; the invoice is saved, but
before our engine records the success.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the second scenario, the invoice exists, but our system may not know&lt;br&gt;
that. If we retry blindly, we could create a duplicate invoice and&lt;br&gt;
potentially charge a customer twice.&lt;/p&gt;

&lt;p&gt;This leads to an important requirement: &lt;strong&gt;we must prevent duplicate&lt;br&gt;
invoice creation, even when the outcome of an execution is uncertain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We need idempotency for each invoice operation. We also need to&lt;br&gt;
distinguish a confirmed failure from an uncertain outcome. An uncertain&lt;br&gt;
run should be reconciled before another attempt is allowed to create an&lt;br&gt;
invoice.&lt;/p&gt;

&lt;p&gt;In other words, we shouldn't blindly retry an API request just because&lt;br&gt;
we didn't receive a successful response. The same request needs a stable&lt;br&gt;
idempotency key, and the execution system must check whether the&lt;br&gt;
intended effect already happened.&lt;/p&gt;

&lt;p&gt;We also need to store the workflow definitions, parameters, mappings,&lt;br&gt;
and rules in a structured format, such as JSON, so every API request can&lt;br&gt;
be validated against the workflow it invokes.&lt;/p&gt;
&lt;h3&gt;
  
  
  What about response time?
&lt;/h3&gt;

&lt;p&gt;How fast should an API request be?&lt;/p&gt;

&lt;p&gt;Here's the catch: we can optimise everything on our side, but what if&lt;br&gt;
the target application itself is slow?&lt;/p&gt;

&lt;p&gt;We might be able to acknowledge a request in under 500 ms, but that does&lt;br&gt;
&lt;strong&gt;not&lt;/strong&gt; mean the invoice will be created in 500 ms. The legacy billing&lt;br&gt;
application may take much longer to complete the operation.&lt;/p&gt;

&lt;p&gt;So we need to distinguish between &lt;strong&gt;API response time&lt;/strong&gt; and &lt;strong&gt;workflow&lt;br&gt;
completion time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This leads to another question: what happens when we receive 50,000&lt;br&gt;
requests?&lt;/p&gt;

&lt;p&gt;That's what I spent a good few hours discussing with Claude. Before&lt;br&gt;
getting into the cost estimates, I found it useful to understand a few&lt;br&gt;
basic concepts.&lt;/p&gt;
&lt;h3&gt;
  
  
  Cost estimation
&lt;/h3&gt;

&lt;p&gt;Before going deeper, here are three questions that help us estimate&lt;br&gt;
capacity and cost.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;What it helps estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rate&lt;/td&gt;
&lt;td&gt;How quickly do requests arrive?&lt;/td&gt;
&lt;td&gt;API requests per second, database writes per second, and queue throughput&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency&lt;/td&gt;
&lt;td&gt;How many operations are in progress at once?&lt;/td&gt;
&lt;td&gt;Worker slots, connections, and memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;How much data does each operation produce?&lt;/td&gt;
&lt;td&gt;Storage, bandwidth, and cost&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A useful mental model is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Rate&lt;/strong&gt; = number of requests ÷ time window&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Concurrency&lt;/strong&gt; ≈ rate × average processing time&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Storage&lt;/strong&gt; = number of records × average record size&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also need to ask one more question: &lt;strong&gt;what is the limiting resource,&lt;br&gt;
and where does that limit live?&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Let's assume 50,000 requests
&lt;/h3&gt;

&lt;p&gt;Suppose we need to process &lt;strong&gt;50,000 invoices in four hours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Four hours is 14,400 seconds, so the average arrival rate is:&lt;/p&gt;

&lt;p&gt;50,000 ÷ 14,400 ≈ &lt;strong&gt;3.5 requests per second&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now suppose the legacy application takes around &lt;strong&gt;30 seconds to create&lt;br&gt;
one invoice&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Using Little's Law:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrency ≈ 3.5 requests/second × 30 seconds ≈ 104 concurrent runs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At first, that doesn't sound too bad. Around 104 runs in progress seems&lt;br&gt;
manageable from an infrastructure perspective.&lt;/p&gt;

&lt;p&gt;But there is another constraint.&lt;/p&gt;
&lt;h3&gt;
  
  
  The legacy system is the bottleneck
&lt;/h3&gt;

&lt;p&gt;Let's assume each business has one legacy application instance, and that&lt;br&gt;
instance can create only one invoice at a time.&lt;/p&gt;

&lt;p&gt;If one business needs to process 500 invoices, and each invoice takes 30&lt;br&gt;
seconds:&lt;/p&gt;

&lt;p&gt;500 × 30 seconds = 15,000 seconds = &lt;strong&gt;4 hours and 10 minutes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That already exceeds our four-hour target.&lt;/p&gt;

&lt;p&gt;Adding more API servers or workers won't solve this problem. If the&lt;br&gt;
target application can process only one invoice at a time, the&lt;br&gt;
automation engine cannot make that individual instance process invoices&lt;br&gt;
faster simply by adding infrastructure.&lt;/p&gt;

&lt;p&gt;The real capacity limit is the concurrency supported by each business's&lt;br&gt;
legacy application. Increasing it may require additional sessions,&lt;br&gt;
application instances, or licences, depending on what the software and&lt;br&gt;
the business environment support.&lt;/p&gt;

&lt;p&gt;So the important question isn't simply, "How do we handle 50,000&lt;br&gt;
requests?"&lt;/p&gt;

&lt;p&gt;It is: &lt;strong&gt;How many requests can arrive, how long does each workflow take,&lt;br&gt;
and how many workflows can each target system safely execute at once?&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Do we need Kafka or SQS?
&lt;/h3&gt;

&lt;p&gt;For this assumed workload, we don't necessarily need Kafka or SQS from&lt;br&gt;
day one.&lt;/p&gt;

&lt;p&gt;We could start with &lt;strong&gt;PostgreSQL as the durable job queue&lt;/strong&gt;, keeping the&lt;br&gt;
execution record and queue state in the same database. That reduces the&lt;br&gt;
number of systems we need to operate and helps keep the execution state&lt;br&gt;
consistent with the queued work.&lt;/p&gt;
&lt;h2&gt;
  
  
  Core entities
&lt;/h2&gt;

&lt;p&gt;Before implementing the system, I want to identify the core entities and&lt;br&gt;
how they relate to each other.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Entity&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tenant&lt;/td&gt;
&lt;td&gt;The business using our platform&lt;/td&gt;
&lt;td&gt;Sharma Traders&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client App&lt;/td&gt;
&lt;td&gt;The application calling our API&lt;/td&gt;
&lt;td&gt;A script or Postman during development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target App&lt;/td&gt;
&lt;td&gt;The software product being automated&lt;/td&gt;
&lt;td&gt;Tally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target Instance&lt;/td&gt;
&lt;td&gt;A particular installation or instance of that software&lt;/td&gt;
&lt;td&gt;Sharma Traders' Tally installation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;The automation worker that performs the task&lt;/td&gt;
&lt;td&gt;A worker operating the target application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workflow&lt;/td&gt;
&lt;td&gt;The task the business wants to automate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;create-invoice&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Demonstration&lt;/td&gt;
&lt;td&gt;The recorded example from which a workflow version was created&lt;/td&gt;
&lt;td&gt;A recording of a person creating an invoice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run&lt;/td&gt;
&lt;td&gt;One invocation of a workflow, including its input and outcome&lt;/td&gt;
&lt;td&gt;A request to create a particular invoice&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At a high level, the relationships look 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;Tenant
├── Target Instances ──&amp;gt; Target App
│   └── Agents
├── Client Apps
│   └── Runs ──&amp;gt; Target Instance
└── Workflows
    └── Demonstrations

Workflow ──&amp;gt; Runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where I'll pause for now
&lt;/h2&gt;

&lt;p&gt;I wanted to keep this part focused on understanding the problem, tracing&lt;br&gt;
a request through the system, and identifying the first set of design&lt;br&gt;
constraints. There is still a lot to explore, especially around queue&lt;br&gt;
implementation, failure recovery, and cost estimation.&lt;/p&gt;

&lt;p&gt;I'll leave the deeper implementation details for the next part. For now,&lt;br&gt;
the main lesson is simple: &lt;strong&gt;before scaling the automation engine,&lt;br&gt;
understand the workflow, track the request end to end, and identify the&lt;br&gt;
system that actually limits throughput.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>automation</category>
      <category>claude</category>
    </item>
    <item>
      <title>How $exists can become cuplrit in MONGODB?</title>
      <dc:creator>Girish bari</dc:creator>
      <pubDate>Sun, 30 Aug 2026 12:14:10 +0000</pubDate>
      <link>https://dev.to/gigbee/how-can-exists-can-become-cuplrit-in-mongodb-3onk</link>
      <guid>https://dev.to/gigbee/how-can-exists-can-become-cuplrit-in-mongodb-3onk</guid>
      <description>&lt;p&gt;From a long time I had a doubt that &lt;code&gt;$exists&lt;/code&gt; makes the query inefficient, but I was not confident enough to conclude any points soon. Today I observed something which made me confident to not use &lt;code&gt;$exists&lt;/code&gt; going forward in my queries until it is extremely (I mean extremely) needed.&lt;/p&gt;

&lt;p&gt;Here is why?&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="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XXXXXXXXXXXX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;marketing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;attempt_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$exists&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Motive :- Get all the records from &lt;code&gt;event_logs&lt;/code&gt; where &lt;code&gt;attempt_count&lt;/code&gt; exists (docs which has field &lt;code&gt;attempt_count: 1/2/3&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even after giving the hint :- Query was &lt;strong&gt;inefficient&lt;/strong&gt;&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="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;event_logs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XXXXXXXXXXXX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;marketing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;attempt_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$exists&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;project_id_1_source_1_attempt_count_1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;explain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;executionStats&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;The point here is why it is &lt;strong&gt;checking 16k&lt;/strong&gt; totalkeys and totalDocs while the nreturned is 9k, the ideal case should be totalkeys = totalDocs = nreturned (making it a covered query)&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%2F6cnq9ll64531v4ia8k2t.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%2F6cnq9ll64531v4ia8k2t.png" alt="when using exist" width="537" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solution for above issue :-&lt;/p&gt;

&lt;p&gt;Use range &lt;code&gt;$gte&lt;/code&gt;, &lt;code&gt;$gt&lt;/code&gt;, &lt;code&gt;$lte&lt;/code&gt;, &lt;code&gt;$lt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I used this query:&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="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;event_logs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XXXXXXXXXXXX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;marketing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;attempt_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$gte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;project_id_1_source_1_attempt_count_1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;explain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;executionStats&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;Magic 🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CULPRIT:- &lt;code&gt;$exists&lt;/code&gt;&lt;/strong&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%2F9ejzhee7ztb4duissvf7.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%2F9ejzhee7ztb4duissvf7.png" alt="when not using exist" width="799" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reason by LLM:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Point of &lt;code&gt;$exists&lt;/code&gt;:&lt;/strong&gt; It tells us the field presence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;-&amp;gt; Now according to our requirement it seems to be very much perfect to use it. What if I convert &lt;code&gt;$exists&lt;/code&gt; into something as a range?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;In layman terms:&lt;/strong&gt; What I have understood is that &lt;code&gt;$exists&lt;/code&gt; makes your query search the needed as well as not needed docs because &lt;code&gt;$exists&lt;/code&gt; tells MongoDB cursor to check all the docs where there is no &lt;code&gt;attempt_count&lt;/code&gt; and check all the docs where there is &lt;code&gt;attempt_count&lt;/code&gt; exists and then it is only able to segregate between those sets of docs to give you the required &lt;code&gt;nReturned&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&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%2Fyi63i76ybdj3fs3cc4pg.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%2Fyi63i76ybdj3fs3cc4pg.png" alt="final proof" width="798" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;My needed docs were 9k and not 16k, but &lt;code&gt;$exists&lt;/code&gt; made the query scan all 16k docs (around 8k &lt;strong&gt;extra&lt;/strong&gt;).&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>When DSA Solved Our AWS Scaling Problem</title>
      <dc:creator>Girish bari</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:33:26 +0000</pubDate>
      <link>https://dev.to/gigbee/when-dsa-solved-our-aws-scaling-problem-213n</link>
      <guid>https://dev.to/gigbee/when-dsa-solved-our-aws-scaling-problem-213n</guid>
      <description>&lt;h2&gt;
  
  
  When DSA Solved Our AWS Scaling Problem
&lt;/h2&gt;

&lt;p&gt;In the age of AI, it feels like DSA is slowly disappearing from day-to-day development.&lt;/p&gt;

&lt;p&gt;You can ask an AI to generate a queue, configure an AWS service, or write a retry mechanism in seconds.&lt;/p&gt;

&lt;p&gt;But there is one thing AI cannot remove from engineering:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraints.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And when constraints appear, DSA suddenly becomes relevant again.&lt;/p&gt;

&lt;p&gt;At our startup, we often solve problems in a scalable way. But scalability doesn't always mean adding another AWS service. Sometimes, the solution is simply &lt;strong&gt;using the existing components differently&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You usually don't recognize a DSA concept in a real-world system until someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Why are we doing it this way?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question led us to a surprisingly simple solution to an AWS scheduling problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: We Were Running Out of Schedules
&lt;/h2&gt;

&lt;p&gt;Imagine we have a large number of jobs.&lt;/p&gt;

&lt;p&gt;Each job can fail and needs to be retried on subsequent days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parent Job
   │
   ├── Retry 1 → +1 day
   ├── Retry 2 → +2 days
   └── Retry 3 → +3 days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initially, this seems straightforward.&lt;/p&gt;

&lt;p&gt;We can simply create an EventBridge schedule for every retry.&lt;/p&gt;

&lt;p&gt;But then scale enters the picture.&lt;/p&gt;

&lt;p&gt;We encountered a situation where, for every &lt;strong&gt;6,000 jobs&lt;/strong&gt;, we needed to create &lt;strong&gt;3 separate EventBridge schedules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6,000 jobs
   ×
3 retry schedules
   =
18,000 schedules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine increasing the workload.&lt;/p&gt;

&lt;p&gt;What happens if we have &lt;strong&gt;10,000 jobs&lt;/strong&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 jobs
    ×
3 retries
    =
30,000 schedules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And what if this keeps growing?&lt;/p&gt;

&lt;p&gt;We eventually run into EventBridge scheduling limits.&lt;/p&gt;

&lt;p&gt;The obvious solution might be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's add another AWS component."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But our senior asked a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Can we solve this using a sliding window?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That was the interesting part.&lt;/p&gt;




&lt;h2&gt;
  
  
  First, What Is a Sliding Window?
&lt;/h2&gt;

&lt;p&gt;A sliding window is a technique where we don't process the entire dataset at once.&lt;/p&gt;

&lt;p&gt;Instead, we maintain a smaller &lt;strong&gt;active window&lt;/strong&gt; and continuously move it forward.&lt;/p&gt;

&lt;p&gt;For example, imagine these jobs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Day 1   Day 2   Day 3   Day 4   Day 5   Day 6   Day 7
 ├───────┼───────┼───────┼───────┼───────┼───────┼───────┤
         [──────────── Window ────────────]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As time moves forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before:

Day 1   Day 2   Day 3   Day 4   Day 5   Day 6   Day 7
         [──────── Window ────────]


After:

Day 1   Day 2   Day 3   Day 4   Day 5   Day 6   Day 7
                 [──────── Window ────────]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important idea is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We don't need to keep scheduling everything forever.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We only care about jobs relevant to the current time window.&lt;/p&gt;

&lt;p&gt;That observation changes how we think about the EventBridge problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  What If We Don't Schedule Every Retry?
&lt;/h2&gt;

&lt;p&gt;This was the key idea.&lt;/p&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"When should this retry happen?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and creating an EventBridge schedule for that future date...&lt;/p&gt;

&lt;p&gt;we ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Which retries are supposed to happen today?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That small change removes the need to schedule every future retry individually.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Original Approach
&lt;/h2&gt;

&lt;p&gt;Let's say today is &lt;strong&gt;August 18&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A parent job runs today.&lt;/p&gt;

&lt;p&gt;Its retries are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;August 18
   │
   ├── Retry 1 → August 19
   ├── Retry 2 → August 20
   └── Retry 3 → August 21
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The traditional approach is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              EventBridge
                  │
       ┌──────────┼──────────┐
       ▼          ▼          ▼
    Aug 19     Aug 20     Aug 21
    Retry 1    Retry 2    Retry 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For every parent job, we create future schedules.&lt;/p&gt;

&lt;p&gt;This is where the number of schedules grows rapidly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Sliding Window Approach
&lt;/h2&gt;

&lt;p&gt;Now let's change the perspective.&lt;/p&gt;

&lt;p&gt;Instead of scheduling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Retry 1 → tomorrow
Retry 2 → day after tomorrow
Retry 3 → three days later
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we maintain a &lt;strong&gt;daily execution window&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every day, we ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Which existing parent jobs have a retry due today?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then we execute those retries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    TODAY
                      │
                      ▼
             ┌─────────────────┐
             │   Sliding       │
             │    Window       │
             └────────┬────────┘
                      │
        ┌─────────────┼─────────────┐
        ▼             ▼             ▼
     Retry 1       Retry 2       Retry 3
      due today     due today     due today
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;EventBridge no longer needs to know about every individual retry.&lt;/p&gt;

&lt;p&gt;It only needs to trigger the &lt;strong&gt;parent job&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  But What About Jobs From Previous Days?
&lt;/h2&gt;

&lt;p&gt;This is where the idea becomes interesting.&lt;/p&gt;

&lt;p&gt;Suppose a parent job ran &lt;strong&gt;3 days ago&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parent Job
August 15
   │
   ├── Retry 1 → August 16
   ├── Retry 2 → August 17
   └── Retry 3 → August 18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Today is August 18.&lt;/p&gt;

&lt;p&gt;The third retry is due &lt;strong&gt;today&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Under the traditional approach, we would have created a schedule on August 15 for the retry that should execute on August 18.&lt;/p&gt;

&lt;p&gt;But we don't need to do that anymore.&lt;/p&gt;

&lt;p&gt;Instead, today's sliding window discovers it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;August 15        August 16        August 17        August 18
Parent Job       Retry 1          Retry 2          Retry 3
    │                │                │                │
    └────────────────┴────────────────┴────────────────┘
                                                     ▲
                                                     │
                                                   TODAY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system simply asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"What retries are due on August 18?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Parent Job: August 15
Retry:      3
Due:        August 18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it executes it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Trick
&lt;/h2&gt;

&lt;p&gt;This is the entire trick:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't schedule the future retries.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌─────────────────────┐
                 │   Daily Trigger     │
                 └──────────┬──────────┘
                            │
                            ▼
                 ┌─────────────────────┐
                 │  Current Time      │
                 │     Window         │
                 └──────────┬──────────┘
                            │
                            ▼
              ┌──────────────────────────┐
              │ Find retries due today   │
              └────────────┬─────────────┘
                           │
                 ┌─────────┴─────────┐
                 ▼                   ▼
            Retry due             Not due
                 │                   │
                 ▼                   ▼
              Execute              Ignore

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Scales Better
&lt;/h2&gt;

&lt;p&gt;The important difference is &lt;strong&gt;what we are scheduling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Number of schedules grows&lt;br&gt;
with the number of jobs&lt;/p&gt;

&lt;p&gt;Now the number of EventBridge schedules is no longer directly proportional to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Number of Jobs × Number of Retries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, EventBridge becomes the mechanism that wakes up the &lt;strong&gt;scheduler/processor&lt;/strong&gt;, while the application determines which work actually needs to happen.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Lesson
&lt;/h2&gt;

&lt;p&gt;The interesting part of this problem wasn't really EventBridge.&lt;/p&gt;

&lt;p&gt;It was recognizing that we were using EventBridge to solve a problem that didn't necessarily belong there.&lt;/p&gt;

&lt;p&gt;We initially thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We need to schedule millions of future events."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The better question was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Do we actually need to schedule millions of future events?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the answer was no.&lt;/p&gt;

&lt;p&gt;We only needed to know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What needs to happen today?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is where a simple DSA concept like &lt;strong&gt;sliding window&lt;/strong&gt; becomes a practical system-design technique.&lt;/p&gt;




&lt;h2&gt;
  
  
  DSA Is Not Dead
&lt;/h2&gt;

&lt;p&gt;This is why I don't think DSA is disappearing from software engineering.&lt;br&gt;
Sometimes the answer is a sophisticated distributed system.&lt;/p&gt;

&lt;p&gt;And sometimes...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;it's a sliding window.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The important skill isn't memorizing DSA patterns.&lt;/p&gt;

</description>
      <category>dsa</category>
      <category>development</category>
      <category>webdev</category>
      <category>career</category>
    </item>
  </channel>
</rss>
