<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged system-architecture</title>
<link>https://coderlegion.com/tag/system-architecture</link>
<description>Powered by Question2Answer</description>
<item>
<title>Why Your Tech Stack Doesn’t Matter</title>
<link>https://coderlegion.com/16905/why-your-tech-stack-doesnt-matter</link>
<description>&lt;h3 id=&quot;architecting-for-reliability-in-the-age-of-multi-agent-systems&quot;&gt;Architecting for Reliability in the Age of Multi-Agent Systems&lt;/h3&gt;
&lt;p&gt;We are currently over-indexing on &quot;Model Orchestration.&quot; &lt;/p&gt;
&lt;p&gt;Every week, a new library, a new vector database, or a new framework tops the GitHub trending charts. &lt;/p&gt;
&lt;p&gt;This week it might be &lt;a rel=&quot;nofollow&quot; href=&quot;https://info.langchain.com/&quot;&gt;LangGraph&lt;/a&gt;. The next &lt;a rel=&quot;nofollow&quot; href=&quot;https://crewai.com/&quot;&gt;CrewAI&lt;/a&gt;. Something else right behind it.&lt;/p&gt;
&lt;p&gt;Every week the same question shows up:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;Which stack should I use to build a reliable multi-agent system?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It's the wrong question.&lt;/p&gt;
&lt;p&gt;Because I've yet to see a system fail because to the wrong framework, language, or database.&lt;/p&gt;
&lt;p&gt;I've seen them fail because they couldn't recover state, couldn't control context, and couldn't explain what they just did. &lt;/p&gt;
&lt;p&gt;There’s a persistent belief that the logo on the documentation is the secret sauce for a production-ready system.&lt;/p&gt;
&lt;p&gt;It isn’t. In fact, if you’re spending the majority of your time debating the stack, you’re missing the architectural patterns that actually determine whether your agents will succeed or hallucinate into oblivion.&lt;/p&gt;
&lt;h3 id=&quot;the-illusion-of-the-framework&quot;&gt;The Illusion of the Framework&lt;/h3&gt;
&lt;p&gt;A Multi-Agent System (MAS) is &lt;strong&gt;not&lt;/strong&gt; a library problem. It is a &lt;strong&gt;State Management&lt;/strong&gt; problem disguised as an AI problem. Whether you use a graph-based logic or a role-based queue, the fundamental challenges and failure modes remain identical:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lost state&lt;/li&gt;
&lt;li&gt;bloated context&lt;/li&gt;
&lt;li&gt;untraceable decisions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The stack you choose is merely the syntax you use to solve universal engineering constraints.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;The Core Thesis:&lt;/strong&gt; Reliability in agentic workflows is derived from &lt;em&gt;patterns&lt;/em&gt;, not &lt;em&gt;packages&lt;/em&gt;. A secure, scalable system built in Python looks fundamentally the same as one built in Rust if the underlying system primitives are respected.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;the-three-constants-of-reliable-agents&quot;&gt;The Three Constants of Reliable Agents&lt;/h3&gt;
&lt;p&gt;Regardless of your tools, your architecture must solve for these three pillars to move from a &quot;cool demo&quot; to a production asset:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;State is Sovereign&lt;br&gt;
If an agentic loop fails at step 7 of 12, does your system restart from scratch? If so, your stack doesn't matter because your architecture is broken. A resilient system requires &lt;strong&gt;Deterministic Checkpointing&lt;/strong&gt;: &lt;ul&gt;
&lt;li&gt;Capture the full &lt;strong&gt;thread state&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Preserve &lt;strong&gt;intent&lt;/strong&gt;, not just data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resume&lt;/strong&gt; execution without replaying the entire workflow.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Without this, your system is just a loop with amnesia.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Context Tax&lt;br&gt;
Context windows are not infinite. In reality, every token you give an agent is a tax on its reasoning. The &quot;how&quot; isn't about which LLM you use; it's about the &lt;strong&gt;Routing Layer&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Classify intent&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expose&lt;/strong&gt; only relevant tools&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minimize&lt;/strong&gt; context surface area&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Less context doesn’t limit the system—it sharpens it.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Governance as a First-Class Citizen&lt;br&gt;
An agent is a service principal. If it cannot be audited, revoked, or sandboxed at the identity level, it shouldn't have access to your data or exist in production. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A reliable system enforces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Least-Privilege Authorization&lt;/strong&gt;, ensuring agents operate within a cryptographic &quot;box&quot; regardless of whether they are running in a Docker container or a serverless function.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scoped&lt;/strong&gt; tool usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Traceable execution&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;/h3&gt;
&lt;p&gt;Consider a simple multi-agent workflow:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.kenwalger.com/blog/wp-content/uploads/2026/05/mermaid-diagram-2026-05-06-153045.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;If your system can't resume from that point with the same context and intent, you don't have a system.&lt;/p&gt;
&lt;p&gt;You have a demo.&lt;/p&gt;
&lt;p&gt;A reliable system looks different.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.kenwalger.com/blog/wp-content/uploads/2026/05/mermaid-diagram-2026-05-06-153110.png&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-framework-agnostic-checklist&quot;&gt;The Framework-Agnostic Checklist&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Pillar        &lt;/th&gt;&lt;th&gt;The Real Question&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Coordination  &lt;/td&gt;&lt;td&gt;How do agents hand off work without bloating context or losing intent?&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Observability &lt;/td&gt;&lt;td&gt;Can we trace every decision back to inputs and reasoning steps?&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Resilience    &lt;/td&gt;&lt;td&gt;What happens when a model fails mid-workflow? Can we resume without replaying?&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Sovereignty   &lt;/td&gt;&lt;td&gt;Who owns the data and execution environment—us or the platform?&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;closing-thoughts&quot;&gt;Closing Thoughts&lt;/h3&gt;
&lt;p&gt;These are not new problems. They're just showing up in a new layer.&lt;/p&gt;
&lt;p&gt;Stop chasing the framework. A system built in Python and one built in Rust will fail in exactly the same ways if the architecture is wrong.&lt;/p&gt;
&lt;p&gt;The difference isn't the stack. It's whether you've designed for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Control&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The tools are interchangeable. The architecture is not.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;This is the foundation for the upcoming &lt;em&gt;Sovereign Synapse&lt;/em&gt; series—where we move from theory to a local-first system that treats memory, context, and ownership as first-class concerns.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/16905/why-your-tech-stack-doesnt-matter</guid>
<pubDate>Wed, 06 May 2026 22:39:04 +0000</pubDate>
</item>
<item>
<title>8 Most Important System Design Concepts You Should Know</title>
<link>https://coderlegion.com/3625/8-most-important-system-design-concepts-you-should-know</link>
<description>&lt;p&gt;Get a Free System Design PDF with 158 pages by subscribing to our weekly newsletter: &lt;a rel=&quot;nofollow&quot; href=&quot;https://bit.ly/bbg-social&quot;&gt;https://bit.ly/bbg-social&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Animation tools: Adobe Illustrator and After Effects.&lt;/p&gt;
&lt;p&gt;Checkout our bestselling System Design Interview books: &lt;br&gt;
Volume 1: &lt;a rel=&quot;nofollow&quot; href=&quot;https://amzn.to/3Ou7gkd&quot;&gt;https://amzn.to/3Ou7gkd&lt;/a&gt;&lt;br&gt;
Volume 2: &lt;a rel=&quot;nofollow&quot; href=&quot;https://amzn.to/3HqGozy&quot;&gt;https://amzn.to/3HqGozy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The digital version of System Design Interview books: &lt;a rel=&quot;nofollow&quot; href=&quot;https://bit.ly/3mlDSk9&quot;&gt;https://bit.ly/3mlDSk9&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ABOUT US: &lt;br&gt;
Covering topics and trends in large-scale system design, from the authors of the best-selling System Design Interview series.&lt;/p&gt;
</description>
<category>Sys Design &amp; Arch</category>
<guid isPermaLink="true">https://coderlegion.com/3625/8-most-important-system-design-concepts-you-should-know</guid>
<pubDate>Sun, 29 Jun 2025 08:22:17 +0000</pubDate>
</item>
<item>
<title>The subtle art of waiting</title>
<link>https://coderlegion.com/2800/the-subtle-art-of-waiting</link>
<description>&lt;p&gt;Recently, while working on a workshop titled &lt;a rel=&quot;nofollow&quot; href=&quot;https://loftlabs-experiments.github.io/workshop-test-pr-k8s/&quot;&gt;Testing Your Pull Request on Kubernetes with GKE, and GitHub Actions&lt;/a&gt;, I faced twice the same issue: service A needs service B, but service A starts faster than service B, and the system fails. In this post, I want to describe the context of these issues and how I solved them both with the same tool.&lt;/p&gt;
&lt;h3 id=&quot;waiting-in-kubernetes&quot;&gt;Waiting in Kubernetes&lt;/h3&gt;
&lt;p&gt;It might sound strange to wait in Kubernetes. The self-healing nature of the Kubernetes platform is one of its biggest benefits. Let's consider two pods: a Python application and a PostgreSQL database.&lt;/p&gt;
&lt;p&gt;The application starts very fast and eagerly tries to establish a connection to the database.  Meanwhile, the database is initializing itself with the provided data; the connection fails. The pod ends up in the &lt;code&gt;Failed&lt;/code&gt; state.&lt;/p&gt;
&lt;p&gt;After a while, Kubernetes requests the application pod's state. Because it's failed, it terminates it and starts a new pod. At this point, two things can happen: the database pod isn't ready yet, and it's back to square one or it's ready, and the application finally connects.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=14558761510786390433&quot; alt=&quot;Kubernetes self-healing sequence diagram&quot;&gt;&lt;/p&gt;
&lt;p&gt;To speed up the process, Kubernetes offers &lt;a rel=&quot;nofollow&quot; href=&quot;https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-startup-probes&quot;&gt;startup probes&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;startupProbe:
  httpGet:
    path: /health
    port: 8080
  failureThreshold: 30
  periodSeconds: 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With the above probe, Kubernetes waits for an initial ten seconds before requesting the pod's status. If it fails, it waits for another ten seconds. Rinse and repeat 30 times before it fails definitely.&lt;/p&gt;
&lt;p&gt;You may have noticed the HTTP &lt;code&gt;/healthz&lt;/code&gt; endpoint above. Kubernetes offers two exclusive &lt;a rel=&quot;nofollow&quot; href=&quot;https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#Probe&quot;&gt;Probe&lt;/a&gt; configuration settings: &lt;code&gt;httpGet&lt;/code&gt; or &lt;code&gt;exec&lt;/code&gt;. The former is suitable for web applications, while the latter is for other applications. It implies we need to know which kind of container the pod contains and how to check its status, provided it can. I'm no PostgreSQL expert, so I searched for a status check command. The &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/bitnami/charts/blob/main/bitnami/postgresql/templates/primary/statefulset.yaml#L417-L427&quot;&gt;Bitnami Helm Chart&lt;/a&gt; looks like the following when applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;startupProbe:
  exec:
    command:
      - /bin/sh
      - -c
      - -e
      - exec pg_isready -U $PG_USER -h $PG_HOST -p $PG_PORT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the above is a simplification, as it gladly ignores the database name and an SSL certificate.&lt;/p&gt;
&lt;p&gt;The startup probe speeds things up compared to the default situation if you configure it properly. You can set a long initial delay, and then shorter increments. Yet, the more diverse the containers, the harder it gets to configure, as you need to be an expert in each of the underlying containers.&lt;/p&gt;
&lt;p&gt;It would be beneficial to look for alternatives.&lt;/p&gt;
&lt;h3 id=&quot;wait4x&quot;&gt;Wait4x&lt;/h3&gt;
&lt;p&gt;Alternatives are tools whose focus is on waiting. A long time ago, I found the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/eficode/wait-for&quot;&gt;wait-for&lt;/a&gt; script for this. The idea is straightforward:&lt;/p&gt;
&lt;p&gt;&amp;gt;&lt;code&gt;./wait-for&lt;/code&gt; is a script designed to synchronize services like docker containers. It is &lt;code&gt;sh&lt;/code&gt; and &lt;code&gt;alpine&lt;/code&gt; compatible.&lt;/p&gt;
&lt;p&gt;Here's how to wait for an HTTP API:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sh -c './wait-for http://my.api/health -- echo &quot;The api is up! Let's use it&quot;'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It got the job done, but at the time, you had to copy the script and manually check for updates. I've checked, and the project now provides a regular container.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://wait4x.dev/&quot;&gt;wait4x&lt;/a&gt; plays the same role, but is available as a versioned container and provides more services to wait for: HTTP, DNS, databases, and message queues. That's my current choice.&lt;/p&gt;
&lt;p&gt;Whatever tool you use, you can use it inside an &lt;a rel=&quot;nofollow&quot; href=&quot;https://kubernetes.io/docs/concepts/workloads/pods/init-containers/[init&quot;&gt;https://kubernetes.io/docs/concepts/workloads/pods/init-containers/[init&lt;/a&gt; container]:&lt;/p&gt;
&lt;p&gt;&amp;gt;A Pod can have multiple containers running apps within it, but it can also have one or more init containers, which are run before the app containers are started.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&amp;gt;Init containers are regular containers, except:&lt;/p&gt;
&lt;p&gt;&amp;gt;&lt;em&gt; Init containers always run to completion.&lt;br&gt;
&amp;gt;&lt;/em&gt; Each init container must complete successfully before the next one starts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Imagine the following &lt;code&gt;Pod&lt;/code&gt; that depends on a PostgreSQL &lt;code&gt;Deployment&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  labels:
    type: app
    app: recommandations
spec:
  containers:
    - name: recommandations
      image: recommandations:latest
      envFrom:
        - configMapRef:
            name: postgres-config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The application is Python and starts quite fast. It attempts to connect to the PostgreSQL database. Unfortunately, the database hasn't finished initializing, so the connection fails, and Kubernetes restarts the pod.&lt;/p&gt;
&lt;p&gt;We can fix it with an &lt;code&gt;initContainer&lt;/code&gt; and a waiting container:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  labels:
    type: app
    app: recommandations
spec:
  initContainers:
    - name: wait-for-postgres
      image: atkrad/wait4x:3.1
      command:
        - wait4x
        - postgresql
        - postgres://$(DATABASE_URL)?sslmode=disable
      envFrom:
        - configMapRef:
            name: postgres-config
  containers:
    - name: recommandations
      image: recommandations:latest
      envFrom:
        - configMapRef:
            name: postgres-config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above setup, the &lt;code&gt;initContainer&lt;/code&gt; doesn't stop until the database accepts connections. When it does, it terminates, and the &lt;code&gt;recommandations&lt;/code&gt; container can start. Kubernetes doesn't need to terminate the &lt;code&gt;Pod&lt;/code&gt; as in the previous setup! It entails fewer logs and potentially fewer alerts.&lt;/p&gt;
&lt;h3 id=&quot;when-waiting-becomes-mandatory&quot;&gt;When waiting becomes mandatory&lt;/h3&gt;
&lt;p&gt;The above is a slight improvement, but you can do without it. In other cases, waiting becomes mandatory. I experienced it recently when preparing for the workshop mentioned above. The scenario is the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The pipeline applies a manifest on the Kubernetes side&lt;/li&gt;
&lt;li&gt;In the next step, it runs the test&lt;/li&gt;
&lt;li&gt;As the test starts before the application is read, it fails.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We must wait until the backend is ready before we test. Let's use &lt;code&gt;wait4x&lt;/code&gt; to wait for the &lt;code&gt;Pod&lt;/code&gt; to accept requests before we launch the tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- name: Wait until the application has started
  uses: addnab/docker-run-action@v3                                       #1
  with:
    image: atkrad/wait4x:latest
    run: wait4x http ${{ env.BASE_URL }}/health --expect-status-code 200  #2
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;The GitHub Action allows running a container. I could have downloaded the Go binary instead.&lt;/li&gt;
&lt;li&gt;Wait until the &lt;code&gt;/health&lt;/code&gt; endpoint returns a &lt;code&gt;200&lt;/code&gt; response code.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Kubernetes startup probes are a great way to avoid unnecessary restarts when you start services that depend on each other. The alternative is an external waiting tool configured in an &lt;code&gt;initContainer&lt;/code&gt;. &lt;code&gt;wait4x&lt;/code&gt; is a tool that can be used in other contexts. It's now part of my toolbelt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To go further:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/wait4x/wait4x#wait4x&quot;&gt;wait4x&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://vadosware.io/post/so-you-need-to-wait-for-some-kubernetes-resources/&quot;&gt;So you need to wait for some Kubernetes resources?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Originally published at &lt;a rel=&quot;nofollow&quot; href=&quot;https://blog.frankel.ch/subtle-art-waiting/&quot;&gt;A Java Geek&lt;/a&gt; on April 20&lt;sup&gt;th&lt;/sup&gt;, 2025&lt;/em&gt;&lt;/p&gt;
</description>
<category>Java</category>
<guid isPermaLink="true">https://coderlegion.com/2800/the-subtle-art-of-waiting</guid>
<pubDate>Wed, 23 Apr 2025 21:40:24 +0000</pubDate>
</item>
</channel>
</rss>