<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Think in Systems]]></title><description><![CDATA[Think in Systems]]></description><link>https://thinkinsystems.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6aa308d41b7498f5632bc234/4d68b186-4ff9-4ac7-a277-7cb341c520b4.png</url><title>Think in Systems</title><link>https://thinkinsystems.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 29 Sep 2026 08:54:55 GMT</lastBuildDate><atom:link href="https://thinkinsystems.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[10 Critical Software Architecture Gaps That Quietly Become Business Problems]]></title><description><![CDATA[Introduction
Most software systems do not fail because someone forgot to write code.
They fail because the system gradually accumulates architectural gaps.
A feature is added.
Then another.
A database]]></description><link>https://thinkinsystems.hashnode.dev/10-critical-software-architecture-gaps</link><guid isPermaLink="true">https://thinkinsystems.hashnode.dev/10-critical-software-architecture-gaps</guid><category><![CDATA[software architecture]]></category><category><![CDATA[System Design]]></category><category><![CDATA[Backend Engineering]]></category><category><![CDATA[scalability]]></category><category><![CDATA[Reliability]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Abhijeet]]></dc:creator><pubDate>Thu, 24 Sep 2026 04:39:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/06677a3e-d5a4-4cc5-8e5a-832be4a8ef9c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction</h2>
<p>Most software systems do not fail because someone forgot to write code.</p>
<p>They fail because the system gradually accumulates <strong>architectural gaps</strong>.</p>
<p>A feature is added.</p>
<p>Then another.</p>
<p>A database query is written quickly.</p>
<p>An external API is called synchronously.</p>
<p>A secret is placed in configuration.</p>
<p>A log statement is added when production breaks.</p>
<p>An AI feature starts as a simple API call and stays that way even after the application becomes business critical.</p>
<p>Individually, these decisions may look harmless.</p>
<p>Together, they create a system that becomes increasingly difficult to scale, operate, secure, and change.</p>
<p>The interesting part is that many of these problems are invisible when the system is small.</p>
<p>A system with 100 users may tolerate poor indexing.</p>
<p>A system with one server may tolerate local session state.</p>
<p>A system with one dependency may survive synchronous calls.</p>
<p>A system with low traffic may survive direct database reads and writes.</p>
<p>The architecture starts showing its weaknesses when <strong>load, complexity, dependencies, data volume, or business criticality increases</strong>.</p>
<p>In this article, I will look at 10 architecture gaps that commonly appear in production systems.</p>
<p>This is not a guide to fixing them.</p>
<p>The objective here is simpler:</p>
<p><strong>Recognize the gap before it becomes an outage, security incident, scaling problem, or revenue problem.</strong></p>
<p>The corresponding fixes will be covered separately in Think in Systems.</p>
<hr />
<h2>1. Monolithic Tight Coupling</h2>
<h3>The gap</h3>
<p>A monolith is not automatically a bad architecture.</p>
<p>The problem begins when components inside the system become so tightly coupled that a change or failure in one area can unexpectedly affect another.</p>
<p>Imagine a system containing:</p>
<pre><code class="language-plaintext">Chat
  |
  v
Payment
  |
  v
Order
  |
  v
Notification
</code></pre>
<p>A change in the chat module should not unexpectedly bring down payment processing.</p>
<p>Yet tightly coupled systems can create exactly this kind of blast radius.</p>
<p>A seemingly isolated change can affect shared code, shared database tables, shared transactions, shared configuration, or shared resources.</p>
<h3>Why it becomes dangerous</h3>
<p>Tight coupling increases the number of things engineers must understand before making a change.</p>
<p>The real dependency graph becomes much larger than the visible feature.</p>
<p>A developer may think:</p>
<blockquote>
<p>"I am changing the chat feature."</p>
</blockquote>
<p>The system may actually behave like:</p>
<pre><code class="language-plaintext">Chat change
     |
     +---- Shared library
     |
     +---- Shared database
     |
     +---- Shared transaction
     |
     +---- Shared configuration
     |
     +---- Payment
     |
     +---- Order
</code></pre>
<p>The result is a larger blast radius.</p>
<p>This is particularly dangerous in systems where different capabilities have different business criticality.</p>
<p>A failure in a recommendation feature should not have the same blast radius as a failure in payment processing.</p>
<h3>Signals that you may have this gap</h3>
<p>• Small changes require extensive regression testing across unrelated features</p>
<p>• Engineers are afraid to modify older modules</p>
<p>• Multiple teams depend on the same internal code or database structures</p>
<p>• Deployments frequently affect unrelated functionality</p>
<p>• A failure in one feature causes failures elsewhere</p>
<p>• Nobody can clearly explain the dependency boundaries</p>
<h3>The deeper problem</h3>
<p>The issue is not simply "monolith versus microservices."</p>
<p>A well designed monolith can have strong boundaries.</p>
<p>A poorly designed microservices system can have extremely tight coupling through synchronous dependencies, shared databases, and fragile contracts.</p>
<p>The architectural question is:</p>
<p><strong>Can one part of the system change or fail without unnecessarily affecting everything else?</strong></p>
<hr />
<h2>2. Synchronous API Chokeholds</h2>
<p>Synchronous communication is useful.</p>
<p>A client sends a request.</p>
<p>The server processes it.</p>
<p>The response comes back.</p>
<p>Simple.</p>
<p>The problem appears when complex workflows are placed entirely inside synchronous request paths.</p>
<p>Consider a brokerage order workflow:</p>
<pre><code class="language-plaintext">User
  |
  v
Order API
  |
  +--&gt; Authentication
  |
  +--&gt; Risk validation
  |
  +--&gt; Balance validation
  |
  +--&gt; Instrument validation
  |
  +--&gt; Broker validation
  |
  +--&gt; Order processing
  |
  v
Response
</code></pre>
<p>Each dependency can add latency.</p>
<p>If one dependency becomes slow, the entire request can become slow.</p>
<p>Now multiply that by thousands of concurrent requests.</p>
<p>You have created an architectural chokehold.</p>
<p>OWASP's Secure by Design guidance specifically calls out long synchronous chains across services as a reliability concern and recommends explicitly defining asynchronous semantics where appropriate.</p>
<h3>Why it becomes dangerous</h3>
<p>Synchronous chains couple the availability and latency of multiple components.</p>
<p>If:</p>
<pre><code class="language-plaintext">A → B → C → D
</code></pre>
<p>then the user facing request may depend on the combined behavior of A, B, C and D.</p>
<p>A slow dependency does not remain isolated.</p>
<p>It can consume:</p>
<p>• Threads</p>
<p>• Connections</p>
<p>• CPU</p>
<p>• Memory</p>
<p>• Connection pools</p>
<p>• Request capacity</p>
<p>Eventually, a dependency problem can become an application problem.</p>
<h3>Signals that you may have this gap</h3>
<p>• Long request chains</p>
<p>• Increasing p95 and p99 latency</p>
<p>• Requests waiting on multiple downstream services</p>
<p>• Thread pools or connection pools getting exhausted</p>
<p>• Timeouts appearing during traffic spikes</p>
<p>• User facing APIs performing too much work before returning</p>
<p>The important question is:</p>
<p><strong>Does this work really need to happen before the user receives a response?</strong></p>
<hr />
<h2>3. Hardcoded API Configurations</h2>
<p>Consider code like this:</p>
<pre><code class="language-plaintext">const API_KEY = "sk_live_123456";
const ENVIRONMENT = "production";
const PAYMENT_URL = "https://payment.example.com";
</code></pre>
<p>It looks convenient.</p>
<p>It is also an architectural and security problem.</p>
<p>Configuration and secrets are now coupled directly to application code.</p>
<p>Why it becomes dangerous</p>
<p>Source code tends to travel.</p>
<p>It can exist in:</p>
<p>• Git repositories</p>
<p>• Developer machines</p>
<p>• CI systems</p>
<p>• Build artifacts</p>
<p>• Pull requests</p>
<p>• Logs</p>
<p>• Backups</p>
<p>• Forks</p>
<p>• Old branches</p>
<p>A secret committed to a repository can remain exposed even after the line is removed.</p>
<p>The larger problem is not simply where the API key is stored.</p>
<p>It is whether the architecture has a clear separation between:</p>
<pre><code class="language-plaintext">Application Code
       |
       v
Configuration
       |
       v
Environment
       |
       v
Secrets
</code></pre>
<p>Security architecture guidance emphasizes controlled secret and key management, environment consistency, encryption, and least privilege.</p>
<p>Signals that you may have this gap</p>
<p>• API keys appear in source code</p>
<p>• Production URLs are hardcoded</p>
<p>• Developers manually change configuration before deployment</p>
<p>• Different environments require code changes</p>
<p>• Secrets are shared through chat or documents</p>
<p>• Rotating credentials requires a code deployment</p>
<p>The deeper question is:</p>
<p>Can the application change environments without changing its source code?</p>
<hr />
<h2>4. Missing Database Indexing</h2>
<p>Databases can make millions of records feel fast.</p>
<p>Until they do not.</p>
<p>Consider:</p>
<pre><code class="language-plaintext">SELECT *
FROM users
WHERE email = 'user@example.com';
</code></pre>
<p>With an appropriate index, the database may locate the relevant data efficiently.</p>
<p>Without one, the database may need to inspect a large portion of the table.</p>
<p>That difference becomes increasingly important as data grows.</p>
<h3>The scaling pattern</h3>
<p>A system might begin with:</p>
<pre><code class="language-plaintext">10,000 users
</code></pre>
<p>The query appears fast.</p>
<p>Then:</p>
<pre><code class="language-plaintext">1 million users
</code></pre>
<p>Still acceptable.</p>
<p>Then:</p>
<pre><code class="language-plaintext">50 million users
</code></pre>
<p>Suddenly, a query that looked harmless becomes expensive.</p>
<p>The application has not changed.</p>
<p>The data characteristics have.</p>
<h3>Why it becomes dangerous</h3>
<p>Slow queries consume database resources.</p>
<p>That can lead to:</p>
<pre><code class="language-plaintext">Slow Query
    |
    v
More CPU
    |
    v
More Concurrent Connections
    |
    v
Higher Latency
    |
    v
More Requests Waiting
    |
    v
Database Saturation
</code></pre>
<p>The problem can then spread to the application layer.</p>
<h3>Signals that you may have this gap</h3>
<p>• Queries become slower as data grows</p>
<p>• Full table scans appear in query plans</p>
<p>• Database CPU increases unexpectedly</p>
<p>• p95 and p99 database latency rise</p>
<p>• Application servers spend significant time waiting for database responses</p>
<p>• Queries were optimized for today's data volume rather than expected growth</p>
<p>Indexing is not simply a database optimization exercise.</p>
<p>It is an architectural consideration because <strong>data access patterns are part of system design</strong>.</p>
<hr />
<h2>5. Stateful Server Reliance</h2>
<p>Imagine a user logs in.</p>
<p>The application stores the user's session on Server A.</p>
<p>Later, the load balancer sends the next request to Server B.</p>
<p>Server B does not know about the session.</p>
<p>Now the application has a problem.</p>
<pre><code class="language-plaintext">             Load Balancer
              /          \
             /            \
        Server A        Server B
           |
      Session Data
</code></pre>
<p>This is a stateful server dependency.</p>
<p>The server is carrying information that other servers need.</p>
<h3>Why it becomes dangerous</h3>
<p>Horizontal scaling assumes that requests can be distributed across multiple instances.</p>
<p>But local state creates a dependency on a specific machine.</p>
<p>You can end up with:</p>
<pre><code class="language-plaintext">1 Server
  ↓
2 Servers
  ↓
4 Servers
  ↓
8 Servers
</code></pre>
<p>while still having an architecture that effectively behaves like:</p>
<pre><code class="language-plaintext">"This user belongs to Server A."
</code></pre>
<p>That undermines the benefits of horizontal scaling.</p>
<h3>Signals that you may have this gap</h3>
<p>• Users experience session loss after deployments</p>
<p>• Requests behave differently depending on which server receives them</p>
<p>• Scaling requires special load balancer behavior</p>
<p>• Server replacement causes user state to disappear</p>
<p>• Failover is difficult</p>
<p>• Autoscaling introduces unexpected application behavior</p>
<p>The important architectural question is:</p>
<p><strong>What state belongs to the request, and what state belongs to the system?</strong></p>
<p>That distinction becomes increasingly important as systems scale.</p>
<hr />
<h2>6. Absence of Circuit Breakers</h2>
<p>Modern applications rarely operate alone.</p>
<p>They call:</p>
<p>• Payment gateways</p>
<p>• Identity providers</p>
<p>• Banks</p>
<p>• Market data providers</p>
<p>• Email services</p>
<p>• Notification systems</p>
<p>• AI APIs</p>
<p>• Shipping providers</p>
<p>• Other internal services</p>
<p>Now imagine a downstream service becomes slow.</p>
<p>Your application continues calling it.</p>
<p>Those calls start waiting.</p>
<p>More users arrive.</p>
<p>More requests wait.</p>
<p>Threads and connections are consumed.</p>
<p>Retries may increase the load further.</p>
<p>The result can become a cascading failure.</p>
<pre><code class="language-plaintext">Third Party Slow
       |
       v
Requests Wait
       |
       v
Connection Pool Exhausted
       |
       v
Requests Queue
       |
       v
Application Slows
       |
       v
More Timeouts
       |
       v
More Retries
       |
       v
System Degradation
</code></pre>
<p>AWS describes circuit breakers as a way to stop repeatedly calling a dependency that is failing, while Microsoft similarly distinguishes circuit breakers from retries: retries attempt recovery from transient failures, while circuit breakers prevent repeated calls when failure is persistent.</p>
<h3>Why it becomes dangerous</h3>
<p>A dependency failure should ideally remain a dependency failure.</p>
<p>It should not automatically become:</p>
<pre><code class="language-plaintext">Dependency failure
        ↓
Application failure
        ↓
Platform failure
        ↓
Business outage
</code></pre>
<h3>Signals that you may have this gap</h3>
<p>• External service timeouts cause application wide latency</p>
<p>• Requests continue accumulating during dependency failures</p>
<p>• Retry storms occur</p>
<p>• Thread or connection pools become exhausted</p>
<p>• One failing service affects unrelated features</p>
<p>• There is no defined degraded mode</p>
<p>The deeper architectural question is:</p>
<p><strong>What happens inside our system when a dependency stops responding?</strong></p>
<hr />
<h2>7. Raw SQL Vulnerabilities</h2>
<p>SQL itself is not the problem.</p>
<p>Direct SQL can be perfectly valid and appropriate.</p>
<p>The problem appears when applications construct SQL using untrusted input without appropriate parameterization and validation.</p>
<p>For example:</p>
<pre><code class="language-plaintext">query =
"SELECT * FROM users WHERE id = '" + userId + "'";
</code></pre>
<p>Now application input has become part of the SQL statement itself.</p>
<p>This creates an injection risk.</p>
<p>OWASP specifically recommends defensive database practices and treats application layer injection prevention as a distinct security concern.</p>
<h3>An important distinction</h3>
<p>The architecture gap here is sometimes described as:</p>
<blockquote>
<p>"We use raw SQL."</p>
</blockquote>
<p>That is too broad.</p>
<p>Raw SQL is not inherently insecure.</p>
<p>The real concern is:</p>
<pre><code class="language-plaintext">Untrusted Input
      +
Unsafe Query Construction
      =
Injection Risk
</code></pre>
<p>Parameterized queries, safe query construction, input validation, and appropriate access controls matter more than whether the application uses an ORM.</p>
<p>An ORM can reduce certain classes of risk, but <strong>using an ORM does not automatically make an application secure</strong>.</p>
<h3>Signals that you may have this gap</h3>
<p>• SQL queries are constructed using string concatenation</p>
<p>• User input directly enters query strings</p>
<p>• Database permissions are overly broad</p>
<p>• SQL security practices vary between teams</p>
<p>• There is no standard data access layer</p>
<p>• Security testing repeatedly finds injection risks</p>
<p>The architectural question is:</p>
<p><strong>Where is the boundary between application input and database execution?</strong></p>
<hr />
<h2>8. Unbuffered Database Read and Write</h2>
<p>The database is often the center of an application.</p>
<p>That makes it tempting to send everything directly to it.</p>
<p>A checkout request arrives.</p>
<p>The application reads several records.</p>
<p>Then writes several records.</p>
<p>Another checkout arrives.</p>
<p>Then another.</p>
<p>Soon hundreds or thousands of concurrent requests are competing for the same database resources.</p>
<pre><code class="language-plaintext">Request 1 ──┐
Request 2 ──┤
Request 3 ──┤
Request 4 ──┼──&gt; Database
Request 5 ──┤
Request 6 ──┤
Request N ──┘
</code></pre>
<p>The database eventually becomes the bottleneck.</p>
<h3>Why it becomes dangerous</h3>
<p>A database has finite resources.</p>
<p>Those resources include:</p>
<p>• CPU</p>
<p>• Memory</p>
<p>• Connections</p>
<p>• Disk I/O</p>
<p>• Locks</p>
<p>• Buffer cache</p>
<p>• Query execution capacity</p>
<p>• Transaction capacity</p>
<p>If every request requires immediate database interaction, traffic growth can translate directly into database pressure.</p>
<p>This is particularly important for transaction heavy systems.</p>
<p>A sudden checkout spike can turn into database contention rather than simply higher application traffic.</p>
<h3>Signals that you may have this gap</h3>
<p>• Database connections frequently reach their limit</p>
<p>• Lock contention increases under load</p>
<p>• Write latency rises during traffic spikes</p>
<p>• Read traffic competes with critical writes</p>
<p>• Application servers spend significant time waiting for database operations</p>
<p>• The database is consistently the first component to saturate</p>
<p>The architectural question is:</p>
<p><strong>Does every piece of work need to reach the primary database immediately?</strong></p>
<p>That question is especially important when designing high throughput systems.</p>
<hr />
<h2>9. Zero Log Visibility</h2>
<p>An application can be perfectly designed on paper and still be extremely difficult to operate.</p>
<p>Production tells you what actually happened.</p>
<p>Without useful logs, metrics, traces, and monitoring, engineers are forced to reconstruct incidents from incomplete information.</p>
<p>Imagine receiving this alert:</p>
<pre><code class="language-plaintext">Payment failure rate increased.
</code></pre>
<p>Now ask:</p>
<pre><code class="language-plaintext">Which API?
Which customer?
Which region?
Which payment provider?
Which release?
Which dependency?
Which error?
When did it start?
How many requests?
Which requests failed?
What happened immediately before the failure?
</code></pre>
<p>If the system cannot answer those questions, debugging becomes guesswork.</p>
<p>OWASP's cloud security guidance emphasizes logging and monitoring for understanding system behavior and investigating security incidents.</p>
<p>Modern secure design guidance also treats observability as something that should be designed into the system rather than added only after incidents occur.</p>
<h3>Why it becomes dangerous</h3>
<p>Poor visibility increases:</p>
<p>• Mean time to detect</p>
<p>• Mean time to diagnose</p>
<p>• Mean time to recover</p>
<p>It also makes capacity planning and performance analysis harder.</p>
<p>A production system is not just:</p>
<pre><code class="language-plaintext">Code + Infrastructure
</code></pre>
<p>It is:</p>
<pre><code class="language-plaintext">Code
+
Infrastructure
+
Telemetry
+
Operational Knowledge
</code></pre>
<h3>Signals that you may have this gap</h3>
<p>• Engineers SSH into servers to investigate incidents</p>
<p>• Logs exist on individual machines</p>
<p>• Logs cannot be correlated across services</p>
<p>• Production errors lack request identifiers</p>
<p>• There are no useful latency metrics</p>
<p>• Teams discover incidents through customer complaints</p>
<p>• Nobody can explain what changed before an outage</p>
<p>The architectural question is:</p>
<p><strong>Can we understand what the system is doing while it is doing it?</strong></p>
<hr />
<h2>10. Amateur Prompt Wrapper Layouts</h2>
<p>AI applications introduce another architectural layer.</p>
<p>At first, the implementation may be extremely simple:</p>
<pre><code class="language-plaintext">User Prompt
     |
     v
LLM API
     |
     v
Response
</code></pre>
<p>That can be perfectly reasonable for an experiment.</p>
<p>The problem begins when the same architecture becomes the foundation of a production application.</p>
<p>Consider an AI workflow that performs:</p>
<pre><code class="language-plaintext">User Request
     ↓
Prompt Construction
     ↓
LLM
     ↓
Response
     ↓
Business Logic
     ↓
Database
</code></pre>
<p>What happens when the model:</p>
<p>• Returns invalid JSON?</p>
<p>• Changes the expected structure?</p>
<p>• Times out?</p>
<p>• Returns incomplete information?</p>
<p>• Produces an unexpected value?</p>
<p>• Uses more tokens than expected?</p>
<p>• Returns a response that downstream code cannot process?</p>
<p>A basic API wrapper may not have an answer.</p>
<h3>Why this is an architecture problem</h3>
<p>An LLM is a probabilistic component.</p>
<p>Traditional application components generally operate around deterministic contracts.</p>
<p>That creates a boundary problem.</p>
<p>Your application may expect:</p>
<pre><code class="language-plaintext">{
  "customer_id": "123",
  "risk": "low"
}
</code></pre>
<p>But the model may return:</p>
<pre><code class="language-plaintext">The customer appears to have a relatively low risk profile.
</code></pre>
<p>The response may be semantically useful to a human while being structurally unusable by the application.</p>
<h3>Signals that you may have this gap</h3>
<p>• AI responses are passed directly into business logic</p>
<p>• There is no structured output validation</p>
<p>• Invalid model responses can break workflows</p>
<p>• Retry behavior is undefined</p>
<p>• Provider failures are not handled explicitly</p>
<p>• Prompt changes are made without regression testing</p>
<p>• Model or provider changes can silently alter application behavior</p>
<p>• AI costs are not bounded</p>
<p>• There is no fallback when the model is unavailable</p>
<p>The architectural question is:</p>
<p><strong>What contract exists between the probabilistic AI component and the deterministic software around it?</strong></p>
<p>This is becoming one of the important architecture questions for modern AI applications.</p>
<hr />
<h2>The Common Pattern Behind All 10 Gaps</h2>
<p>These problems look unrelated.</p>
<p>They are not.</p>
<p>Look at them together.</p>
<table>
<thead>
<tr>
<th>Gap</th>
<th>What becomes fragile</th>
</tr>
</thead>
<tbody><tr>
<td>Monolithic tight coupling</td>
<td>Change and failure boundaries</td>
</tr>
<tr>
<td>Synchronous API chokeholds</td>
<td>Latency and dependency chains</td>
</tr>
<tr>
<td>Hardcoded configurations</td>
<td>Security and deployment</td>
</tr>
<tr>
<td>Missing database indexing</td>
<td>Data access performance</td>
</tr>
<tr>
<td>Stateful server reliance</td>
<td>Horizontal scaling</td>
</tr>
<tr>
<td>Missing circuit breakers</td>
<td>Failure isolation</td>
</tr>
<tr>
<td>Raw SQL vulnerabilities</td>
<td>Data security</td>
</tr>
<tr>
<td>Unbuffered database access</td>
<td>Database scalability</td>
</tr>
<tr>
<td>Zero log visibility</td>
<td>Operations and diagnosis</td>
</tr>
<tr>
<td>Weak AI wrappers</td>
<td>AI reliability and contracts</td>
</tr>
</tbody></table>
<p>There is a common theme.</p>
<p><strong>The system has not clearly defined its boundaries.</strong></p>
<p>Boundaries around:</p>
<pre><code class="language-plaintext">Components
Dependencies
Data
Configuration
State
Failures
Traffic
Security
Observability
AI behavior
</code></pre>
<p>Once those boundaries become unclear, problems start crossing them.</p>
<p>A database problem becomes an application problem.</p>
<p>An API problem becomes a user experience problem.</p>
<p>A third party outage becomes a platform outage.</p>
<p>A configuration mistake becomes a security incident.</p>
<p>An AI response becomes a business logic failure.</p>
<p>That is the real architecture problem.</p>
<hr />
<h2>Architecture Is About More Than Components</h2>
<p>When engineers discuss architecture, conversations often begin with:</p>
<blockquote>
<p>"Should we use Kafka?"</p>
</blockquote>
<blockquote>
<p>"Should we use Redis?"</p>
</blockquote>
<blockquote>
<p>"Should we use microservices?"</p>
</blockquote>
<blockquote>
<p>"Should we use Kubernetes?"</p>
</blockquote>
<blockquote>
<p>"Should we use PostgreSQL?"</p>
</blockquote>
<p>These are useful questions.</p>
<p>But they are not the first questions.</p>
<p>A better architecture discussion starts with:</p>
<pre><code class="language-plaintext">What outcome are we trying to produce?

What workloads exist?

What are the critical paths?

What can fail?

What must remain available?

What must be strongly consistent?

What can be asynchronous?

What data will grow?

What needs to scale independently?

What needs to be observable?

What happens when dependencies fail?

What happens when traffic increases?

What happens when the system behaves unexpectedly?
</code></pre>
<p>Technology choices should follow those answers.</p>
<p>Not the other way around.</p>
<hr />
<h2>A Simple Architecture Gap Review</h2>
<p>You can use these questions as a first pass over an existing system.</p>
<h3>Coupling</h3>
<p>Can one feature change without unexpectedly affecting unrelated features?</p>
<h3>Communication</h3>
<p>Which operations genuinely need synchronous execution?</p>
<h3>Configuration</h3>
<p>Can environments and secrets be managed independently from application code?</p>
<h3>Data</h3>
<p>Will the database access patterns remain efficient as data grows?</p>
<h3>State</h3>
<p>Can application instances be added or removed without losing important user state?</p>
<h3>Failure</h3>
<p>What happens when an external dependency becomes slow or unavailable?</p>
<h3>Security</h3>
<p>Can untrusted input cross into sensitive systems without appropriate controls?</p>
<h3>Capacity</h3>
<p>What happens when database traffic increases by 10x?</p>
<h3>Observability</h3>
<p>Can engineers understand an incident without guessing?</p>
<h3>AI</h3>
<p>What happens when an AI component returns an unexpected response?</p>
<p>If the answer to any of these questions is unclear, you may have an architecture gap worth investigating.</p>
<hr />
<h2>The Most Dangerous Gaps Are Often Invisible</h2>
<p>One of the biggest mistakes in architecture reviews is looking only for things that are already broken.</p>
<p>A better approach is to look for things that <strong>will become broken under a changed condition</strong>.</p>
<p>For example:</p>
<pre><code class="language-plaintext">More Users
      ↓
More Requests
      ↓
More Database Load
</code></pre>
<p>Or:</p>
<pre><code class="language-plaintext">More Dependencies
      ↓
More Failure Modes
      ↓
More Complex Failure Propagation
</code></pre>
<p>Or:</p>
<pre><code class="language-plaintext">More Data
      ↓
Different Query Characteristics
      ↓
Different Performance Profile
</code></pre>
<p>Or:</p>
<pre><code class="language-plaintext">More AI Usage
      ↓
More Probabilistic Behavior
      ↓
More Need for Explicit Contracts
</code></pre>
<p>Architecture is therefore not just about how the system behaves today.</p>
<p>It is about how the system behaves when its environment changes.</p>
<hr />
<h2>Architecture Gaps Become Business Gaps</h2>
<p>Eventually, technical problems become business problems.</p>
<p>A slow database can become:</p>
<p><strong>Slow checkout.</strong></p>
<p>A dependency failure can become:</p>
<p><strong>Failed payment.</strong></p>
<p>Poor observability can become:</p>
<p><strong>Longer outage.</strong></p>
<p>Tight coupling can become:</p>
<p><strong>Slower product releases.</strong></p>
<p>Poor scaling architecture can become:</p>
<p><strong>Lost customers during traffic spikes.</strong></p>
<p>Hardcoded secrets can become:</p>
<p><strong>A security incident.</strong></p>
<p>Weak AI architecture can become:</p>
<p><strong>Incorrect business decisions.</strong></p>
<p>That is why architecture deserves business level attention.</p>
<p>The question is not:</p>
<blockquote>
<p>"Is our architecture elegant?"</p>
</blockquote>
<p>The better question is:</p>
<blockquote>
<p><strong>"Can our architecture reliably produce the business outcome we need as the system changes?"</strong></p>
</blockquote>
<hr />
<h2>Final Takeaway</h2>
<p>A software system rarely becomes fragile because of one terrible architectural decision.</p>
<p>It usually becomes fragile through a collection of small decisions that were acceptable at the time.</p>
<p>The warning signs are often visible long before the outage.</p>
<p>Look for:</p>
<pre><code class="language-plaintext">Tight coupling
Synchronous chokeholds
Configuration leakage
Poor data access
Stateful infrastructure
Weak failure isolation
Unsafe database boundaries
Database saturation
Poor observability
Weak AI contracts
</code></pre>
<p>These are not merely engineering inconveniences.</p>
<p>They are signals that the system may not have clear boundaries around <strong>change, scale, state, security, failure, data, and behavior</strong>.</p>
<p>And that is where architecture becomes important.</p>
<p><strong>Good architecture is not about adding more technology.</strong></p>
<p>It is about creating clear boundaries so the system can change, scale, fail, and recover without taking everything else down with it.</p>
<hr />
<h2>What comes next</h2>
<p>Identifying the gap is only the first step.</p>
<p>The next question is:</p>
<p><strong>How do you fix it?</strong></p>
<p>In the next Think in Systems edition, I will take these architecture gaps from diagnosis to intervention and look at the patterns, design decisions, and tradeoffs that can address them.</p>
<p>Because finding the gap is useful.</p>
<p><strong>Fixing the system is what creates the outcome.</strong></p>
<hr />
<h3>Think in Systems</h3>
<p><strong>Complex problems. Simple systems. Better outcomes.</strong></p>
<p>Think in Systems is my weekly newsletter for people who build and lead across technology, business, AI, product, and engineering.</p>
<p>I use practical frameworks to move from:</p>
<p><strong>Problem → System → Constraint → Intervention → Outcome</strong></p>
<a href="https://newsletter.abhijeetbatsa.com/subscribe" target="_blank">
  
    Subscribe →
  
</a>
]]></content:encoded></item><item><title><![CDATA[Orders, Executions, Trades, Transactions and Positions: What's the Difference?]]></title><description><![CDATA[When people first enter financial technology, several terms appear everywhere:

Order. Execution. Trade. Transaction. Position.

They are often used together.
They are also often confused.
That confus]]></description><link>https://thinkinsystems.hashnode.dev/orders-executions-trades-transactions-and-positions-what-s-the-difference</link><guid isPermaLink="true">https://thinkinsystems.hashnode.dev/orders-executions-trades-transactions-and-positions-what-s-the-difference</guid><category><![CDATA[WealthTech]]></category><category><![CDATA[brokerage]]></category><category><![CDATA[System Design]]></category><category><![CDATA[Trading Systems]]></category><category><![CDATA[fintech]]></category><dc:creator><![CDATA[Abhijeet]]></dc:creator><pubDate>Sun, 20 Sep 2026 13:09:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/06eb42c1-3cff-4752-9158-93458ac8701c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When people first enter financial technology, several terms appear everywhere:</p>
<blockquote>
<p>Order. Execution. Trade. Transaction. Position.</p>
</blockquote>
<p>They are often used together.</p>
<p>They are also often confused.</p>
<p>That confusion becomes a problem when designing financial software because each represents a different point in the lifecycle of an investor's activity.</p>
<p>A simple mental model is:</p>
<pre><code class="language-plaintext">INTENTION
   |
   v
ORDER
   |
   v
EXECUTION
   |
   v
TRADE
   |
   v
POSITION
</code></pre>
<p>A transaction is a broader concept that can represent a financial movement or event, depending on the system and accounting model.</p>
<p>Let's separate them.</p>
<hr />
<h2>1. Order</h2>
<p>An order represents an instruction to buy or sell an instrument.</p>
<p>Example:</p>
<pre><code class="language-plaintext">Instrument: ABC
Side: Buy
Quantity: 100
Order type: Limit
Limit price: ₹500
</code></pre>
<p>The important word is:</p>
<p>Instruction.</p>
<p>The customer is saying:</p>
<blockquote>
<p>"I want to buy 100 shares of ABC at this price."</p>
</blockquote>
<p>That does not mean the purchase has happened.</p>
<p>The order may be:</p>
<pre><code class="language-plaintext">Created
Validated
Rejected
Accepted
Partially filled
Filled
Cancelled
ExpiredAn order therefore represents intent and lifecycle state.
</code></pre>
<hr />
<h2>2. Execution</h2>
<p>An execution represents an actual fill against an order.</p>
<p>Suppose the customer submits:</p>
<pre><code class="language-plaintext">Buy 100 ABC
</code></pre>
<p>The market may execute:</p>
<pre><code class="language-plaintext">40 shares at ₹499
30 shares at ₹500
30 shares at ₹501
</code></pre>
<p>That creates three executions.</p>
<pre><code class="language-plaintext">Order
100 shares
     |
     +---- Execution 1
     |     40 @ ₹499
     |
     +---- Execution 2
     |     30 @ ₹500
     |
     +---- Execution 3
           30 @ ₹501
</code></pre>
<p>The order is therefore not necessarily equal to one execution.</p>
<p>This distinction becomes important when modelling order state, average execution price and downstream position updates.</p>
<hr />
<h2>3. Trade</h2>
<p>A trade represents the economic result of an execution between counterparties.</p>
<p>In a brokerage platform, terminology can vary by market and system design.</p>
<p>But conceptually:</p>
<pre><code class="language-plaintext">Order
  ↓
Execution
  ↓
Trade
</code></pre>
<p>The trade becomes part of the downstream financial lifecycle.</p>
<p>It can contribute to:</p>
<p>• Position updates</p>
<p>• Settlement</p>
<p>• Ledger entries</p>
<p>• Reporting</p>
<p>• Portfolio calculations</p>
<p>• Reconciliation</p>
<p>This is why a trade should not simply be treated as another name for an order.</p>
<hr />
<h2>4. Transaction</h2>
<p>Transaction is the broadest term in this discussion.</p>
<p>A transaction can represent a financial movement or business event.</p>
<p>Examples might include:</p>
<pre><code class="language-plaintext">Cash deposit
Cash withdrawal
Buy transaction
Sell transaction
Fee
Tax
Dividend
Interest
Transfer
Adjustment
Settlement movement
</code></pre>
<p>So:</p>
<pre><code class="language-plaintext">Every trade related event may participate in
a broader transaction lifecycle.

But not every transaction is a trade.
</code></pre>
<p>For example:</p>
<p>A customer deposits ₹100,000 into their brokerage account.</p>
<p>That is a financial transaction.</p>
<p>No security was traded.</p>
<hr />
<h2>5. Position</h2>
<p>A position represents the customer's current holding or exposure.</p>
<p>Suppose the customer executes:</p>
<pre><code class="language-plaintext">Buy 100 ABC
</code></pre>
<p>Their position might become:</p>
<pre><code class="language-plaintext">ABC
Quantity: 100
</code></pre>
<p>Then they sell:</p>
<pre><code class="language-plaintext">40 ABC
</code></pre>
<p>The resulting position might become:</p>
<pre><code class="language-plaintext">ABC
Quantity: 60
</code></pre>
<p>So position is fundamentally about current state.</p>
<p>The order describes what was requested.</p>
<p>The execution describes what was filled.</p>
<p>The trade represents the resulting economic activity.</p>
<p>The position represents the resulting holding.</p>
<hr />
<h2>6. One complete example</h2>
<p>Let's follow one order.</p>
<p>The customer submits:</p>
<pre><code class="language-plaintext">Buy 100 ABC
Limit price ₹500
</code></pre>
<p><strong>Step 1</strong></p>
<p>An order is created.</p>
<pre><code class="language-plaintext">ORDER
Buy 100 ABC
</code></pre>
<p><strong>Step 2</strong></p>
<p>The order passes validation and risk checks.</p>
<pre><code class="language-plaintext">ORDER
Accepted
</code></pre>
<p><strong>Step 3</strong></p>
<p>The order is routed to the relevant execution venue.</p>
<p><strong>Step 4</strong></p>
<p>The market fills:</p>
<pre><code class="language-plaintext">40 @ ₹499
60 @ ₹500
</code></pre>
<p>There are now two executions.</p>
<p><strong>Step 5</strong></p>
<p>The resulting trade records are captured.</p>
<p><strong>Step 6</strong></p>
<p>The position changes:</p>
<pre><code class="language-plaintext">ABC
+100 shares
</code></pre>
<p><strong>Step 7</strong></p>
<p>The financial system records the appropriate financial movements.</p>
<p><strong>Step 8</strong></p>
<p>Downstream systems update:</p>
<pre><code class="language-plaintext">Portfolio
Reporting
Notifications
Analytics
Reconciliation
</code></pre>
<p>The complete lifecycle is therefore:</p>
<pre><code class="language-plaintext">Customer intention
       ↓
      Order
       ↓
   Risk checks
       ↓
    Routing
       ↓
   Execution
       ↓
     Trade
       ↓
    Position
       ↓
 Financial records
       ↓
 Portfolio / Reporting
</code></pre>
<hr />
<h2>7. Why the distinction matters architecturally</h2>
<p>These concepts often become separate data models because they answer different questions.</p>
<table>
<thead>
<tr>
<th>Concept</th>
<th>Core question</th>
</tr>
</thead>
<tbody><tr>
<td>Order</td>
<td>What did the customer ask us to do?</td>
</tr>
<tr>
<td>Execution</td>
<td>What portion of the order actually filled?</td>
</tr>
<tr>
<td>Trade</td>
<td>What economic trade occurred?</td>
</tr>
<tr>
<td>Transaction</td>
<td>What financial movement or event occurred?</td>
</tr>
<tr>
<td>Position</td>
<td>What does the customer currently hold?</td>
</tr>
</tbody></table>
<p>This separation also helps when handling failures.</p>
<p>Imagine the customer submits an order.</p>
<p>The application times out.</p>
<p>The customer retries.</p>
<p>The first request may already have reached the downstream trading system.</p>
<p>Now the system needs to determine whether an order already exists and whether it has been executed.</p>
<blockquote>
<p>That is one reason idempotency and durable order state matter in financial systems.</p>
</blockquote>
<hr />
<h2>8. Order versus position</h2>
<p>This distinction is especially important.</p>
<blockquote>
<p>An order is event and intent oriented.</p>
<p>A position is state oriented.</p>
</blockquote>
<p>For example:</p>
<pre><code class="language-plaintext">Order 1
Buy 100
</code></pre>
<p>followed by:</p>
<pre><code class="language-plaintext">Order 2
Sell 40
</code></pre>
<p>can result in:</p>
<pre><code class="language-plaintext">Position
60
</code></pre>
<p>The position cannot tell you everything that happened.</p>
<p>The order history can.</p>
<p>This means a production system generally needs both:</p>
<blockquote>
<p>Historical records, and Current state</p>
</blockquote>
<hr />
<h2>9. Where these concepts sit in the architecture</h2>
<p>A simplified model looks like:</p>
<pre><code class="language-plaintext">             ORDER DOMAIN
                  |
                  v
                Order
                  |
                  v
                Risk
                  |
                  v
                 OMS
                  |
                  v
          Execution Venue
                  |
                  v
            EXECUTION
                  |
                  v
               TRADE
             /       \
            v         v
      POSITION      LEDGER
            |         |
            +----+----+
                 |
                 v
             PORTFOLIO
</code></pre>
<p>This is intentionally simplified.</p>
<p>Different platforms can combine or separate these responsibilities differently.</p>
<p>The important part is understanding the semantic boundaries.</p>
<hr />
<h2>10. A useful rule</h2>
<p>When designing a financial system, ask:</p>
<p>Am I representing what someone wanted, what actually happened, or the current state produced by what happened?</p>
<p>That question often tells you which domain object you need.</p>
<pre><code class="language-plaintext">Wanted
  ↓
Order

Happened
  ↓
Execution / Trade

Current state
  ↓
Position

Financial movement
  ↓
Transaction / Ledger
</code></pre>
<p>Once these concepts are clear, designing the services around them becomes much easier.</p>
<hr />
<h2>Continue the series</h2>
<h3>Next we can go deeper into:</h3>
<p>How Does an Online Brokerage Order Actually Flow?</p>
<p>That article will connect these concepts into a complete lifecycle from customer order submission through validation, risk checks, routing, execution, trade capture, position updates and reconciliation.</p>
<blockquote>
<p>For deeper first person architecture decisions and tradeoffs,</p>
<p><strong>subscribe to</strong> <a href="https://newsletter.abhijeetbatsa.com/subscribe"><mark class="bg-yellow-200 dark:bg-yellow-500/30">Think in Systems.</mark></a></p>
</blockquote>
<p><strong>Complex problems. Simple systems. Better outcomes.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Modern Brokerage Platform Architecture: Core Components and Data Flow]]></title><description><![CDATA[A modern brokerage platform may look simple from the outside.
A customer opens an account.
They add money.
They search for a security.
They place an order.
The order gets executed.
Their portfolio cha]]></description><link>https://thinkinsystems.hashnode.dev/modern-brokerage-platform-architecture-core-components-and-data-flow</link><guid isPermaLink="true">https://thinkinsystems.hashnode.dev/modern-brokerage-platform-architecture-core-components-and-data-flow</guid><category><![CDATA[wealthtech, trading systems, brokerage, system design, software architecture, fintech]]></category><dc:creator><![CDATA[Abhijeet]]></dc:creator><pubDate>Sun, 20 Sep 2026 12:35:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/d211bdc4-c4dd-4de0-954a-22686ed61b55.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A modern brokerage platform may look simple from the outside.</p>
<p>A customer opens an account.</p>
<p>They add money.</p>
<p>They search for a security.</p>
<p>They place an order.</p>
<p>The order gets executed.</p>
<p>Their portfolio changes.</p>
<p>But behind that apparently simple journey is a collection of systems responsible for identity, accounts, funding, order management, risk, execution, positions, portfolios, financial records, market data, notifications and reconciliation.</p>
<p>A brokerage platform is therefore <strong>not a single application.</strong></p>
<p><em><strong>It is a financial system made up of multiple cooperating systems with different responsibilities and correctness requirements.</strong></em></p>
<p>This article explains the major components and how data flows between them.</p>
<p>This is a reference architecture. Actual implementations vary by market, broker, asset class, regulatory environment and operating model.</p>
<hr />
<h2>1. The high level architecture</h2>
<p>A simplified brokerage platform can be represented as:</p>
<pre><code class="language-plaintext">                     CUSTOMER
                        |
                        v
                +---------------+
                | Mobile / Web  |
                +---------------+
                        |
                        v
                +---------------+
                | API Gateway   |
                +---------------+
                        |
         +--------------+--------------+
         |              |              |
         v              v              v
    Identity &amp;       Account        Portfolio
    KYC Services     Services        Services
                        |
                        v
                +---------------+
                | Order Service |
                +---------------+
                        |
                        v
                +---------------+
                | Risk Checks   |
                +---------------+
                        |
                        v
                +---------------+
                | OMS           |
                +---------------+
                        |
                        v
              +---------------------+
              | Broker / Exchange   |
              | Connectivity        |
              +---------------------+
                        |
                        v
                   EXECUTION
                        |
                        v
                +---------------+
                | Trade Capture |
                +---------------+
                        |
            +-----------+-----------+
            |           |           |
            v           v           v
       Positions      Ledger     Portfolio
            |           |           |
            +-----------+-----------+
                        |
                        v
                Reconciliation
</code></pre>
<p>This is intentionally simplified.</p>
<p>A production platform will usually have additional services for market data, reference data, notifications, reporting, compliance, analytics, observability and operational workflows.</p>
<hr />
<h2>2. Customer and presentation layer</h2>
<p>The customer interacts with the brokerage through applications such as:</p>
<p>• Mobile applications</p>
<p>• Web applications</p>
<p>• APIs</p>
<p>The presentation layer should not directly own financial business logic.</p>
<p>For example, the mobile application should not independently decide whether an order is valid.</p>
<p>It should request that decision from the appropriate backend service.</p>
<p>This keeps important business rules inside controlled services rather than distributing them across clients.</p>
<hr />
<h2>3. Identity and KYC</h2>
<p>Before a customer can trade, the platform needs to establish who the customer is and what they are permitted to do.</p>
<p>Typical responsibilities include:</p>
<p>• User identity</p>
<p>• Authentication</p>
<p>• KYC status</p>
<p>• Account status</p>
<p>• Regulatory information</p>
<p>• Customer classification</p>
<p>• Restrictions</p>
<p>The exact responsibilities depend heavily on the jurisdiction and business model.</p>
<p>This service is part of the onboarding system, but its output affects downstream trading capabilities.</p>
<p>For example:</p>
<pre><code class="language-plaintext">Customer
   |
   v
Identity
   |
   v
KYC
   |
   v
Account activation
   |
   v
Trading eligibility
</code></pre>
<p>The important architectural point is that identity and trading eligibility are related but different concerns.</p>
<hr />
<h2>4. Account service</h2>
<p>A customer can have one or more financial accounts.</p>
<p>The account domain typically manages information such as:</p>
<p>• Account identity</p>
<p>• Account status</p>
<p>• Account type</p>
<p>• Base currency</p>
<p>• Trading permissions</p>
<p>• Linked funding relationships</p>
<p>• Regulatory attributes</p>
<p>The account becomes an important boundary for downstream operations.</p>
<p>For example, an order generally needs to be associated with a specific account.</p>
<hr />
<h2>5. Funding and cash management</h2>
<p>A brokerage platform also needs to manage money moving into and out of the platform.</p>
<p>Typical flows include:</p>
<pre><code class="language-plaintext">Bank
  |
  v
Payment / Banking Integration
  |
  v
Cash Account
  |
  v
Available Buying Power
</code></pre>
<p>The exact architecture varies significantly depending on whether the brokerage operates its own payment infrastructure, uses banking partners or integrates with another financial institution.</p>
<p>The important point is that cash movement and securities trading are related but distinct workflows.</p>
<p>A successful deposit does not mean that an equity order has been executed.</p>
<hr />
<h2>6. Order management</h2>
<p>The order service receives the customer's trading instruction.</p>
<p>For example:</p>
<pre><code class="language-plaintext">Buy
100 shares
ABC
Limit price: ₹500
</code></pre>
<p>The order is not yet a trade.</p>
<p>It is an instruction or intention to trade.</p>
<p>The platform needs to validate the request and maintain its lifecycle.</p>
<p>A simplified lifecycle might look like:</p>
<pre><code class="language-plaintext">Created
   |
   v
Validated
   |
   v
Risk Checked
   |
   v
Submitted
   |
   v
Accepted
   |
   v
Partially Filled
   |
   v
Filled
</code></pre>
<p>Other states can include rejected, cancelled, expired or pending.</p>
<p>This is one reason order management becomes a distinct domain.</p>
<p>An order has a lifecycle.</p>
<p>A trade represents an execution.</p>
<p>They should not be treated as the same object.</p>
<hr />
<h2>7. Risk management</h2>
<p>Before an order reaches the market, the platform may need to perform several checks.</p>
<p>Examples include:</p>
<p>• Available funds</p>
<p>• Available quantity</p>
<p>• Position limits</p>
<p>• Instrument restrictions</p>
<p>• Customer restrictions</p>
<p>• Exposure limits</p>
<p>• Trading permissions</p>
<p>• Regulatory checks</p>
<p>• Risk limits</p>
<p>A simplified flow is:</p>
<pre><code class="language-plaintext">Order
  |
  v
Validation
  |
  v
Risk checks
  |
  +---- Rejected
  |
  v
Approved
</code></pre>
<p>The exact checks depend on the product and regulatory environment.</p>
<p>For high performance trading systems, some risk checks may need to happen directly in the critical order path. AWS describes similar patterns in low latency trading architectures where pre trade risk validation sits directly in the trading path.</p>
<hr />
<h2>8. Order Management System</h2>
<p>The Order Management System, or OMS, coordinates order lifecycle management.</p>
<p>It may be responsible for:</p>
<p>• Maintaining order state</p>
<p>• Routing orders</p>
<p>• Managing modifications</p>
<p>• Managing cancellations</p>
<p>• Receiving execution updates</p>
<p>• Maintaining order history</p>
<p>• Connecting with broker or exchange adapters</p>
<p>The OMS does not necessarily perform every trading function itself.</p>
<p>Instead, it coordinates several parts of the order lifecycle.</p>
<p>A simplified model is:</p>
<pre><code class="language-plaintext">Customer
   |
   v
Order Service
   |
   v
Risk
   |
   v
OMS
   |
   v
Broker / Exchange
</code></pre>
<p>Enterprise trading platforms commonly separate order management from execution and connectivity concerns. AWS reference architectures also show order management and broker or exchange connectivity as distinct responsibilities.</p>
<hr />
<h2>9. Broker and exchange connectivity</h2>
<p>The OMS cannot simply send an internal order object directly to every market.</p>
<p>Different venues can expose different protocols, APIs and connectivity models.</p>
<p>An adapter layer can isolate those differences.</p>
<pre><code class="language-plaintext">             OMS
              |
    +---------+---------+
    |         |         |
    v         v         v
 Adapter   Adapter   Adapter
    |         |         |
  Venue A   Venue B   Venue C
</code></pre>
<p>This abstraction becomes particularly important when a platform connects to multiple brokers, exchanges or execution venues.</p>
<hr />
<h2>10. Execution and trade capture</h2>
<p>Once an order reaches the relevant execution venue, it may be:</p>
<p>• Accepted</p>
<p>• Rejected</p>
<p>• Partially executed</p>
<p>• Fully executed</p>
<p>A single order can therefore produce multiple executions.</p>
<p>For example:</p>
<pre><code class="language-plaintext">Order
100 shares
    |
    +---- Execution 1: 40
    |
    +---- Execution 2: 35
    |
    +---- Execution 3: 25
</code></pre>
<p>The total quantity executed is 100.</p>
<p>The order and executions are therefore separate concepts.</p>
<p>The execution becomes the basis for creating trade records and updating downstream financial state.</p>
<hr />
<h2>11. Position management</h2>
<p>A position represents the customer's current holding or exposure.</p>
<p>For example:</p>
<pre><code class="language-plaintext">ABC
Quantity: 100
Average price: ₹500
</code></pre>
<p>A position is not simply another copy of an order.</p>
<p>The order describes what the customer asked the system to do.</p>
<p>The execution describes what actually happened.</p>
<p>The position represents the resulting holding.</p>
<p>Conceptually:</p>
<pre><code class="language-plaintext">Order
  |
  v
Execution
  |
  v
Trade
  |
  v
Position
</code></pre>
<p>The actual calculation can become much more complex when there are multiple executions, corporate actions, transfers, derivatives or different accounting treatments.</p>
<hr />
<h2>12. Portfolio service</h2>
<p>The portfolio layer aggregates financial state for the customer.</p>
<p>It may provide:</p>
<p>• Holdings</p>
<p>• Cash</p>
<p>• Portfolio value</p>
<p>• Unrealized profit and loss</p>
<p>• Realized profit and loss</p>
<p>• Asset allocation</p>
<p>• Performance</p>
<p>• Exposure</p>
<p>The portfolio view is therefore derived from multiple underlying domains.</p>
<pre><code class="language-plaintext">Positions
Cash
Corporate Actions
Prices
Transactions
      |
      v
Portfolio
</code></pre>
<p>This is why a portfolio service should not become the system of record for everything.</p>
<p>It is primarily a view of financial state assembled from underlying records.</p>
<hr />
<h2>13. Financial ledger</h2>
<p>The financial ledger records financial movements according to the accounting model of the platform.</p>
<p>Examples can include:</p>
<p>• Cash movements</p>
<p>• Fees</p>
<p>• Charges</p>
<p>• Settlements</p>
<p>• Adjustments</p>
<p>• Transfers</p>
<p>• Other financial entries</p>
<p>The ledger is different from the operational order database.</p>
<p>An order database answers:</p>
<p>What happened to this order?</p>
<p>A ledger answers:</p>
<p>What financial movement was recorded?</p>
<p>Keeping these concepts separate is important because the lifecycle and correctness requirements are different.</p>
<hr />
<h2>14. Market data</h2>
<p>The customer also needs information about the market.</p>
<p>Market data can include:</p>
<p>• Prices</p>
<p>• Bid and ask</p>
<p>• Volume</p>
<p>• Trades</p>
<p>• Order book information</p>
<p>• Instrument reference data</p>
<p>A simplified flow is:</p>
<pre><code class="language-plaintext">Exchange / Market Data Provider
              |
              v
       Market Data Gateway
              |
              v
       Normalization Layer
              |
              v
        Event Streaming
              |
       +------+------+
       |             |
       v             v
   Trading       Customer APIs
   Services          |
                     v
               Web / Mobile
</code></pre>
<p>Market data architecture can be significantly more complex depending on latency, market coverage and distribution requirements.</p>
<p>AWS describes market data architectures where real time sources are ingested, processed and distributed through streaming infrastructure and interfaces such as WebSockets or APIs.</p>
<hr />
<h2>15. Event streaming</h2>
<p>A brokerage platform contains many events.</p>
<p>Examples:</p>
<pre><code class="language-plaintext">OrderCreated
OrderAccepted
OrderRejected
OrderExecuted
TradeCreated
PositionUpdated
CashUpdated
PortfolioUpdated
</code></pre>
<p>These events can be distributed to other systems.</p>
<p>For example:</p>
<pre><code class="language-plaintext">                 Order Service
                      |
                      v
                Event Stream
                      |
        +-------------+-------------+
        |             |             |
        v             v             v
   Notification   Portfolio     Analytics
</code></pre>
<p>Event streaming can reduce direct coupling between services.</p>
<p>But it does not eliminate the need for transactional correctness.</p>
<p>A critical financial record should not become correct merely because an event was successfully published.</p>
<p>The system still needs clear ownership of the underlying state.</p>
<hr />
<h2>16. Reconciliation</h2>
<p>Financial systems cannot simply assume that every system always agrees.</p>
<p>Records can differ because of:</p>
<p>• Network failures</p>
<p>• Duplicate messages</p>
<p>• Delayed messages</p>
<p>• Partial processing</p>
<p>• External system failures</p>
<p>• Manual adjustments</p>
<p>• Data corrections</p>
<p>Reconciliation compares records across systems.</p>
<p>For example:</p>
<p>Broker Records | | compare v Internal Trade Records | | compare v Ledger | | compare v Positions</p>
<p>A mismatch becomes an operational exception that needs investigation.</p>
<p>Reconciliation is therefore not merely a reporting feature.</p>
<p>It is part of the control architecture of a financial platform.</p>
<hr />
<h2>17. Where the data lives</h2>
<p>A modern brokerage platform usually has multiple categories of data.</p>
<p>Transactional data</p>
<p>Orders, accounts, trades and other operational records.</p>
<p>Financial records</p>
<p>Ledger and financial transactions.</p>
<p>Market data</p>
<p>Prices, quotes, trades and potentially order book information.</p>
<p>Reference data</p>
<p>Instruments, exchanges, currencies and other relatively stable reference information.</p>
<p>Analytical data</p>
<p>Historical events, customer analytics, reporting and business intelligence.</p>
<p>These workloads have different access patterns.</p>
<p>Trying to force every workload into one database usually creates unnecessary coupling.</p>
<hr />
<h2>18. The complete simplified data flow</h2>
<p>Putting the major components together:</p>
<pre><code class="language-plaintext">                     CUSTOMER
                        |
                        v
                Web / Mobile / API
                        |
                        v
                Identity / Account
                        |
                        v
                     Order
                        |
                        v
                Validation / Risk
                        |
                        v
                       OMS
                        |
                        v
             Broker / Exchange Adapter
                        |
                        v
                    Execution
                        |
                        v
                  Trade Capture
                        |
          +-------------+-------------+
          |             |             |
          v             v             v
      Position       Ledger       Portfolio
          |             |             |
          +-------------+-------------+
                        |
                        v
                 Reconciliation
</code></pre>
<p>At the same time:</p>
<pre><code class="language-plaintext">Market Data Sources
        |
        v
Market Data Ingestion
        |
        v
Streaming / Distribution
        |
        +-------------&gt; Trading Services
        |
        +-------------&gt; Customer APIs
        |
        +-------------&gt; Web / Mobile
        |
        +-------------&gt; Analytics
</code></pre>
<p>This gives us two major flows:</p>
<p><strong>Trading flow</strong></p>
<pre><code class="language-plaintext">Intent → Order → Risk → Execution → Trade → Position
</code></pre>
<p><strong>Market data flow</strong></p>
<pre><code class="language-plaintext">Market → Ingestion → Processing → Distribution → Customer
</code></pre>
<p>And a third important control flow:</p>
<p><strong>Financial control flow</strong></p>
<pre><code class="language-plaintext">Transactions → Ledger → Reconciliation
</code></pre>
<hr />
<h2>19. The most important architectural boundary</h2>
<p>A useful way to think about the entire platform is to separate three questions.</p>
<p><strong>What did the customer request?</strong></p>
<p><strong>Order</strong></p>
<p><strong>What actually happened in the market?</strong></p>
<p><strong>Execution and trade</strong></p>
<p><strong>What does the customer own now?</strong></p>
<p><strong>Position and portfolio</strong></p>
<p>Then separately:</p>
<h3>What financial movements were recorded?</h3>
<p><strong>Ledger</strong></p>
<p>And:</p>
<h3>Do our systems agree?</h3>
<p><strong>Reconciliation</strong></p>
<p>Once these responsibilities are explicit, the architecture becomes easier to reason about.</p>
<hr />
<h2><strong>20. Why this architecture matters</strong></h2>
<p>A brokerage platform is not difficult merely because it has many services.</p>
<p>The difficult part is that different parts of the system have different definitions of correctness.</p>
<p>An order can be accepted without being executed.</p>
<p>An order can be partially executed.</p>
<p>A trade can exist before a portfolio view reflects it.</p>
<p>Market data can be delayed while an order is being processed.</p>
<p>A customer request can time out even though the downstream system accepted the order.</p>
<p>A financial record can require reconciliation even when the application itself reported success.</p>
<p>These are architectural problems, not merely coding problems.</p>
<p>That is why a brokerage platform needs explicit boundaries between:</p>
<ul>
<li><p><code>Orders</code></p>
</li>
<li><p><code>Executions</code></p>
</li>
<li><p><code>Trades</code></p>
</li>
<li><p><code>Positions</code></p>
</li>
<li><p><code>Portfolio</code></p>
</li>
<li><p><code>Ledger</code></p>
</li>
<li><p><code>Market Data</code></p>
</li>
<li><p><code>Reconciliation</code></p>
</li>
</ul>
<p>The next articles will examine these domains individually.</p>
<hr />
<h2>Continue the WealthTech Architecture Series</h2>
<p><strong>Next:</strong></p>
<p><strong>Orders, Executions, Trades, Transactions and Positions: What's the Difference?</strong></p>
<p>Understanding these concepts is essential before designing the services that manage them.</p>
<p>For deeper architectural reasoning, design tradeoffs and first person engineering perspectives, subscribe to <strong><mark class="bg-yellow-200 dark:bg-yellow-500/30">Think in Systems</mark></strong><mark class="bg-yellow-200 dark:bg-yellow-500/30">.</mark></p>
<p><strong>Complex problems. Simple systems. Better outcomes.</strong></p>
<p><a href="https://newsletter.abhijeetbatsa.com/subscribe">Subscribe to Think in Systems</a></p>
]]></content:encoded></item><item><title><![CDATA[How Load Balancers Actually Work]]></title><description><![CDATA[Imagine 100,000 people entering through one door
Imagine a stadium.
There are 100,000 people outside.
There are ten entrances.
If everyone uses the same entrance, you have a problem.
The other nine en]]></description><link>https://thinkinsystems.hashnode.dev/how-load-balancers-actually-work</link><guid isPermaLink="true">https://thinkinsystems.hashnode.dev/how-load-balancers-actually-work</guid><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Abhijeet]]></dc:creator><pubDate>Sat, 19 Sep 2026 14:40:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/2a88ec5f-26ff-4fb5-95e7-4700c70e032f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Imagine 100,000 people entering through one door</h3>
<p>Imagine a stadium.</p>
<p>There are 100,000 people outside.</p>
<p>There are ten entrances.</p>
<p>If everyone uses the same entrance, you have a problem.</p>
<p>The other nine entrances may be empty.</p>
<p>The first entrance becomes crowded.</p>
<p>People wait.</p>
<p>The system slows down.</p>
<p>A load balancer solves a similar problem for software systems.</p>
<p>Instead of sending every request to one server, it distributes requests across multiple servers.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/ad8f3b5d-6b96-4fbe-8a77-d6710cc5ce2b.png" alt="" style="display:block;margin:0 auto" />

<p>That is the basic idea.</p>
<p>But real load balancing is much more interesting.</p>
<hr />
<h1>Why do we need multiple servers?</h1>
<p>Suppose your application has one server.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/b0500662-17d8-422d-ae2d-8024aef908b3.png" alt="" style="display:block;margin:0 auto" />

<p>Initially, this might work perfectly.</p>
<p>Then traffic grows.</p>
<p>100 users.</p>
<p>1,000 users.</p>
<p>10,000 users.</p>
<p>Eventually the server reaches its capacity.</p>
<p>You have two options.</p>
<p>Make the server bigger.</p>
<p>Or add more servers.</p>
<p>The second approach is called <strong>horizontal scaling</strong>.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/23c6e542-c50d-473d-8469-d7aaa5e133a3.png" alt="" style="display:block;margin:0 auto" />

<p>Now traffic can be distributed.</p>
<hr />
<h1>What does the load balancer actually do?</h1>
<p>At a basic level:</p>
<pre><code class="language-plaintext">Client
  ↓
Load Balancer
  ↓
Application Server
</code></pre>
<p>The client does not necessarily need to know which application server handled the request.</p>
<p>The load balancer becomes the traffic entry point.</p>
<p>It receives the request.</p>
<p>It decides where the request should go.</p>
<p>It forwards the request.</p>
<p>The server processes it.</p>
<p>The response comes back.</p>
<hr />
<h1>But how does it choose a server?</h1>
<p>This is where algorithms come in.</p>
<h2>Round Robin</h2>
<p>The simplest approach.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/1b883fcb-af3e-4c7d-8695-b6aa9861a974.png" alt="" style="display:block;margin:0 auto" />

<p>It cycles through servers.</p>
<p>Simple.</p>
<p>But it assumes servers have similar capacity and requests have similar cost.</p>
<p>That assumption is not always true.</p>
<hr />
<h1>Weighted Round Robin</h1>
<p>Suppose:</p>
<p>Server A has 8 CPU cores.</p>
<p>Server B has 4.</p>
<p>Server C has 2.</p>
<p>You might want:</p>
<pre><code class="language-plaintext">Server A → 50%
Server B → 30%
Server C → 20%
</code></pre>
<p>The load balancer can assign traffic based on weights.</p>
<hr />
<h1>Least Connections</h1>
<p>Instead of counting requests, the load balancer looks at active connections.</p>
<p>For example:</p>
<pre><code class="language-plaintext">Server A → 100 connections
Server B → 30 connections
Server C → 50 connections
</code></pre>
<p>A new request might go to Server B.</p>
<p>This can be useful when requests have different processing times.</p>
<hr />
<h1>What happens when a server dies?</h1>
<p>This is one of the most important jobs of a load balancer.</p>
<p>Suppose:</p>
<pre><code class="language-plaintext">Server A → Healthy
Server B → Healthy
Server C → Failed
</code></pre>
<p>The load balancer should stop sending traffic to Server C.</p>
<p>How does it know?</p>
<p><strong>Health checks.</strong></p>
<hr />
<h1>Health checks</h1>
<p>The load balancer periodically checks servers.</p>
<p>For example:</p>
<pre><code class="language-plaintext">GET /health
</code></pre>
<p>A healthy response might be:</p>
<pre><code class="language-plaintext">200 OK
</code></pre>
<p>If the server repeatedly fails health checks, it can be removed from the traffic pool.</p>
<p>This gives us:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/967d0d75-6f32-49e0-a5ef-6d5354a70e3f.png" alt="" style="display:block;margin:0 auto" />

<p>The user may never know that Server C failed.</p>
<p>That is one of the benefits of redundancy.</p>
<hr />
<h1>But health checks are not magic</h1>
<p>Imagine the server responds:</p>
<pre><code class="language-plaintext">200 OK
</code></pre>
<p>But its database connection pool is exhausted.</p>
<p>Is the server actually healthy?</p>
<p>This is where health check design becomes important.</p>
<p>A shallow health check may only verify:</p>
<blockquote>
<p>"Is the process alive?"</p>
</blockquote>
<p>A deeper health check may verify critical dependencies.</p>
<p>But checking every dependency can also create problems.</p>
<p>If the database has a temporary issue, suddenly every server might appear unhealthy.</p>
<p>So health checks themselves need thoughtful design.</p>
<hr />
<h1>Layer 4 and Layer 7 load balancing</h1>
<p>Load balancers can operate at different networking layers.</p>
<h2>Layer 4</h2>
<p>Layer 4 works primarily with network information such as:</p>
<p>• IP address<br />• TCP<br />• Port</p>
<p>It does not need to understand the application request deeply.</p>
<h2>Layer 7</h2>
<p>Layer 7 understands application level information such as:</p>
<p>• HTTP<br />• URL path<br />• Headers<br />• Cookies<br />• Hostname</p>
<p>For example:</p>
<pre><code class="language-plaintext">/api/orders → Order Service

/api/payments → Payment Service

/api/users → User Service
</code></pre>
<p>This makes Layer 7 routing much more powerful.</p>
<hr />
<h1>Load balancing is not only about traffic</h1>
<p>It can also provide:</p>
<p>• Health checking<br />• TLS termination<br />• Routing<br />• Connection management<br />• Failover<br />• Rate limiting in some architectures<br />• Session handling<br />• Service discovery integration</p>
<p>The exact capabilities depend on the architecture and product.</p>
<hr />
<h1>What happens during a traffic spike?</h1>
<p>Suppose normal traffic is:</p>
<pre><code class="language-plaintext">1,000 requests/sec
</code></pre>
<p>Then a marketing campaign starts.</p>
<p>Traffic becomes:</p>
<pre><code class="language-plaintext">10,000 requests/sec
</code></pre>
<p>If you have only one server, it may struggle.</p>
<p>With multiple servers:</p>
<pre><code class="language-plaintext">             Load Balancer
          /    /    |    \
         ↓    ↓     ↓     ↓
        S1   S2    S3    S4
</code></pre>
<p>Traffic can be distributed across the fleet.</p>
<p>But here is an important systems thinking lesson:</p>
<blockquote>
<p><strong>A load balancer does not make an unlimited system scalable.</strong></p>
</blockquote>
<p>It only moves the constraint.</p>
<hr />
<h1>The hidden bottleneck</h1>
<p>Suppose you have:</p>
<pre><code class="language-plaintext">Load Balancer
      ↓
10 Application Servers
      ↓
One Database
</code></pre>
<p>The application layer can scale.</p>
<p>The database may not.</p>
<p>You could increase the application servers from 10 to 100.</p>
<p>But if all 100 servers depend on one database, the database may become the constraint.</p>
<p>This is why architecture needs systems thinking.</p>
<p>Scaling one component does not automatically scale the system.</p>
<hr />
<h1>The real model</h1>
<p>Think about the entire path:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/c9acc53a-260f-4f06-8674-2326b15d0633.png" alt="" style="display:block;margin:0 auto" />

<p>Every layer has:</p>
<p>• Capacity</p>
<p>• Latency</p>
<p>• Failure modes</p>
<p>• Dependencies</p>
<p>• Scaling characteristics</p>
<p>The system's behavior emerges from all of them.</p>
<hr />
<h1>The deeper lesson</h1>
<p>When you learn load balancing, don't memorize:</p>
<blockquote>
<p>"Round Robin distributes requests."</p>
</blockquote>
<p>Ask:</p>
<blockquote>
<p>Why do we need distribution?</p>
</blockquote>
<blockquote>
<p>What happens if one server fails?</p>
</blockquote>
<blockquote>
<p>What determines whether a server is healthy?</p>
</blockquote>
<blockquote>
<p>What happens when traffic becomes uneven?</p>
</blockquote>
<blockquote>
<p>What happens if the database becomes the bottleneck?</p>
</blockquote>
<blockquote>
<p>What happens when a request takes much longer than another request?</p>
</blockquote>
<p>Those questions move you from technology knowledge toward architecture thinking.</p>
<hr />
<h2><mark class="bg-yellow-200 dark:bg-yellow-500/30">Think in Systems</mark></h2>
<p>A load balancer is not simply a networking component.</p>
<p>It is part of a larger system designed to manage <strong>capacity, availability and failure</strong>.</p>
<p>That is the mindset I explore in <a href="https://newsletter.abhijeetbatsa.com/subscribe"><strong><mark class="bg-yellow-200 dark:bg-yellow-500/30">Think in Systems</mark></strong></a><mark class="bg-yellow-200 dark:bg-yellow-500/30">.</mark></p>
<p><strong>Complex problems. Simple systems. Better outcomes.</strong></p>
]]></content:encoded></item><item><title><![CDATA[What is a System - A Practical Guide to Systems Thinking]]></title><description><![CDATA[What exactly is a system?
When people hear the word "system", they often think about software.
A backend.
A database.
An API.
A collection of microservices.
But a system is much broader than that.
A s]]></description><link>https://thinkinsystems.hashnode.dev/what-is-a-system-a-practical-guide-to-systems-thinking</link><guid isPermaLink="true">https://thinkinsystems.hashnode.dev/what-is-a-system-a-practical-guide-to-systems-thinking</guid><category><![CDATA[Systems Thinking]]></category><dc:creator><![CDATA[Abhijeet]]></dc:creator><pubDate>Sat, 19 Sep 2026 10:41:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/40ab1f36-0c85-4d06-bcdf-c3fa0496005f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>What exactly is a system?</p>
<p>When people hear the word "system", they often think about software.</p>
<p>A backend.</p>
<p>A database.</p>
<p>An API.</p>
<p>A collection of microservices.</p>
<p>But a system is much broader than that.</p>
<p>A system is a set of <strong>connected parts that interact with each other to produce an outcome</strong>.</p>
<p>That definition works for software.</p>
<p>It also works for businesses.</p>
<p>Teams.</p>
<p>Markets.</p>
<p>AI applications.</p>
<p>Sales processes.</p>
<p>Even something as simple as a restaurant.</p>
<p>The important word is not "parts".</p>
<p>It is <strong>connected</strong>.</p>
<p>Because the behavior of a system comes not only from what its individual parts do.</p>
<p>It comes from <strong>how those parts interact</strong>.</p>
<hr />
<h2>Think about a food delivery application</h2>
<p>A customer opens an application.</p>
<p>They search for a restaurant.</p>
<p>They select food.</p>
<p>They place an order.</p>
<p>They make a payment.</p>
<p>The restaurant accepts the order.</p>
<p>A delivery partner is assigned.</p>
<p>The food is prepared.</p>
<p>The food is delivered.</p>
<p>From the customer's perspective, this looks like one action:</p>
<blockquote>
<p>"Order food."</p>
</blockquote>
<p>But behind that action is a system.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/4be0c3fb-3418-4ad5-a439-0157e85d6bbd.png" alt="" style="display:block;margin:0 auto" />

<p>Each component has a responsibility.</p>
<p>But none of them produces the final outcome alone.</p>
<p>The outcome emerges from their interaction.</p>
<hr />
<h1>A system has parts</h1>
<p>Let's start with the simplest model.</p>
<pre><code class="language-plaintext">System
│
├── Components
├── Relationships
├── Inputs
├── Processes
├── Constraints
└── Outputs
</code></pre>
<h3>Components</h3>
<p>The things that make up the system.</p>
<p>In software:</p>
<p>• Applications</p>
<p>• Services</p>
<p>• Databases</p>
<p>• Queues</p>
<p>• Users</p>
<p>• External systems</p>
<h3>Relationships</h3>
<p>How those components interact.</p>
<p>For example:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/f60fbcfd-eca0-45fc-b5f6-a29252ad74a2.png" alt="" style="display:block;margin:0 auto" />

<h3>Inputs</h3>
<p>What enters the system.</p>
<p>Examples:</p>
<p>• User request</p>
<p>• Payment</p>
<p>• Market data</p>
<p>• Customer information</p>
<h3>Processes</h3>
<p>What the system does with those inputs.</p>
<h3>Constraints</h3>
<p>What limits the system.</p>
<p>Examples:</p>
<p>• Database capacity</p>
<p>• Network latency</p>
<p>• Regulatory rules</p>
<p>• Budget</p>
<p>• Human decision making</p>
<h3>Outputs</h3>
<p>What the system ultimately produces.</p>
<p>Examples:</p>
<p>• Successful payment</p>
<p>• Completed order</p>
<p>• Customer account</p>
<p>• Investment position</p>
<hr />
<h1>But here is where system thinking becomes interesting</h1>
<p>Suppose your application is slow.</p>
<p>What would you investigate?</p>
<p>A developer might immediately look at the application code.</p>
<p>But the problem may not be inside the application.</p>
<p>Maybe the database is overloaded.</p>
<p>Maybe the API is waiting for another service.</p>
<p>Maybe a third party API is slow.</p>
<p>Maybe the application is making unnecessary calls.</p>
<p>Maybe a queue is backed up.</p>
<p>Maybe the system is performing expensive synchronous work.</p>
<p>So instead of asking:</p>
<blockquote>
<p>"Which component is broken?"</p>
</blockquote>
<p>System thinking asks:</p>
<blockquote>
<p><strong>"What is producing this outcome?"</strong></p>
</blockquote>
<p>That is a very different question.</p>
<hr />
<h1>Components do not tell the whole story</h1>
<p>Consider this system:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/6690eb01-82f0-4f4b-8c1c-afee80384e81.png" alt="" style="display:block;margin:0 auto" />

<p>It looks simple.</p>
<p>Now imagine:</p>
<p>The API receives 10,000 requests per second.</p>
<p>The application processes them.</p>
<p>The database can handle only 2,000 writes per second.</p>
<p>The database becomes the constraint.</p>
<p>The application may appear slow.</p>
<p>But the application is not necessarily the root cause.</p>
<p>The system is constrained by the database.</p>
<p>This gives us an important principle:</p>
<blockquote>
<p><strong>The visible problem is not always the system producing the problem.</strong></p>
</blockquote>
<hr />
<h1>A system is about relationships</h1>
<p>Imagine two teams.</p>
<p>Team A has ten engineers.</p>
<p>Team B has ten engineers.</p>
<p>Both teams have similar technical skills.</p>
<p>But Team A needs five approvals before production deployment.</p>
<p>Team B needs one.</p>
<p>Which team can move faster?</p>
<p>The answer may have little to do with engineering capability.</p>
<p>The difference may be the system around the engineers.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/a6788909-02a7-4efe-8977-d274467d5d16.png" alt="" style="display:block;margin:0 auto" />

<p>This is why systems thinking is useful beyond software engineering.</p>
<hr />
<h1>The system boundary matters</h1>
<p>You also need to decide:</p>
<blockquote>
<p>"What exactly am I studying?"</p>
</blockquote>
<p>Suppose your payment fails.</p>
<p>You could study only the payment service.</p>
<p>Or you could study:</p>
<pre><code class="language-plaintext">Customer
 ↓
Checkout
 ↓
Payment Gateway
 ↓
Bank
 ↓
Payment Processor
 ↓
Merchant System
</code></pre>
<p>Your system boundary determines what you can see.</p>
<p>If your boundary is too small, you may miss the real constraint.</p>
<p>If it is too large, the analysis becomes unnecessarily complicated.</p>
<p>Good system design therefore starts with defining the boundary.</p>
<hr />
<h1>A practical model</h1>
<p>When I start looking at a system, I use:</p>
<img src="https://cdn.hashnode.com/uploads/covers/6aa308d41b7498f5632bc234/5ec1152d-58bc-4e99-a907-e16d5d4baa9d.png" alt="" style="display:block;margin:0 auto" />

<p>Notice something important.</p>
<p>The intervention comes <strong>after</strong> understanding the system.</p>
<p>Not before.</p>
<hr />
<h1>The beginner mistake</h1>
<p>A common mistake is:</p>
<pre><code class="language-plaintext">Problem
 ↓
Solution
</code></pre>
<p>For example:</p>
<p>"Application is slow."</p>
<p>Solution:</p>
<p>"Add Redis."</p>
<p>But why is it slow?</p>
<p>Maybe caching helps.</p>
<p>Maybe it does not.</p>
<p>Perhaps the real issue is database contention.</p>
<p>Perhaps network calls dominate latency.</p>
<p>Perhaps an external dependency is slow.</p>
<p>Technology should come after understanding the system.</p>
<hr />
<h1>The engineering perspective</h1>
<p>As you become more experienced, architecture becomes less about memorizing technologies.</p>
<p>It becomes more about answering questions.</p>
<p>Where is the state?</p>
<p>Who owns it?</p>
<p>What happens when something fails?</p>
<p>Where is the bottleneck?</p>
<p>What must be strongly consistent?</p>
<p>What can eventually become consistent?</p>
<p>What happens when traffic increases?</p>
<p>What happens when dependencies become unavailable?</p>
<p>What happens when the system does not know whether an operation succeeded?</p>
<p>These questions are systems questions.</p>
<hr />
<h1>A simple exercise</h1>
<p>Take any application you use.</p>
<p>A banking application.</p>
<p>Food delivery.</p>
<p>Instagram.</p>
<p>An eCommerce website.</p>
<p>Draw this:</p>
<pre><code class="language-plaintext">User
 ↓
 ?
 ↓
 ?
 ↓
 ?
 ↓
Outcome
</code></pre>
<p>Then fill in the components.</p>
<p>After that, ask:</p>
<ol>
<li><p><code>What are the inputs?</code></p>
</li>
<li><p><code>What are the outputs?</code></p>
</li>
<li><p><code>Which components depend on each other?</code></p>
</li>
<li><p><code>Where can the system fail?</code></p>
</li>
<li><p><code>What is the most likely constraint?</code></p>
</li>
<li><p><code>What must always be correct?</code></p>
</li>
<li><p><code>What can eventually become consistent?</code></p>
</li>
</ol>
<p>You have just started doing system design.</p>
<hr />
<h1>The deeper idea</h1>
<p>System design is not primarily about drawing boxes.</p>
<p>It is about understanding <strong>relationships, constraints and outcomes</strong>.</p>
<p>Once you understand that, technologies become easier to reason about.</p>
<p>You stop asking:</p>
<blockquote>
<p>"Should I use Kafka?"</p>
</blockquote>
<p>And start asking:</p>
<blockquote>
<p>"Do I need asynchronous event distribution here?"</p>
</blockquote>
<p>You stop asking:</p>
<blockquote>
<p>"Should I use Redis?"</p>
</blockquote>
<p>And start asking:</p>
<blockquote>
<p>"Do I have a low latency access problem that should be separated from my primary data store?"</p>
</blockquote>
<p>That shift is the beginning of systems thinking.</p>
<hr />
<h2><mark class="bg-yellow-200 dark:bg-yellow-500/30">Think in Systems</mark></h2>
<p>I write about software systems, AI systems, business systems and the thinking behind better decisions.</p>
<p><strong>Complex problems. Simple systems. Better outcomes.</strong></p>
<p>Subscribe to <a href="https://newsletter.abhijeetbatsa.com/subscribe"><strong><mark class="bg-yellow-200 dark:bg-yellow-500/30">Think in Systems</mark></strong></a> for the deeper weekly breakdown.</p>
]]></content:encoded></item></channel></rss>