<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by IcePanel on Medium]]></title>
        <description><![CDATA[Stories by IcePanel on Medium]]></description>
        <link>https://medium.com/@icepanel?source=rss-7709f5c2ae4f------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*tXX6rP-gt0eJTPQbFNqsEw.png</url>
            <title>Stories by IcePanel on Medium</title>
            <link>https://medium.com/@icepanel?source=rss-7709f5c2ae4f------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 09 Jun 2026 02:57:48 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@icepanel/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Adopting ADRs in Enterprise]]></title>
            <link>https://icepanel.medium.com/adopting-adrs-in-enterprise-842a4e8ab474?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/842a4e8ab474</guid>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[saas]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[enterprise-architecture]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Fri, 08 May 2026 15:43:30 GMT</pubDate>
            <atom:updated>2026-05-08T15:43:30.241Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*LoKPTyBJih8oaAx2.png" /></figure><p>For anyone who has spent the past few years repeatedly giving LLMs the context behind something before it can give you a useful answer, then I’m sure you’ve come to understand just how easy it is for information to become siloed inside even a small organisation and maybe known only by you.</p><p>In enterprise organisations, this unintentional information gatekeeping not only means team members have to spend time running around searching for the right person to understand why an architectural decision was made three years ago. A lot of the time, the reasoning behind those decisions has eroded away or been forgotten completely.</p><p>This isn’t good, and it’s certainly not useful if you intend to dust off your auth flow and consider something new, but need to check in with those who built the original version. Those previous decisions may be propping up other architectural decisions. It’s like a stack of fragile playing cards, ready to tumble at the slightest gust of wind.</p><p>There’s a whole world of ways in which teams may choose to share why important decisions were made. Maybe in long-form text in a word editor, maybe in a markdown file tied to a repo, a Slack thread, an email or perhaps a mixture of all of them (which is unfortunately most common). You get the idea, these decisions and most importantly all of that context is scattered, and often dependent on the right person still being around.</p><p>That’s one reason I’m so sold on ADRs (Architectural Decision Records). Designed to serve as lightweight records of the context behind architecture decisions, ADRs are a log of important decisions made by a team, and the context that surrounds them.</p><h3>What goes inside an ADR?</h3><p>Michael Nygard, the man who popularised the idea of ADRs, <a href="https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions">suggests</a> they should consist of five things: a title (a logical name for the decision), a status (was this idea adopted, rejected or superseded), the context, the decision itself, and the consequences.</p><p>That’s a great default and many teams also benefit from expanding on it slightly. One of the most valuable additions is an alternatives considered section, a record of the options you evaluated but didn’t choose, and why. This is where the real value of an ADR lives.</p><p>Without this, future engineers have no way of knowing whether an alternative was already debated and ruled out, or simply never considered. The difference matters enormously when someone shows up three years later, suggesting you switch from REST to GraphQL and the team has no memory of the two-week debate that already happened… 3 times!</p><p>You might also consider including assumptions and constraints that were true at the time of the decision. Architectural decisions are often only correct under a specific set of circumstances. Capturing those circumstances makes it far easier to know when a decision should be revisited.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*scoBzOgG7nDVIsGU.png" /><figcaption>Example ADR inside IcePanel</figcaption></figure><h3>Keep them concise</h3><p>ADRs shouldn’t become short novels. The goal is a document that’s easily digestible, something an engineer or architect can read in five minutes and walk away with a clear understanding of what was decided and why.</p><p>It’s far too easy to create documentation that’s “over-engineered” (please pardon the pun).</p><p>The reality is that fewer people will read longer documents, and if the important details are buried three pages in, people skim and miss things. The goal should be to keep the main signal as clean as possible. You can always link out to supporting documentation if a topic needs expansion, but resist the urge to make the ADR itself overly explained.</p><h3>Who writes them, and when</h3><p>ADRs shouldn’t be the exclusive domain of architects or tech leads. Any engineer driving a significant decision should be authoring one. If people assume it’s someone else’s job, they simply never get written. You may choose to have them only approvable by a tech lead or architect, but they can be approached collaboratively.</p><p>The right moment to write an ADR is before or during the decision, not after. After-the-fact ADRs have a tendency to become rationalisations once the outcome is already known. If they are written in the moment, they capture the genuine uncertainty, the tradeoffs actually considered, and the constraints that were real at the time. That’s what makes them useful later.</p><h3>ADRs have a lifecycle</h3><p>One of the most important and non-obvious things about ADRs is what happens when a decision gets revisited. You don’t delete the old record. You mark it as superseded e.g. “superseded by ADR-042” and write a new one explaining what changed and why. This creates a useful audit trail you can follow through time. This kind of internal org memory is rare and has outsized value.</p><h3>How granular should ADRs be?</h3><p>As a rule of thumb, any decision that required significant debate, or carries a large number of upstream or downstream dependencies, is worth logging. Choosing PostgreSQL over MongoDB for a new core service is an ADR. Deciding on a caching strategy that affects multiple teams is an ADR. Renaming a variable, or choosing a library for a one-off script, is not.</p><p>If you find your team debating whether something warrants an ADR, it probably does.</p><h3>Rolling this out</h3><p>If you’re interested in adopting ADRs across your organisation, attempting to do this across all teams at once is possible, but not advisable. Start with one team. Ideally, the tech lead is already bought into the idea and understands the value of having important decisions be searchable and clearly logged. Let that team build the habit, refine the template to suit your organisation, and then introduce the concept to other teams, with evidence of how this has been useful for the original team. Start small, experiment, customize, then scale.</p><h3>Why is now a good time to implement this sort of structure?</h3><p>LLMs rely on context to give you useful answers and output. The greater the context, the greater the answer. With the IcePanel MCP, your AI tooling can now read directly from IcePanel. Super handy if you’re about to set an agent on a task to rebuild a part of your service and need to surface constraints. It’s becoming clear that teams who invest in internal memory now are going to get significantly more out of AI tooling than those who don’t. ADRs are a small habit with compounding returns, and it couldn’t be a better time to start building that habit!</p><p>Get started and <a href="https://app.icepanel.io/">write your first ADR</a> ✍️</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=842a4e8ab474" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Impact of AI on Migration Projects]]></title>
            <link>https://icepanel.medium.com/impact-of-ai-on-migration-projects-1a7e3c035d71?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/1a7e3c035d71</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[llm]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Mon, 27 Apr 2026 16:09:22 GMT</pubDate>
            <atom:updated>2026-04-27T16:09:22.775Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bjK9AFhHT5NMNvbM5tDI7g.png" /></figure><h3>Introduction</h3><p>Software architects play a key role in maintaining architectures through migration projects. Reasons might be driven by security requirements (e.g., integrating with a new 3rd party system or deprecating legacy software) or complying with new product requirements (e.g., scaling to meet customer demand or supporting new features from developer teams).</p><p>AI has a visible impact on software development, from coding to testing to documenting features. Now with the rise of AI agents, there are opportunities to integrate AI workflows for architecture-focused projects.</p><p>In this post we’ll talk about the impact of using AI tools like <a href="https://claude.com/product/claude-code">Claude Code</a> or <a href="https://openai.com/codex/">Codex</a> for architecture projects. We’ll cover what a migration project looks like, the pros and cons of using AI, and tips for managing such projects.</p><h3>Case study: Database migration project</h3><p>I once had a 6-month project to migrate our primary database (<a href="https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraPostgreSQL.html">Aurora PostgreSQL</a>) with multiple microservices connected directly. There was a product discussion to scale our system, and as a result of horizontally scaling the microservices, we started hitting connection limits to Aurora. The services were exhausting the database’s max connections during peak traffic and causing intermittent failures and slow queries.</p><p>Wearing the architect’s hat, we started to scope the problem. The project seemed straightforward on paper, but there were several dependencies that required a careful rollout strategy. For example:</p><ol><li>How many services were connected to our primary database?</li><li>What were the read/write patterns? Some services were read-heavy and could be routed to read replicas. Others needed write access to the primary.</li><li>What other migrations or projects are in flight? We had to coordinate timelines with two other teams shipping features that depended on the same database.</li><li>What would the post-migration deployment process look like? Every team deploying a new service needs to know the new connection path.</li></ol><p>Our solution was to introduce <a href="https://aws.amazon.com/rds/proxy/">RDS Proxy</a> as an intermediary layer between the database and services. This allows services to point to the proxy endpoint instead of the database directly. The proxy handles connection pooling, failover, and routing to read replicas.</p><p>To manage a safe migration, we had to roll this out into multiple stages:</p><ul><li>Stage A: Deploy RDS proxy</li><li>Stage B: Migrate services one by one</li><li>Stage C: Scale out the architecture by adding more read replicas</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0cubwJ8cmz-_XTmTLpPfCA.png" /></figure><p>The proxy deployment itself was straightforward. What took time was the coordination: testing each service’s behaviour through the proxy under load, validating failover scenarios, getting sign-off through the organisation’s process, and sequencing the migration across teams without disrupting production traffic.</p><h3>AI impact</h3><p>What worked well was collecting data points with agentic tools like <a href="https://claude.com/product/claude-code">Claude Code</a> or <a href="https://windsurf.com/cascade">Cascade</a> and building a prototype to test the RDS proxy connection. For example, we used AI to audit the 12 services connected to the primary database and map their query patterns. We used AI to prototype most of the Terraform configuration for the proxy. It also wrote the migration playbook for other teams. Each service migration required updating infrastructure environment variables, running regression tests, and redeploying.</p><h3>How can AI help</h3><p>There are three main things AI can massively help:</p><ol><li>Automating repeatable tasks</li><li>Prototyping and researching solutions</li><li>Challenging your proposals</li></ol><h4>1. Automate repeatable tasks</h4><p>Architects or engineers will be asked to follow some process when driving this migration project. Depending on your organisation, you might need to write story-pointed tasks, share a technical spec for review, or give regular updates. Some of these tactics are repeatable steps that architects have to allocate time for to deliver a project successfully. However, they can be time expensive for an engineering resource, especially at scale. That’s where AI automation can help.</p><p>AI excels at these repeatable artifacts. You can prompt it to generate Jira tickets from a migration checklist, draft status updates from commit logs, or convert meeting notes into action items. The key is investing in building templates that align with your organisation’s format so it can produce consistent outputs with minimal editing.</p><h4>2. Prototyping and researching ideas</h4><p>Architects need to prototype solutions and evaluate alternatives before committing. AI can help accelerate prototype development and generate comparisons with the main architect as the decision maker.</p><p>For example, in our RDS proxy migration, we used AI to compare connection pooling alternatives (RDS Proxy vs application-level pooling) and draft Terraform modules for services. This let us evaluate trade-offs in order of hours without investing too much development time.</p><h4>3. Challenging your proposals</h4><p>Before I publish a migration plan or share a technical spec with stakeholders, I like to prompt AI to critique my ideas. I’ve found AI surprisingly good at surfacing edge cases and suggesting changes. If I’m brainstorming a new solution, I often try to challenge my thinking and see if there’s a better way to solve a problem. With AI, I’m able to broaden the solution space and identify the optimal solution to adopt.</p><h3>Where AI falls short</h3><h4>1. Verbosity (AI-slop)</h4><p>AI is good at generating content, not context. Whenever you’re prompting an LLM to explain or document, it will often lean towards generating more characters to make the overall output “look” good, but with marginal value.</p><h4>2. Over-simplification</h4><p>AI is good at solving problems based on the parameters it is aware of. As you work on a migration project, it is a good practice not to accept AI-generated solutions at face value, because there is a good chance it is missing context and oversimplifying the problem you’re trying to solve. For example, if you have two repositories: (1) Application repo and (2) Infrastructure repo, and you gave access to (2) to help come up with a migration plan. It is almost certain that without scanning other sources like (1), it will misjudge the complexity of the problem and give answers without seeing the full picture.</p><p>My advice is to try to give access to multiple tools/MCPs, but be critical of the output and identify missing context.</p><h4>3. Delegating critical decisions to AI</h4><p>Jeff Bezos once introduced the idea of “Decision Types” that later became a core part of Amazon’s culture: Type 1 and Type 2 decisions. He wrote the following in a <a href="https://www.sec.gov/Archives/edgar/data/1018724/000119312516530910/d168744dex991.htm">shareholder letter</a>:</p><p>“Some decisions are consequential and irreversible or nearly irreversible — one-way doors — and these decisions must be made methodically, carefully, slowly, with great deliberation and consultation. If you walk through and don’t like what you see on the other side, you can’t get back to where you were before. We can call these Type 1 decisions. But most decisions aren’t like that — they are changeable, reversible — they’re two-way doors. If you’ve made a suboptimal Type 2 decision, you don’t have to live with the consequences for that long. You can reopen the door and go back through. Type 2 decisions can and should be made quickly by high judgment individuals or small groups.”</p><p>Using AI for Type 2 decisions is a great use case. It frees up decision-making space from engineers and allows them to focus on the right problems. However, using AI for Type 1 decisions can be very expensive and risky. Primarily, because you are accountable for the end product of your decisions, and delegating it to AI can damage your reputation and affect the overall project.</p><p>Good advice is to explore AI tools and automate most (if not all) Type 2 decisions, and allocate deep thinking for Type 1 decisions.</p><h3>Conclusion</h3><p>Architectural thinking has and continues to be a core skill required by businesses from their architects. AI cannot replace that skill, however it can add great leverage for software architects like automating repeatable tasks, prototyping, and research. On the flip side, AI falls short on things like context-heavy decisions and accountability.</p><p>If you’re working on a migration project, try to use AI to accelerate the mechanics, but own the strategy. Software architects and engineers are needed for human judgment on many activities like project scoping, coordination, stakeholder alignment, and planning architectural changes.</p><h3>📚 Resources</h3><ul><li><a href="https://www.ibm.com/think/topics/agentic-engineering">https://www.ibm.com/think/topics/agentic-engineering</a></li><li><a href="https://addyosmani.com/blog/agentic-engineering/">https://addyosmani.com/blog/agentic-engineering/</a></li><li><a href="https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html">https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html</a></li><li><a href="https://aws.amazon.com/rds/proxy/">https://aws.amazon.com/rds/proxy/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1a7e3c035d71" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Design a metrics & alerting system using IcePanel]]></title>
            <link>https://icepanel.medium.com/design-a-metrics-alerting-system-using-icepanel-26767cae3959?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/26767cae3959</guid>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[grafana]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Tue, 03 Mar 2026 22:19:43 GMT</pubDate>
            <atom:updated>2026-03-03T22:21:13.155Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NzBODtLsDu6sTAHny2ZOiQ.png" /></figure><h3>📝 Introduction</h3><p>In this post, we’ll design a Metrics Monitoring and Alerting System that engineers use for their infrastructure observability and maintenance health. The industry standard for this system is a combination of two technologies: <a href="https://prometheus.io/"><strong>Prometheus</strong></a> (metrics collection, storage, and alerting) and <a href="https://grafana.com/grafana/"><strong>Grafana</strong></a><strong> </strong>(visualisation).<strong> </strong>We’ll break down the problem, establish scope, and design the system as software architects. We’ll also create four hierarchical diagrams: Context, Container, Component, and Code (not familiar with these? Read <a href="https://icepanel.io/blog/2024-07-18-what-is-the-c4-model">this</a>).</p><p>Each diagram will be annotated to explain the key building blocks and responsibilities, and we’ll highlight how users interact with the system by visualising data flow using <a href="https://docs.icepanel.io/visual-storytelling/flows">IcePanel Flows</a>.</p><p>We’ll start by defining the scope of the system through its functional requirements (what the system does) and non-functional requirements (the qualities it should have). From there, we’ll progressively go through each layer of the C4 model to build the overall architecture.</p><p>You can view the final architecture at this link: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/IlDZ">https://s.icepanel.io/DWnaysJ3cbCQqg/IlDZ</a></p><h3>🔎 Scope</h3><p>A well-designed monitoring and alerting system plays a key role in providing visibility into the health of a system’s infrastructure. This is crucial for engineers who want to ensure high availability and reliability of their systems. This will be factored into our non-functional requirements.</p><p>First, we define what we mean by <strong>metrics</strong> in this post:</p><ol><li><strong>Infrastructure metrics: </strong>Operational system metrics that contain low-level usage data such as CPU load, memory usage, and disk space.</li><li><strong>Software metrics</strong>: Service-level metrics containing higher-level data like requests per second, request latency, or number of running servers in a cluster.</li><li><strong>Business metrics</strong>: This is outside the scope of this post. We’ll focus on infrastructure and software metrics.</li></ol><p>The functional requirements for this system are:</p><ol><li>Engineers should be able to query data sources (Prometheus) and view real-time dashboards and metrics (Grafana).</li><li>The system should evaluate alert rules (Prometheus) against metrics and page on-call engineers when rules have been breached.</li></ol><p>The non-functional requirements for this system are:</p><ul><li>Highly scalable. Our metrics collection pipeline should accommodate growing metrics and alert volume. Let’s quantify it as 100 server pools and 100 machines per pool, scraping ~100 metrics per machine every 10 seconds. Roughly 100,000 data points / second or ~8.6 billion data points per day! This estimate describes a write-heavy system.</li><li>Low latency. Viewing dashboards should reflect near real-time metrics. Engineers should not miss any fired alerts.</li><li>Availability &gt;&gt; consistency. Losing a few data points is tolerable. However, the system must be available 24/7, especially for alerts.</li></ul><p>We’ll intentionally leave log monitoring (<a href="https://www.elastic.co/elastic-stack">ELK stack</a>) and <a href="https://www.datadoghq.com/knowledge-center/distributed-tracing/">distributed tracing</a> outside of scope.</p><p>Let’s start with the first diagram, Context.</p><h3>Level 1 — Context</h3><p>The Context layer defines the actors and external systems we depend on. In this design, we have one actor and three external systems:</p><ol><li><strong>Engineer (Actor):</strong> Monitors system health by querying metrics and viewing dashboards. This includes software engineers, on-call responders, platform, and SREs. They also get notified by alerts from the system in case a predefined threshold was breached.</li><li><strong>AWS CloudWatch (System)</strong>: An AWS monitoring service that collects metrics from cloud infrastructure and managed services. Our system pulls infrastructure metrics from CloudWatch to surface them alongside application metrics. If you’re interested to learn more, this is implemented by a CloudWatch exporter (read <a href="https://github.com/prometheus/cloudwatch_exporter">here</a>).</li><li><strong>Monitored Services (System)</strong>: Self-instrumented applications, databases, and message queues that expose a /metrics HTTP endpoint for our system to pull. Our system scrapes them directly using Prometheus’s <a href="https://dev.to/mikkergimenez/why-is-prometheus-pull-based-36k1">pull model</a>.</li><li><strong>PagerDuty (System)</strong>: An incident management platform that receives triggered alerts from our system. It routes them to the on-call engineer. Other notification channels (Email, Slack, SMS) are also supported but abstracted away for simplicity.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JF6Le4UiFxGDi7BrtuH2hw.png" /></figure><p>Prometheus and Grafana are not visible yet in this Context view. They live inside the system boundary, which we’ll cover next in the Container diagram.</p><h3>Level 2 — Container</h3><p>The Container layer models independently deployable applications, services, and data stores. We use a microservices architecture to independently scale certain workloads and provide high availability and performance as defined in the non-functional requirements. This is a write-heavy system (100k data points / second) with spiky reads (metrics queries or dashboards refreshing every X seconds). This write-heavy pattern directly shapes the architecture decisions in the Container layer below.</p><p>The system is composed of three main parts:</p><h4>1. Metrics collection:</h4><ul><li>Metrics Collector Pool (ECS Autoscaling): Pool of metrics collectors that pull /metrics endpoints from monitored services on a configured interval (e.g., 10 seconds). These collectors are distributed across targets using a consistent hash ring to avoid duplicate data collection.</li><li>Service Discovery (<a href="https://www.google.com/url?q=https://etcd.io/&amp;sa=D&amp;source=editors&amp;ust=1772578132240276&amp;usg=AOvVaw2MDdtKrOCAOJPfE0DakpD0">etcd</a> / <a href="https://www.google.com/url?q=https://zookeeper.apache.org/&amp;sa=D&amp;source=editors&amp;ust=1772578132240484&amp;usg=AOvVaw2D9cjv3Bbzv_nq4uf8h5Ax">Zookeeper</a>): A coordination component that maintains the dynamic registry of scrape targets. It notifies the Metrics Collector Pool when monitored services are added or removed so collectors always know what to scrape.</li><li>Message Queue (<a href="https://www.google.com/url?q=https://kafka.apache.org/&amp;sa=D&amp;source=editors&amp;ust=1772578132241154&amp;usg=AOvVaw1VaMLa2laXuUSX8VeR1OkZ">Kafka</a>): Receives raw metrics from the Collector Pool and buffers them before processing. Decouples collection from storage and prevents data loss when the TSDB is unavailable. Partitioned by metric name and label for parallel consumption.</li><li>Stream Processor (<a href="https://www.google.com/url?q=https://flink.apache.org/&amp;sa=D&amp;source=editors&amp;ust=1772578132241691&amp;usg=AOvVaw3cu821FGTQISZoXCl1gzZu">Flink</a>): Consumes raw metrics from Kafka, aggregates and processes them, then writes to the TSDB. Handles late-arriving data and reduces write volume through pre-aggregation.</li><li>Time-Series Database (<a href="https://www.google.com/url?q=https://www.influxdata.com/&amp;sa=D&amp;source=editors&amp;ust=1772578132242169&amp;usg=AOvVaw003pgQP7mQ_PHGreCYw2q3">InfluxDB</a>): A time-series database (TSDB) that stores all metrics as time-series data with label-based indexing. It provides optimisation features for time-series data like downsampling and data compression.</li></ul><h4>2. Alerting:</h4><ul><li>Prometheus Server (ECS): Evaluates alert rules defined in YAML config files against the TSDB on a configured interval. Pushes fired alerts to Alertmanager via HTTP POST.</li><li>Alert Manager (ECS): Receives fired alerts from Prometheus Server. Deduplicates, groups, and routes them to Alert Consumers via Kafka.</li><li>Alert Store (DynamoDB): Persists alert state (inactive → pending → firing → resolved) to ensure at-least-once delivery across restarts and retries.</li><li>Alert Consumer (ECS): Pulls alert events from Kafka and dispatches notifications to PagerDuty, Slack, Email, or HTTP endpoints.</li></ul><h4>3. Visualisation and querying:</h4><ul><li>Alerts UI (React): Frontend for engineers to view firing alerts and manage silences via the Alertmanager API.</li><li>Metrics Dashboard (React / Grafana Frontend): A UI for engineers to query and visualise time-series metrics via the Query Service.</li><li>Query Service (ECS / Grafana Backend): Receives query requests (via <a href="https://www.google.com/url?q=https://prometheus.io/docs/prometheus/latest/querying/basics/&amp;sa=D&amp;source=editors&amp;ust=1772578132244532&amp;usg=AOvVaw15SgZn0VE1-gWFEqUgrTBy">PromQL</a>) from the Metrics Dashboard, checks Redis for cached results, and falls back to the TSDB on a cache miss.</li><li>Query Cache (Redis): Caches frequently accessed query results to reduce repeated read load on the TSDB.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1xd_EnGQx8cG7paVMVq9pQ.png" /></figure><p>How the system works:</p><p>The system operates across two parallel pipelines (metrics collection pipeline and alerting pipeline), which share the TSDB as the ground-truth datastore.</p><p><strong>Metrics pipeline:</strong> The Metrics Collector Pool scrapes these /metrics endpoints with Service Discovery (zookeeper/etcd) managing the target list dynamically. Scraped metrics are written to Kafka, consumed by the Stream Processor (Flink), and written to the TSDB. When engineers query dashboards, the Metrics Dashboard sends PromQL requests to the Query Service, which checks the Redis cache first, and falls back to the TSDB on a cache miss.</p><p><strong>Alerting pipeline:</strong> The Prometheus Server evaluates alert rules from YAML config files against the TSDB every evaluation interval (e.g., 10 seconds). When a threshold is breached, Prometheus Server pushes the alert to Alert Manager via HTTP POST. Alert Manager deduplicates alerts, routes them to the dispatcher, dispatches to consumers (via Kafka), and persists its state to DynamoDB. Alert Consumers pull from Kafka and dispatch notifications to PagerDuty, Email, Slack, or HTTP endpoints. PagerDuty then pages the on-call engineer.</p><h3>Data flows</h3><p>We’ve designed two primary data flows using IcePanel. Check them out and see how the system works.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/817/1*-YzmDk60qUpH7Shot1hyTA.png" /></figure><p><strong>Flow 1:</strong> Engineer queries a metrics dashboard</p><p>Complete flow: <a href="https://www.google.com/url?q=https://s.icepanel.io/DWnaysJ3cbCQqg/Jvuo&amp;sa=D&amp;source=editors&amp;ust=1772578132248131&amp;usg=AOvVaw1tIZhxLTFSEC3ZZymPRAFV">https://s.icepanel.io/DWnaysJ3cbCQqg/Jvuo</a></p><ol><li>Engineer opens the Metrics Dashboard (Grafana UI)</li><li>React app sends HTTP GET with a PromQL query to the Query Service</li><li>Query Service checks Redis. Cache hit returns immediately; cache miss executes against TSDB</li><li>Time-series data is returned and rendered as charts</li></ol><p><strong>Flow 2: </strong>Alert fires and pages the on-call engineer</p><p>Complete flow: <a href="https://www.google.com/url?q=https://s.icepanel.io/DWnaysJ3cbCQqg/342p&amp;sa=D&amp;source=editors&amp;ust=1772578132249160&amp;usg=AOvVaw0Hf98scaMvyAEpDo47NcY1">https://s.icepanel.io/DWnaysJ3cbCQqg/342p</a></p><ol><li>Prometheus Server evaluates an alert rule against the TSDB</li><li>Prometheus Server pushes alert to Alertmanager via HTTP POST</li><li>Alert event published to Kafka</li><li>Alert Consumer dispatches notification to PagerDuty</li><li>PagerDuty pages the on-call engineer</li></ol><p>Before going into level 3 (Component), there are a few key architectural decisions worth discussing. We’ll go through the data model, storage, and push vs pull models.</p><h3>Data Model</h3><p>Metrics data is recorded as time-series data: a set of values with associated timestamps, uniquely identified by a metric name and optional tags. For example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*l30O0QA5ULirbDr4vHKzMg.png" /></figure><p>An engineer might want to query the system to answer questions like:</p><ul><li>What is the CPU load on the production server at 18:00?</li><li>What is the average memory load across all Redis caches for the last 6 hours?</li><li>What is the total number of requests to our API in the last hour?</li></ul><p>Here’s an example Grafana dashboard showing real-time website performance metrics like memory and CPU usage, server requests, login activity, and client-side page load times broken down by percentile (<a href="https://www.google.com/url?q=https://grafana.com/oss/grafana/&amp;sa=D&amp;source=editors&amp;ust=1772578132251800&amp;usg=AOvVaw2eHXMvK-ozxV5yxVmsJgFv">source</a>).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3lk_U5UdxLU_YY4JF5RMew.png" /></figure><h3>Selecting a database storage</h3><p>In theory, a general-purpose database could support time-series data, but it would require expert-level tuning to make it work at our scale. For example, a SQL database like PostgreSQL is not optimised for operations you would commonly perform against time-series data. NoSQL is another choice. Cassandra can be used for time-series data. However, this would still require expert NoSQL knowledge to design a scalable schema for storing and querying time-series data.</p><p>For this problem, we’ll need a storage system optimized for time-series data. AWS has <a href="https://www.google.com/url?q=https://aws.amazon.com/timestream/&amp;sa=D&amp;source=editors&amp;ust=1772578132253093&amp;usg=AOvVaw1Kql8VU7eXhwJQ9VN0maeO">Timestream</a> as a managed time-series database. According to DB-engines, the two most popular ones are <a href="https://www.google.com/url?q=https://www.influxdata.com/lp/influxdb-database&amp;sa=D&amp;source=editors&amp;ust=1772578132253343&amp;usg=AOvVaw3xxpqdRtwC4amXTODz--Tl">InfluxDB</a> and <a href="https://www.google.com/url?q=https://www.tigerdata.com/timescaledb&amp;sa=D&amp;source=editors&amp;ust=1772578132253460&amp;usg=AOvVaw3IQoJhN3dVNCasScErDUnu">TimescaleDB</a>, which are designed to store large volumes of time-series data and quickly perform real-time analysis on that data. Both of them primarily rely on an in-memory cache and on-disk storage. They both handle durability and performance quite well. For this example, we’ll pick InfluxDB. There was a previous benchmark that reported InfluxDB with 8 cores and 32GB RAM can handle over 250k writes per second, which fits well within our requirements.</p><h3>Pull vs Push model</h3><p>There are two ways metrics data can be collected. In a pull model, dedicated collectors scrape /metrics endpoints from running applications on a configured interval. In a push model, a collection agent is installed on every monitored server as a <a href="https://www.google.com/url?q=https://www.geeksforgeeks.org/system-design/sidecar-design-pattern-for-microservices/&amp;sa=D&amp;source=editors&amp;ust=1772578132254972&amp;usg=AOvVaw3QrQ8sx-q7wh9xtUSI-HBG">sidecar container</a>. Examples of push architecture are <a href="https://www.google.com/url?q=https://aws.amazon.com/cloudwatch/&amp;sa=D&amp;source=editors&amp;ust=1772578132255186&amp;usg=AOvVaw1gstGXS4JqjYBjRa2MhtsH">Amazon CloudWatch</a> and <a href="https://www.google.com/url?q=https://graphite.com/&amp;sa=D&amp;source=editors&amp;ust=1772578132255306&amp;usg=AOvVaw0H4UfPdqfjHiIAEq_MQNj0">Graphite</a>.</p><p><a href="https://www.google.com/url?q=https://dev.to/mikkergimenez/why-is-prometheus-pull-based-36k1&amp;sa=D&amp;source=editors&amp;ust=1772578132255511&amp;usg=AOvVaw1OqdxCbL09xp4W-dj_dzzw">Prometheus uses a pull model</a>. The collector scrapes targets rather than targets pushing to the collector. This is deliberate: it makes the collector the source of truth for what’s being monitored, enables easier debugging (you can curl any /metrics endpoint directly), and allows Service Discovery to manage the target list centrally.</p><p>For our design, we use the pull model as the primary path. CloudWatch metrics enter via the <a href="https://www.google.com/url?q=https://github.com/prometheus/cloudwatch_exporter&amp;sa=D&amp;source=editors&amp;ust=1772578132256292&amp;usg=AOvVaw17R1SVaxiUTg2YVy-jWPE2">CloudWatch Exporter</a>, which translates the CloudWatch API format into the standard /metrics format that Prometheus can scrape.</p><h3>Level 3 — Component</h3><p>In the C4 model, a component is a grouping of related functionality encapsulated behind a well-defined interface. We’ll zoom into three components: Prometheus Server, Alert Manager, and Query Service.</p><h4>1. Prometheus Server</h4><p>Prometheus Server queries the TSDB directly via PromQL to evaluate alert rules and detect threshold violations. It primarily consists of:</p><p>Rule Evaluator: A module that reads alert rules from YAML config files (stored in S3 and downloaded at startup). On every evaluation interval, it executes PromQL queries against the TSDB and compares results against defined thresholds. If a breach persists for the configured duration, it marks the alert as firing and passes it to the Notifier.</p><p>Notifier: A module that receives fired alerts from the Rule Evaluator. It pushes fired alerts to the Alert Manager via HTTP POST /api/v1/alerts, where they are deduplicated, dispatched, and persisted.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KtUFZT4kIILW9HJN2XkzaQ.png" /></figure><h4>2. Alert Manager</h4><p>The Alert Manager receives fired alerts from Prometheus Server and handles the full routing, deduplication, and dispatch lifecycle. It consists of four main modules:</p><p>HTTP Handler: Receives the fired alerts via HTTP POST from Prometheus Server and provides GET endpoints to serve the Alerts UI for engineers to view firing alerts and manage silences.</p><p>Deduplicator: Suppresses duplicate alerts from the handler. If the same alert fires multiple times within a grouping window, it is collapsed into a single notification to prevent spamming the notification channels.</p><p>Alert Dispatcher: Assembles the final alert event and routes it downstream. It publishes the alert event to Kafka for consumption by Alert Consumers.</p><p>DynamoDB Client: Persists the alert state transitions (inactive → pending → firing → resolved) to the Alert Store (DynamoDB). It ensures the system can resume correctly across restarts and guarantees at-least-once delivery across retries.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VaMVPM4ixVp4x916WZo0KQ.png" /></figure><h3>3. Query Service</h3><p>Query Service is Grafana’s core backend. It receives PromQL query requests from the Metrics Dashboard and executes them against the TSDB. It also caches short-lived query results to Redis to serve repeatable queries.</p><p>Query Handler: Receives HTTP GET requests from the Metrics Dashboard containing PromQL expressions. It validates the query, checks Redis for a cached result first, and falls back to executing directly against the TSDB on a cache miss.</p><p>The cache is particularly valuable for dashboard panels that auto-refresh every few seconds. Without caching, every render will hit the TSDB directly and create a spiky read load.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bp02eERvxjLIN3s48RXIyQ.png" /></figure><p>Let’s go one level deeper with the source code in the Code layer.</p><h3>Level 4 — Code</h3><p>At the code level, we focus on implementation structure rather than deployment. Rather than showing full implementations, we model the public API of each component and the contracts between them. This maps directly to the components described at Level 3. We’ll briefly describe two components: <strong>Prometheus Server</strong> and<strong> Alert Manager</strong>.</p><h4>1. Prometheus Server (Rule Evaluator)</h4><p>The Rule Evaluator is the core evaluation loop inside Prometheus Server. It loads alert rule groups from YAML config files, each containing one or more rules with a PromQL expression, a threshold, and a duration (how long a breach must persist before the alert fires). On every evaluation tick it queries the TSDB and compares results. If a rule is breached, it hands the alert to the Notifier.</p><ul><li>class AlertRule</li><li>name: e.g. “HighCPUUsage”</li><li>expr: PromQL expression, e.g. “cpu_usage &gt; 0.9”</li><li>for_duration: seconds a breach must persist before firing</li><li>tags: alert labels in key-value pairs</li><li>class RuleEvaluator</li><li>def load_rules(config_path): Load and parse alert rule groups from a YAML file</li><li>def evaluate(rule: AlertRule): Executes the rule’s PromQL against the TSDB</li><li>def run_evaluation_loop(interval_seconds): Evaluates loaded rules on every tick</li></ul><h4>2. Alert Manager</h4><p>The Alert Manager receives fired alerts from Prometheus Server and handles the full routing, deduplication, and dispatch lifecycle. It stores the state of the alerts, and handles the dispatch to an alert consumer via a Kafka topic.</p><ul><li>​​class Alert</li><li>name: e.g., “HighCPUUsage”</li><li>tags: e.g. {“severity”: “critical”, “env”: “prod”}</li><li>annotations: e.g. {“summary”: “CPU &gt; 90%”}</li><li>state: e.g., inactive, pending, firing, resolved</li><li>fired_at:</li><li>resolved_at:</li><li>class AlertReceiver: HTTP handler for Prometheus Server.</li><li>def receive(alerts: list[Alert]): Accepts a batch of alerts from Prometheus Server</li><li>class AlertStore: DynamoDB client for persisting alert state.</li><li>def save(alert: Alert): Persist an alert and its current state to DynamoDB.</li><li>def get_all_firing(): Return all alerts currently in “firing” state.</li><li>class AlertDispatcher: Kafka client that publishes alert events to the alerts topic.</li><li>def dispatch(alert: Alert): Serialize alert and publish to the Kafka alerts topic.</li><li>def get_receiver(alert: Alert): Resolve which receiver this alert should be routed to.</li></ul><h3>Conclusion</h3><p>In this post, we designed a metrics monitoring &amp; alerting system using the C4 model on IcePanel. We began with the core requirements and modelled the system top-down, starting with the Context layer, followed by Container, Component, and Code.</p><p>We covered several architectural decisions worth taking away from this design.</p><ul><li>Pull vs push model: We used Prometheus’s pull model to scrape targets rather than receiving pushed metrics. It keeps the collectors in control of what’s monitored without pushing unwanted data.</li><li>Consistent hash ring: We used a coordination component (etcd/zookeeper) to distribute scrape targets across a collector pool without duplication.</li><li>Data storage system: We covered the access patterns for a write-heavy system and used a TSDB optimised database like InfluxDB.</li><li>Rule evaluation vs routing: We defined the responsibility of evaluating rules against the TSDB and firing alerts (Prometheus Server). We designed the Alert Manager as a separate container that receives fired alerts and handles deduplication, routing, and dispatch to downstream systems.</li></ul><p>If you’d like to see more design deep dives, check out:</p><ul><li><a href="https://www.google.com/url?q=https://icepanel.io/blog/2026-01-28-design-chatgpt-with-icepanel&amp;sa=D&amp;source=editors&amp;ust=1772578132269751&amp;usg=AOvVaw3a2ItSpxlorbZ-SUcfZaLv">https://icepanel.io/blog/2026-01-28-design-chatgpt-with-icepanel</a></li><li><a href="https://www.google.com/url?q=https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel&amp;sa=D&amp;source=editors&amp;ust=1772578132270099&amp;usg=AOvVaw27YEuZDmfJOv48DjHDeWmY">https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel</a></li><li><a href="https://www.google.com/url?q=https://icepanel.io/blog/2025-11-18-design-youtube-using-icepanel&amp;sa=D&amp;source=editors&amp;ust=1772578132270363&amp;usg=AOvVaw3YNhg_Yn0QdeBZRBfP5s62">https://icepanel.io/blog/2025-11-18-design-youtube-using-icepanel</a></li><li><a href="https://www.google.com/url?q=https://icepanel.io/blog/2025-12-18-design-ebay-using-icepanel&amp;sa=D&amp;source=editors&amp;ust=1772578132270617&amp;usg=AOvVaw3C8W5WE7Ar2kuw7_JfBABf">https://icepanel.io/blog/2025-12-18-design-ebay-using-icepanel</a></li></ul><h3>📚 Resources</h3><ul><li><a href="https://www.google.com/url?q=https://prometheus.io/docs/introduction/overview/&amp;sa=D&amp;source=editors&amp;ust=1772578132270989&amp;usg=AOvVaw2QLB7b27B3idn5L8i7Ti82">https://prometheus.io/docs/introduction/overview/</a></li><li><a href="https://www.google.com/url?q=https://grafana.com/docs/grafana/latest/&amp;sa=D&amp;source=editors&amp;ust=1772578132271240&amp;usg=AOvVaw3GVwYurag2SjE4BJpWzEfg">https://grafana.com/docs/grafana/latest/</a></li><li><a href="https://www.google.com/url?q=https://prometheus.io/docs/alerting/latest/alertmanager/&amp;sa=D&amp;source=editors&amp;ust=1772578132271515&amp;usg=AOvVaw1L2minJycfZe9KkhnwZvlq">https://prometheus.io/docs/alerting/latest/alertmanager/</a></li><li><a href="https://www.google.com/url?q=https://www.influxdata.com/&amp;sa=D&amp;source=editors&amp;ust=1772578132271689&amp;usg=AOvVaw2Sk1zKmbPfs12yZb_WXwSg">https://www.influxdata.com/</a></li><li><a href="https://www.google.com/url?q=https://kafka.apache.org/42/getting-started/introduction/&amp;sa=D&amp;source=editors&amp;ust=1772578132271938&amp;usg=AOvVaw3eGVI6d9j4Ne6Jq1XJQbuK">https://kafka.apache.org/42/getting-started/introduction/</a></li><li><a href="https://www.google.com/url?q=https://flink.apache.org/&amp;sa=D&amp;source=editors&amp;ust=1772578132272115&amp;usg=AOvVaw1mhAYZEK-vEV1KZiB8ONRt">https://flink.apache.org/</a></li><li><a href="https://www.google.com/url?q=https://aws.amazon.com/cloudwatch/&amp;sa=D&amp;source=editors&amp;ust=1772578132272301&amp;usg=AOvVaw3wjRiGqr9lMFPHEtJYKgVA">https://aws.amazon.com/cloudwatch/</a></li><li><a href="https://www.google.com/url?q=https://aws.amazon.com/timestream/&amp;sa=D&amp;source=editors&amp;ust=1772578132272484&amp;usg=AOvVaw1uif51SKRk4WOSlpKPjECd">https://aws.amazon.com/timestream/</a></li><li><a href="https://www.google.com/url?q=https://www.pagerduty.com/&amp;sa=D&amp;source=editors&amp;ust=1772578132272647&amp;usg=AOvVaw0ymaSplNGKYuaQej1C9dsH">https://www.pagerduty.com/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=26767cae3959" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modelling Kubernetes Clusters using C4 Model]]></title>
            <link>https://icepanel.medium.com/modelling-kubernetes-clusters-using-c4-model-89f50d3de638?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/89f50d3de638</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Mon, 23 Feb 2026 19:32:06 GMT</pubDate>
            <atom:updated>2026-02-23T19:32:06.959Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rlrdFW7E1L6prVkAbldhpg.png" /></figure><p><a href="https://kubernetes.io/">Kubernetes (K8s)</a> is the de facto standard technology for orchestrating containerised applications at scale. However, visualising it only as a K8s cluster diagram doesn’t express its architecture in a format accessible to all stakeholders. In this post, we’ll talk about K8s, how to visualise it with the <a href="https://c4model.com/">C4 model</a> with an example app (ShopFlow), and some tips to get started.</p><h3>Introduction</h3><p>Thinking about architecture with the C4 model works great as a technology-independent abstraction. However, software architectures are often visualised as cloud-specific diagrams like AWS/Azure/GCP diagrams or as Kubernetes cluster views. These diagrams are often static and contain all implementation details at a single view. Details like networking, service meshes, and ingress/egress traffic get in the way when trying to understand the high-level components in the architecture, like core business services or datastores. For organisations running on K8s with little-to-no architectural documentation, there is a modelling problem.</p><h3>The modelling problem with Kubernetes (K8s)</h3><p><a href="https://kubernetes.io/">K8s</a> is the dominant open-source platform for orchestrating containerised applications, maintained by the <a href="https://www.cncf.io/">Cloud Native Computing Foundation (CNCF)</a>. It has become the most widely adopted technology for running distributed applications at scale.</p><p>K8s comes with its own abstractions and ecosystem, which is great for expressing infrastructure as code (IaC) but not for communicating the architecture as a whole. K8s has declarative resources for networking, scheduling, and service discovery. A <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/">Deployment</a> describes how your application runs. A <a href="https://kubernetes.io/docs/concepts/services-networking/service/">Service</a> gives it a stable network identity. An <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/">Ingress</a> handles external routing. A <a href="https://kubernetes.io/docs/concepts/configuration/configmap/">ConfigMap</a> externalises configuration. Other K8s resources can be found in the <a href="https://kubernetes.io/docs/concepts/">concepts page</a>.</p><p>Inside this ecosystem, deployment and networking details matter to the platform team, but not on an architecture diagram. For example, within an engineering organisation, there are generally three personas that interact with software architecture:</p><ol><li><strong>Platform Owner:</strong> Engineers working on the infrastructure layer that supports running services and workloads. These are typically platform engineers, site reliability engineers, and software architects.</li><li><strong>Service Owner:</strong> Engineers working on the product itself, owning parts or all of the deployable source code. These are software engineers, machine learning engineers, or product engineers.</li><li><strong>Product Owner:</strong> Non-technical stakeholders who own the product roadmap and focus on user-facing interactions and feature delivery. These are product managers or designers.</li></ol><p>A K8s cluster diagram works well for Platform Owners because they need to see namespaces, networking, and resource configurations. It’s sometimes useful for Service Owners, who care mainly about their own deployments and how they connect to other services. But it’s rarely useful for Product Owners, who need to understand what the system does without going through infrastructure detail.</p><p>The C4 model supports all three personas by offering different levels of detail. Level 1 (Context) gives Product Owners the big picture. Level 2 (Container) gives Platform and Service Owners a clear view of deployable units and their relationships. Level 3 (Component) lets Service Owners zoom into the internals of a specific service. Platform Owners can refer to K8s clusters for more networking details.</p><p>In general, K8s describes how architecture is deployed and operated while C4 models the logical architecture. They’re complementary views, not competing ones.</p><h3>Mapping Kubernetes to the C4 model</h3><p>So how does translating a Kubernetes cluster into the C4 model work?</p><h4>Cluster = Context diagram.</h4><p>For starters, the cluster becomes a single Context layer. In this view, the emphasis is on what the system does and who interacts with it (actors and external systems). At a high level, we draw the third-party APIs the cluster depends on and the users who interact with the system (e.g., admins and customers).</p><h4>K8s namespace is a dotted boundary, not a C4 diagram.</h4><p>A K8s <a href="https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/">namespace</a> is a logical grouping of resources within a cluster. It is a useful mechanism for isolating groups of resources together, but not modelled as a first-class element in the C4 model. For C4, it is a visual dotted-line boundary on the Container diagram. It could also be represented as a Group.</p><h4>Deployments = Container diagrams.</h4><p>A K8s <a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/">deployment</a> defines how an application runs and scales. It specifies the number of instances to run, resource limits, and other metadata. In the C4 model, the Container diagram highlights a set of deployable/runnable units that power the system. Each unit is a K8s deployment. <a href="https://kubernetes.io/docs/concepts/workloads/pods/">Pods</a> are runtime instances that wrap one or more running containers (not to be confused with Container diagrams!). They do not belong to the C4 model since this is already abstracted by the deployment resource. Code inside the pod belongs to the Component diagram, where you show internal structure like REST handlers, API clients, and domain logic.</p><h4>Services, Ingresses, and ConfigMaps become annotations or arrows.</h4><p>A K8s <a href="https://kubernetes.io/docs/concepts/services-networking/service/">service</a> is a networking mechanism that lets one workload talk to another. In C4, that’s just an arrow between two Containers with a protocol label. Other resources like Ingress rules, ConfigMaps, or Secrets are operational details that don’t need their own boxes on a Container diagram.</p><h3>ShopFlow: Kubernetes Cluster</h3><p>To see this mapping in practice, let’s take a look at an e-commerce app called <strong>ShopFlow</strong>. It is a simplified version of <a href="http://amazon.com">Amazon.com</a> where customers browse products, place orders, and pay online. The system runs on a single K8s cluster.</p><p>The cluster is organised into three namespaces:</p><ol><li><strong>main</strong> — the core business services. This is where the actual e-commerce logic lives: a Web App serving the customer-facing storefront, an API Gateway routing requests to backend services, a Product Catalog Service, an Order Service handling checkout flows, a Payment Service integrating with Stripe, and a Notification Service that sends order confirmations via email and SMS. Data is stored in PostgreSQL, and services communicate asynchronously through RabbitMQ.</li><li><strong>platform</strong> — the core infrastructure. For example, <a href="https://nginx.org/">NGINX</a> for traffic routing and <a href="https://istio.io/">Istio</a> for managing the service mesh. These are workloads owned by the platform team, not the software teams.</li><li><strong>monitoring</strong> — the observability stack. <a href="https://prometheus.io/">Prometheus</a> and <a href="https://grafana.com/">Grafana</a> for metrics and dashboards, <a href="https://www.fluentd.org/">Fluentd</a> shipping logs to <a href="https://grafana.com/oss/loki/">Loki</a>.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*baPfXRGn059edAhsj-Cppw.png" /></figure><p>Given this K8s cluster, how should this be modelled using C4 diagrams? For this scope, we’ll only focus on the <strong>main</strong> namespace.</p><h3>ShopFlow: C4 Model</h3><p>See complete design on IcePanel: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/QXrC">https://s.icepanel.io/DWnaysJ3cbCQqg/QXrC</a></p><h4>Level 1: Context diagram</h4><p>The Context (system) diagram is for stakeholders who need to understand what the system does and what it depends on. Think product managers, business stakeholders, and new engineers getting onboarded. In this example, we have two external systems that ShopFlow depends on: a payment provider and a notifications provider. There are two main actors: customers and admins.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wCXeKjla2Kkp-shIPP10iw.png" /></figure><h4>Level 2: Container diagram</h4><p>We zoom inside ShopFlow to show its separately deployable units, Containers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BXPYTA59-QJ3aXzksX92Uw.png" /></figure><p>In this Container view, every service is deployed as a K8s Deployment (except datastores and gateways, which can be deployed as managed cloud services like AWS). We have:</p><ol><li><strong>ShopFlow WebApp: </strong>for showing product information and order history in the UI.</li><li><strong>API Gateway:</strong> for routing requests to backend.</li><li><strong>Product Catalog:</strong> for viewing available products and details.</li><li><strong>Order Service: </strong>for managing incoming orders.</li><li><strong>Payment Service:</strong> for managing payment flows.</li><li><strong>Notification Service:</strong> for sending events to customers.</li><li><strong>Message Queue:</strong> for inter-service communication.</li><li><strong>PostgreSQL:</strong> for persisting product data and order history.</li></ol><p>These deployable units are abstracted within the Container diagram without additional details specific to K8s. Networking details are kept minimal here to reduce cognitive load on viewing these diagrams. In general, every K8s deployment should be represented as a Component inside the Container view.</p><h4>Level 3: Component diagram</h4><p>Below is the Component diagram of the “Order Service”. It contains the following modules:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GJA5s3IWZ6eUuRAx9NWEZg.png" /></figure><ol><li>The <strong>Order Controller</strong> handles incoming HTTP requests. It receives requests from the API Gateway and delegates to the appropriate internal component.</li><li>The <strong>Order Core</strong> validates orders, applies business rules, and coordinates the checkout flow.</li><li>The <strong>Order Repository</strong> handles data persistence to PostgreSQL. It encapsulates data access patterns so the domain logic doesn’t know or care about SQL.</li><li>The <strong>Event Publisher</strong> publishes domain events (e.g., OrderPlaced, OrderCancelled) to RabbitMQ. The Notification Service consumes these events downstream.</li><li>The <strong>Payment Client</strong> calls the Payment Service to charge the customer.</li></ol><p>Notice that at Level 3, we’re no longer thinking about K8s. This diagram describes the internal structure of a single deployable unit. You’d draw the same Component diagram whether the Order Service runs on Kubernetes, AWS ECS, or your laptop. That’s what makes C4’s abstraction consistent.</p><p>We won’t cover the fourth diagram (Code) in this example, but you get the idea.</p><h3>Tips for modelling K8s clusters</h3><p>To get started, here are three tips for modelling K8s clusters with C4.</p><h4>1. Focus on the high-level design</h4><p>Avoid going into the networking details in the K8s world. For example, don’t describe which resources can talk to each other with <a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/">network policies</a> (similar to AWS’ security groups) or how Istio proxies work. Instead, focus on the Deployments and Services in K8s to map out the user flow.</p><h4>2. Focus on the resources that enable user flow</h4><p>If you trace a user flow from start to finish, which workloads does it touch? This is the Container view. Everything else is supporting infrastructure that can be mentioned in annotations or separate documentation, not in the C4 model.</p><h4>3. Use namespaces as visual groups, not architectural boundaries.</h4><p>Namespace is a K8s organisational tool. Some teams use namespaces per-team, others per-environment, others per-domain. Use the namespace structure on your C4 diagrams if it helps readers, but don’t let it dictate your architecture.</p><p>Here’s also a quick guide for mapping K8s to C4:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*94fTfMo0qM8-1TIAs-Y9PQ.png" /></figure><h3>Conclusion</h3><p>Working with the C4 model should not reduce the value of K8s diagrams. One communicates the architecture at different layers, the other describes how the architecture is deployed.</p><p>C4 works great for team collaboration as a technology-agnostic framework for visualising systems. K8s is great for showing implementation details, not a high-level overview.</p><h3>📚 Resources</h3><ul><li><a href="https://kubernetes.io/">https://kubernetes.io/</a></li><li><a href="https://www.cncf.io/">https://www.cncf.io/</a></li><li><a href="https://s.icepanel.io/DWnaysJ3cbCQqg/QXrC">https://s.icepanel.io/DWnaysJ3cbCQqg/QXrC</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=89f50d3de638" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Design ChatGPT using IcePanel]]></title>
            <link>https://icepanel.medium.com/design-chatgpt-using-icepanel-7e1fdbd11220?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/7e1fdbd11220</guid>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Wed, 28 Jan 2026 19:54:14 GMT</pubDate>
            <atom:updated>2026-01-28T19:54:14.229Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lyw-1z9MXmMRmLq---OMKQ.png" /></figure><h3>📝 Introduction</h3><p>In this post, we’ll design <strong>ChatGPT</strong>, an AI-powered conversational system that allows users to interact with large language models (LLMs) through natural language. We’ll approach this as software architects and create four hierarchical diagrams: Context, Container, Component, and Code (not familiar with these? Read <a href="https://icepanel.io/blog/2024-07-18-what-is-the-c4-model">this</a>).</p><p>Each diagram will be annotated to explain the key building blocks and responsibilities, and we’ll highlight how users interact with the system by visualising data flow using <a href="https://docs.icepanel.io/visual-storytelling/flows">IcePanel Flows</a>.</p><p>We’ll start by defining the scope of the system through its functional requirements (what the system does) and non-functional requirements (the qualities it should have). From there, we’ll progressively go through each layer of the C4 model to build the overall architecture.</p><p>You can view the final architecture at this link: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/sOie">https://s.icepanel.io/DWnaysJ3cbCQqg/sOie</a></p><h3>🔎 Scope</h3><p>ChatGPT’s core functionality consists of two requirements:</p><ol><li>Users should be able to send prompts and receive streaming responses from LLMs.</li><li>Users should be able to save, load, and search through previous chat histories.</li></ol><p>For non-functional requirements, the system should be:</p><ul><li>Availability &gt;&gt; consistency, expected ~10 million daily active users (DAU).</li><li>Highly scalable. Chat users might peak at 10k-20k/sec calls to the model.</li><li>Low latency, users should expect first tokens in ~500 ms and complete responses in ~3 seconds.</li><li>Rate limiting. Users are allowed to send at most 60 requests/min.</li></ul><p>Let’s start with the first diagram, Context.</p><h3>Level 1 — Context</h3><p>The Context layer defines the actors and external systems ChatGPT depends on. We have one actor and one external system:</p><ol><li><strong>User:</strong> End user who chats to ChatGPT through mobile or web.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8ycGRUeTGjDPz4G-V6cJtg.png" /></figure><ol><li><strong>Identity Provider (Auth0):</strong> Provides federated authentication and single sign-on (SSO) capabilities, allowing users to authenticate using their existing social media or enterprise accounts. Our system receives verified identity tokens and uses them to create or authenticate user sessions without handling passwords directly.</li><li>Other external systems can be integrated (e.g., Payment Provider like Stripe, but we’ll leave it outside of scope). The more detailed design comes next, the Container diagram.</li></ol><h3>Level 2 — Container</h3><p>The Container layer models independently deployable applications, services, and data stores. In this scope, we’ll design ChatGPT using a microservices architecture to independently scale certain workloads and provide high availability and performance (as defined in non-functional requirements).</p><p>Our system is composed of the following Containers:</p><ol><li><strong>Completion Service (EC2): </strong>The core service responsible for taking a conversation history (a list of messages) as input and generating a context-aware AI response.</li><li><strong>Worker Pool (ECS — Autoscaling):</strong> Pool of inference workers that execute LLM requests through the model proxy based on model type, and stream generated tokens back to the Completion service in real time.</li><li><strong>Model Proxy (EC2): </strong>An intelligent router for multi-model API endpoints.</li><li><strong>Model API (EC2 GPU-optimised):</strong> EC2 machines pre-loaded with LLM weights (e.g., GPT-4, GPT-3.5, or other LLMs) and streams generated tokens back to caller.</li><li><strong>Conversation Service (EC2): </strong>A microservice for managing conversation state and retrieving and searching in chat histories.</li></ol><p>In this architecture, we use the following technologies:</p><ol><li><strong>AWS API Gateway</strong>: A secure entry point for all API requests coming from the frontend. Responsible for routing incoming requests and managing HTTP streaming (SSE) for real-time response delivery.</li><li><strong>Rate Limiter (Redis)</strong>: A fast in-memory cache for tracking per-user rate limits.</li><li><strong>Elasticsearch Cluster</strong>: A search engine for full-text search and retrieval of documents (chat history in this example).</li><li><strong>DynamoDB</strong>: A NoSQL document store for persisting chat histories and metadata.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jE_yo_KMO5b8Znn2BXNR9Q.png" /></figure><p>On a high level, the system works as follows.</p><p>The user connects to ChatGPT through the web (<a href="http://chatgpt.com">chatgpt.com</a>) or mobile. They send a prompt to start a new chat with the backend server. Their requests translate to a POST request (/completions/create) with the user’s prompt, selected model, and other metadata in the payload. The backend server receives this request and routes it to the appropriate model infrastructure (GPU servers), which processes the prompt and streams the generated response back to the user. This response flows through the same path in reverse, from the model servers back through the backend API, which formats and delivers the text incrementally to the UI using Server-Sent Events (<a href="https://en.wikipedia.org/wiki/Server-sent_events">SSE</a>), allowing the user to see the LLM’s response appear in real-time as it’s being generated. The user prompt can be modelled in a body request like below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/823/1*4QOlHosMPgdMOS6UY9ps9A.png" /></figure><p>For more examples, check out OpenAI’s API reference: <a href="https://platform.openai.com/docs/api-reference/responses/create">https://platform.openai.com/docs/api-reference/responses/create</a></p><p>We’ve designed two primary data flows using IcePanel. Check out these flows and play them step by step to see how our system works.</p><p><strong>Flow 1:</strong> Send a prompt to ChatGPT</p><p>Complete flow: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/vPHL">https://s.icepanel.io/DWnaysJ3cbCQqg/vPHL</a></p><p>On a high level,</p><ol><li>User sends prompt via an HTTP POST</li><li>API Gateway validates rate limits</li><li>Completion Service acquires a worker and starts inference</li><li>Tokens stream back to the user via SSE</li><li>Response is persisted to DynamoDB</li></ol><p><strong>Flow 2: </strong>Find older chat and send a new prompt</p><p>Complete flow: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/0Oj7">https://s.icepanel.io/DWnaysJ3cbCQqg/0Oj7</a></p><p>On a high level,</p><ol><li>User sends search keywords to find a previous chat.</li><li>Conversation Service queries Elasticsearch for full-text search.</li><li>Chat history is fetched and displayed to the user.</li><li>User sends a new prompt with full conversation context.</li><li>(Flow 1) repeats.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DFyN6w3C1DHqPoGGEqWEEg.png" /></figure><h4>HTTP Streaming and Server-Sent Events (SSE)</h4><p>When a client sends an HTTP POST request to the Completion API endpoint, the server keeps the response open and streams partial results as they are produced. This is implemented using <a href="https://www.google.com/url?q=https://en.wikipedia.org/wiki/Server-sent_events&amp;sa=D&amp;source=editors&amp;ust=1769633267211135&amp;usg=AOvVaw21FYyXYrbhAsY8f_TeSRyX">Server-Sent Events</a> on top of HTTP, which uses a special header (<strong>Transfer-Encoding: chunked</strong>) that tells the client the data will be streamed into a set of chunks. As tokens are generated by the model, they flow immediately through the system (Model API → Worker → Completion Service → Client) and are flushed to the HTTP response stream. This enables low time-to-first-token (hundreds of milliseconds) and significantly improves latency, as users can start reading the response while the model is still generating it. This is how systems like ChatGPT provide a real-time chatting experience to the user (<a href="https://www.google.com/url?q=https://platform.openai.com/docs/api-reference/chat-streaming&amp;sa=D&amp;source=editors&amp;ust=1769633267216136&amp;usg=AOvVaw2-KvsbMh0KZFFE0kFkgOMS">docs</a>).</p><p><strong>Quick note:</strong> Some system design readers might suggest using <a href="https://www.google.com/url?q=https://en.wikipedia.org/wiki/WebSocket&amp;sa=D&amp;source=editors&amp;ust=1769633267216681&amp;usg=AOvVaw0AeO3apTRcw2KciObmoRg-">WebSockets</a> (WS) instead of SSE when designing ChatGPT, since WS is a bidirectional protocol commonly used in chat systems like WhatsApp. However, WS introduces significant complexity that requires specialised infrastructure to route and maintain millions of concurrent live user connections. For the scope of this design, that complexity isn’t necessary. One-directional HTTP streaming from the backend is good enough to solve this problem.</p><h3>Level 3 — Component</h3><p>In the C4 model, a component is a grouping of related modules encapsulated behind a well-defined interface. Let’s look at the Components in ChatGPT.</p><h3>1. Completion Service</h3><p>This service orchestrates the complete LLM inference lifecycle. When a user sends a chat completion request, the Completion API first validates rate limits via the Redis Client. Once approved, the Worker Pool API acquires an available worker from the pool based on the requested model type (GPT-4, GPT-3.5, etc.). These tokens are immediately streamed back through the API Gateway to the user, creating the real-time chat experience.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*30i5gGo_UEVkpuheQX4NdQ.png" /></figure><h3>2. Model Proxy Service</h3><p>The Model Proxy acts as an intelligent routing layer between workers and Model APIs. The Model Router selects the optimal API endpoint by consulting the Health Checker for endpoint status and the Metrics Collector for latency data. It calculates a routing score combining health, latency, and current load to choose the best endpoint. All requests pass through the Circuit Breaker, which monitors failure rates and prevents cascade failures by temporarily blocking requests to unhealthy endpoints. This architecture ensures requests are always routed to the fastest, most reliable Model API instances across multiple regions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0nQZIdKccwpFUOExRRA7OQ.png" /></figure><h3>3. Conversation Service</h3><p>The Conversation Service manages chat history retrieval and search. When a user requests their conversation history, the Conversation API first queries the Elasticsearch Client for fast full-text search across all messages. For direct conversation retrieval, the History Repository fetches data from DynamoDB, which serves as the source of truth. New messages are persisted to DynamoDB and asynchronously synced to Elasticsearch via <a href="https://www.google.com/url?q=https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html&amp;sa=D&amp;source=editors&amp;ust=1769633267222982&amp;usg=AOvVaw2_rTT0YJsNjkrGGx5RXAOL">DynamoDB Streams</a> for eventual consistency (which is acceptable in this case).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HbddrdeFzL73Ubv6NPXAYQ.png" /></figure><p>Let’s go one level deeper with the source code in the Code layer.</p><h3>Level 4 — Code</h3><p>This is where we can view implementation details at the code level. At this level, we focus on code structure rather than diagrams. We’ll briefly go over two Components: <strong>Completion </strong>and<strong> Conversation</strong>.</p><h3>Code Classes in Completion Service</h3><p>This component orchestrates LLM inference requests by managing the complete lifecycle from rate limit validation to streaming response delivery. The Completion API provides RESTful endpoints for initiating chat completions. The RedisClient validates user rate limits by checking global user quotas (60 requests per minute) stored in Redis before allowing requests to proceed. The WorkerPoolAPI manages the pool of available workers, handles load balancing, and acquires connections for inference requests.</p><p><strong>Completion API</strong></p><p>RESTful endpoints for chat completion requests</p><ul><li>POST /v1/chat/completions — Initiate a new chat completion</li><li>POST /v1/chat/completions/:requestId/cancel — Cancel an ongoing completion request</li></ul><p><strong>Redis Client</strong></p><p>Manages per-user rate limiting and validation</p><ul><li><strong>isAllowed(userId)</strong> — Validates if user is within QPS and concurrent generation limits</li><li><strong>updateUsage(userId, tokenCount)</strong> — Records user request and token usage</li></ul><p><strong>Worker Pool API</strong></p><p>Manages worker pool and connection lifecycle</p><ul><li><strong>acquire(modelType, priority): Worker</strong> — Acquires available worker from pool based on model requirements</li><li><strong>release(workerId)</strong> — Returns worker to available pool after request completion</li></ul><h3>Code Classes in Conversation Service</h3><p>This component manages conversation state and retrieves chat history for LLM context. The Conversation API class exposes RESTful endpoints for fetching user conversations and chat history. The API first queries Elasticsearch for fast full-text search across conversation histories before falling back to the History Repository for direct database access. The Elasticsearch client handles all interactions with the Elasticsearch cluster, providing efficient search capabilities. The History Repository serves as the data layer for fetching conversation messages and metadata from the History Database (DynamoDB).</p><p>These classes have roughly the following methods:</p><p><strong>Conversation API</strong></p><p>RESTful endpoints for conversation and chat history management</p><ul><li>GET /v1/conversations/:conversationId — Retrieve conversation details and complete message history.</li><li>GET /v1/conversations/:conversationId/messages?limit&amp;cursor — Retrieve paginated messages for a conversation.</li><li>POST /v1/conversations/search — Search for specific keywords in past conversations</li></ul><p><strong>Elasticsearch Client</strong></p><p>Manages Elasticsearch interactions for fast conversation search</p><ul><li><strong>search(userId, query, filters)</strong> — Full-text search across all user conversations</li><li><strong>getMessages(conversationId, limit, cursor)</strong> — Retrieves messages from Elasticsearch index</li></ul><p><strong>History Repository</strong></p><p>Data access layer for DynamoDB conversation storage</p><ul><li><strong>getConversation(id)</strong> — Fetches chat history given conversationId</li><li><strong>appendMessage(conversationId, role, content, tokens)</strong> — Saves message given conversationId</li></ul><h3>Conclusion</h3><p>In this post, we designed an AI chat system like ChatGPT using the C4 model on IcePanel. We began with the core requirements and modeled the system from the top down, starting with the Context layer, followed by the Container, Component, and finally the Code layer.</p><p>If you’d like to see more design deep dives, check out:</p><ul><li><a href="https://www.google.com/url?q=https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel&amp;sa=D&amp;source=editors&amp;ust=1769633267235758&amp;usg=AOvVaw0cdhwWf2IMaXfEp6ywrZa3">https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel</a></li><li><a href="https://www.google.com/url?q=https://icepanel.io/blog/2025-11-18-design-youtube-using-icepanel&amp;sa=D&amp;source=editors&amp;ust=1769633267236182&amp;usg=AOvVaw1W6TTf9GaG1dcfEALrTgND">https://icepanel.io/blog/2025-11-18-design-youtube-using-icepanel</a></li><li><a href="https://www.google.com/url?q=https://icepanel.io/blog/2025-12-18-design-ebay-using-icepanel&amp;sa=D&amp;source=editors&amp;ust=1769633267236576&amp;usg=AOvVaw0rkxLzEip54sofrE73ouJr">https://icepanel.io/blog/2025-12-18-design-ebay-using-icepanel</a></li></ul><p>Let us know which system you’d like to see modeled next on IcePanel!</p><h3>📚 Resources</h3><ul><li><a href="https://www.google.com/url?q=https://aws.amazon.com/api-gateway/&amp;sa=D&amp;source=editors&amp;ust=1769633267237286&amp;usg=AOvVaw3Z8-E3iz0wz9P8wmgqjGll">https://aws.amazon.com/api-gateway</a></li><li><a href="https://www.google.com/url?q=https://aws.amazon.com/dynamodb&amp;sa=D&amp;source=editors&amp;ust=1769633267237569&amp;usg=AOvVaw0La39U94BIh0Pckql0CO9t">https://aws.amazon.com/dynamodb</a></li><li><a href="https://www.google.com/url?q=https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html&amp;sa=D&amp;source=editors&amp;ust=1769633267238010&amp;usg=AOvVaw2o5H2dRQ5yXFp_cDIY4hqU">https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html</a></li><li><a href="https://www.google.com/url?q=https://platform.openai.com/docs/api-reference/chat-streaming&amp;sa=D&amp;source=editors&amp;ust=1769633267238426&amp;usg=AOvVaw1BaUbMDe4U0mwwc-_RtUJK">https://platform.openai.com/docs/api-reference/chat-streaming</a></li><li><a href="https://www.google.com/url?q=https://platform.openai.com/docs/models&amp;sa=D&amp;source=editors&amp;ust=1769633267238729&amp;usg=AOvVaw0zvZYIwHWmYwqt490KAVJG">https://platform.openai.com/docs/models</a></li><li><a href="https://www.google.com/url?q=https://redis.io/open-source/&amp;sa=D&amp;source=editors&amp;ust=1769633267238982&amp;usg=AOvVaw1gsTgQATg1P1d_fsjUMyfz">https://redis.io/open-source</a></li><li><a href="https://www.google.com/url?q=https://aws.amazon.com/microservices&amp;sa=D&amp;source=editors&amp;ust=1769633267239268&amp;usg=AOvVaw2fW7WTw1mZq3f50_-AujHB">https://aws.amazon.com/microservices</a></li><li><a href="https://www.google.com/url?q=https://aws.amazon.com/what-is/elasticsearch/&amp;sa=D&amp;source=editors&amp;ust=1769633267239596&amp;usg=AOvVaw0YHgHyStWWc2GvHVh7LlE5">https://aws.amazon.com/what-is/elasticsearch</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7e1fdbd11220" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[State of Software Architecture Report — 2025]]></title>
            <link>https://icepanel.medium.com/state-of-software-architecture-report-2025-12178cbc5f93?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/12178cbc5f93</guid>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Wed, 21 Jan 2026 19:50:55 GMT</pubDate>
            <atom:updated>2026-01-21T19:50:55.587Z</atom:updated>
            <content:encoded><![CDATA[<h3>State of Software Architecture Report — 2025</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*szLXx6dpzzB594YjgnlkEA.png" /></figure><h3>🤔 Why did we do this?</h3><p>Every year, we ask the community to share their thoughts and opinions shaping software architecture. Check out the 2024 results <a href="https://icepanel.io/blog/2024-11-26-state-of-software-architecture-2024">here</a>. Looking back, 2025 was a year of rapid change and continued AI adoption. Interest in AI continued to diffuse, extending into more industries and more complex workflows. How do architects feel about all of this? How has it impacted their day-to-day? We were curious to find out.</p><p>We’re excited to share the results from our 2025 survey. Let’s dive in!</p><h3>🔑 Key highlights</h3><p>Read this section if you want the TL;DR, or scroll down and look for a detailed breakdown of each section.</p><ul><li>75 people responded, with 57% being architects and 29% engineers/developers.</li><li>Most respondents were experienced professionals, with 95% being full-time employees. 68% had 6+ years of experience.</li><li>Keeping documentation up to date was overwhelmingly the biggest challenge, followed by a lack of standards and finding the right level of detail.</li><li>Diagramming tools (87%) and collaborative wikis (79%) were the most popular tools for software architecture. 44% now use AI/LLMs for documentation.</li><li>Source of truth shifted remained in collaborative wikis (42%) and dedicated tools (24%).</li><li>More than 70% were at least moderately confident using the C4 model. Context diagrams (81%) and Container diagrams (79%) were most commonly used.</li><li>AI usage is mostly experimental: 37% use it in some workflows, 33% are exploring, 19% haven’t started yet. Main uses include diagram generation, docs creation, and design validation.</li><li>Architects see their role evolving to be more strategic and quality-focused, with AI augmenting rather than replacing their work.</li></ul><h3>👥 Who answered?</h3><ul><li>There were a total of 75 responses.</li><li>More than half (57%) of the respondents were architects, with solution architects being the most common at 29%. Engineers/developers were the second largest group at 29%.</li><li>The majority of respondents were experienced full-time employees (95%), with 6–10 years (29%) and more than 10 years of experience (39%). More tenured respondents responded this year (6+ years of experience).*</li><li>There was a wide range of company sizes, with 100–499 (26%) and 5,000 or more (21%) being the most common.</li><li>Despite the wide range of company sizes, most had a small team of dedicated architects. The most common team size was 1–9 architects, at 51%.</li><li>Difference not statistically significant based on chi-square test.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aqsd9SbcAy_fxnDmp3vhZQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qyqY8ZCKZTK0H7yBy8UnuA.png" /></figure><h3>🤬 Biggest challenge related to architecture</h3><ul><li><strong>Keeping documentation up to date:</strong> Overwhelmingly, the most common challenge mentioned. People struggle with architectural drift, maintaining the current state in an agile process, and often end up with out-of-date docs that people lose trust in.</li><li><strong>Lack of standards and consistency:</strong> No agreed-upon standard or conventions established. Teams have different interpretations of the C4 model, conflicting views of the system in the org, and scattered tooling with no central source of truth.</li><li><strong>Finding the right level of detail:</strong> Dealing with the tension of too much detail and too little. Understanding “how to deep go” when diagramming so it’s valuable, and communicating to different audiences (developers to C-suite).</li><li><strong>Time and resource constraints:</strong> Lack of time or the inability to prioritize documentation work. Docs are often seen as a burden rather than a value-add. Justifying the quality of docs vs the speed of delivery.</li></ul><h3>⚒️ Tooling and practices</h3><p>This section focuses on specific tooling and practices for creating and maintaining software architecture documentation.</p><ul><li>The majority of respondents used Diagramming tools (87%), followed by collaborative wiki tools (79%), to document software architecture.</li><li>65% mentioned using a modelling tool, almost identical to 2024 at 64%.</li><li>44% used AI/LLMs and diagrams-as-code. These were new options this year.</li><li>Physical whiteboarding was still going strong at 40%.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c8geJynMMdGmpccyoGdWpA.png" /></figure><p>Source of truth of architecture continued to converge in 2 places:</p><ul><li>42% said it was on a collaborative wiki tool, while 24% said they used a dedicated tool.</li><li>This is a reverse of 2024, where collaborative wiki (29%) was above a dedicated tool (37%).*</li><li>19% had no single source of truth, and 11% tracked it with code or informally. Both were up from 2024.*</li></ul><p>* Both differences were not statistically significant.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FonOyaxa38102Kw5WUBgaw.png" /></figure><ul><li>There was no pattern for how often people updated their architecture documents. It was a close split between monthly (26%), annually (23%), quarterly (23%), and weekly (23%).</li><li>It was a close, even split on using architecture decision records (ADRs). 48% said they use ADRs, and 52% don’t.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xbqO_O5TsSRdSUEABU57Lg.png" /></figure><p>The most common architecture patterns used were microservices (60%) and event-driven (55%). Both of these are down from 2024; however, the differences were not statistically significant.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*491ujD-rvzgNkyT_k0PZJw.png" /></figure><h3>4️⃣ C4 model</h3><p>This section focuses on the adoption of the C4 model and its challenges.</p><ul><li>Most people were moderately (29%) or very confident (41%) in using the C4 model.</li><li>There was a slight increase in overall confidence from 2024, but the difference was not statistically significant.</li><li>We asked respondents who were not confident or only slightly confident to explain in more detail why. Some example responses were: &quot;Lack of interest in adopting it,&quot; or &quot;haven’t spent time learning it yet.&quot;</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pIvG51Y9_zG8mS7ifQr8Dg.png" /></figure><ul><li>Context diagrams were the most commonly used diagram type in the C4 model at 81%, followed by Container/app (79%), and Component diagrams (41%).</li><li>Context increased, while container and component decreased from 2024. The increase in context diagram usage was statistically significant (p=0.05/7).</li><li>Among supplementary C4 diagrams, most people used dynamic diagrams/IcePanel Flows (28%) or system landscape diagrams (27%).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UEtYnON82CSso-jCQUwZvA.png" /></figure><h3>🔮 AI/LLMs and the future of software architects</h3><p>The final section focuses on how AI/LLMs are used and how they impact software architects. These were mostly open-ended questions.</p><p>Adoption of AI/LLMs continues to be a work in progress. Most teams are still experimenting:</p><ul><li>37% said it’s used in some aspects of their workflow/tooling.</li><li>33% have dabbled in it, but it’s been mostly exploratory.</li><li>19% have yet to explore it.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QundbyOb9sZGD0XJ8OgwQg.png" /></figure><p>In general, people are still in the experimental and early stages of using AI. Many have yet to use it at all and are cautious about fully trusting its output. With that said, a general theme we saw was using AI/LLMs as assistants for brainstorming and gut-checks.</p><h3>⭐ Top ways people are using AI/LLMs</h3><ul><li><strong>Diagram generation:</strong> Generating Mermaid diagrams, going from code to diagrams (reverse engineering), automating diagram updates with code changes, and creating a DSL for diagramming tools.</li><li><strong>Creating and summarizing docs:</strong> Creating ADRs, translating text for different audiences (technical to business), and summarizing architectures.</li><li><strong>Design validation:</strong> Using AI as a thinking partner. “Rubber ducking” designs, sanity checking decisions or asking for a second opinion, exploring potential designs and tradeoffs, evaluating architecture decisions.</li><li><strong>Research and ideation:</strong> Brainstorming new ideas and changes, researching different patterns and concepts, asking for suggestions on what could be improved. People using it as a ‘consultancy’.</li></ul><p>People see the role of architects evolving into something more strategic and quality-focused, shifting from a creator to a coach/facilitator. In general, people see AI as an augmentation, rather than a replacement, helping them be more efficient by removing a lot of mundane tasks, such as maintaining docs. AI will help architects focus on designing resilient, scalable systems that align with business objectives, rather than lower-level technical decisions.</p><h3>🧊 That’s a wrap!</h3><p>Another survey in books. Thanks so much to everyone who participated! If you’ve got any thoughts on the results or ideas for what we should focus on next time, let us know — <a href="mailto:mail@icepanel.io">mail@icepanel.io</a>. We’d love to hear from you!</p><p>Stay Chill 🤙</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=12178cbc5f93" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why engineers should use architecture diagrams]]></title>
            <link>https://icepanel.medium.com/why-engineers-should-use-architecture-diagrams-c3ff75ab5a66?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/c3ff75ab5a66</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Mon, 12 Jan 2026 16:23:05 GMT</pubDate>
            <atom:updated>2026-01-12T16:23:05.612Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n4aC-LUA1XdadJGT4delmA.png" /></figure><h3>Introduction</h3><p>Quality and speed of shipping projects are two core metrics for evaluating performance of engineering teams. Projects typically go through multiple phases like research, requirements gathering, solution design, and implementation, each of which depends on a clear understanding of teams’ software architecture. Engineers who use architecture diagrams can accelerate most of these phases (if not all) when applied effectively.</p><p>Regardless of the diagram choice, <a href="https://c4model.com/">C4 Model</a>, UML diagrams (<a href="https://en.wikipedia.org/wiki/Sequence_diagram">Sequence</a>, <a href="https://en.wikipedia.org/wiki/Activity_diagram#:~:text=Activity%20diagrams%20are%20graphical%20representations,choice%2C%20iteration%2C%20and%20concurrency.">Activity</a>), or cloud-specific like AWS diagrams, the goal is the same: to build shared architectural knowledge and avoid accidental complexity. This makes collaboration easier for teams when they start referencing these diagrams during whiteboarding sessions, design reviews, and documentation.</p><p>Here are four reasons engineers should use architecture diagrams:</p><ol><li>Establish a common baseline for discussing systems</li><li>Reduce review time and cognitive load</li><li>Enable asynchronous communication</li><li>Build a documentation-first culture</li></ol><p>Let’s go through each one.</p><h3>1. Common baseline for discussing systems</h3><p>Engineers are frequently asked to weigh in on product ideas and feature proposals from upstream management. Some proposals are application-specific, requiring developers to scope and implement solutions programmatically, while others are more infrastructure-specific, requiring architects to consider the knock-on effects of the architectural changes.</p><p>Architecture diagrams serve as living documentation of their systems. When kept up to date, engineers can discuss new ideas with their trade-offs and make key decisions to confidently go from design to implementation. On the flip side, introducing changes without sufficient context can create a functional risk (i.e., break systems) and/or data vulnerabilities. For example:</p><ol><li>Deploying a message queue (SQS) in a public subnet with disabled encryption (data risk)</li><li>Adding a cache in front of a service (inconsistent data risk)</li><li>Deprecating a microservice with downstream dependencies (potential cascade failures)</li></ol><p>All of which can be avoided if all engineers share the same knowledge baseline for discussing systems.</p><p>Generally speaking, architectural diagrams typically capture three elements: (1) data flow, (2) data storage, and (3) data processing. These elements help reviewers understand how a proposed change fits into the system and its potential downstream impact. For example, when introducing a new microservice, reviewers might ask:</p><ul><li>Data flow: What are its fan-in and fan-out dependencies?</li><li>Storage: Is the service stateless or stateful, and where is its data stored?</li><li>Processing: What does the service produce, and how is its data modeled?</li></ul><p>Sharing a common understanding of how and why the architecture is designed makes collaboration as an engineer much easier.</p><h3>2. Reduce review time and cognitive load</h3><p>This can be helpful in code reviews. Referencing diagrams in a pull request (PRs) shows that the author has considered the architectural implications of their changes. This provides reviewers with context to:</p><ol><li>Explain the expected behaviour when the change is deployed (e.g., extra SQL queries to the core database, potentially added latency to the service).</li><li>Ensure the author has thought about higher-level system interactions (e.g., number of connections to the core database).</li></ol><p>Reviewers can then evaluate changes without mentally reconstructing the entire system. This reduces back-and-forth questions in PRs like “How does this affect X?” or “Have you thought about Y?”.</p><p>Architecture diagrams are particularly important for platform teams managing infrastructure-as-code (<a href="https://learn.microsoft.com/en-us/devops/deliver/what-is-infrastructure-as-code">IaaC</a>) repos. Diagrams are critical in these scenarios because code/configuration changes often alter the current architecture, using tools like <a href="https://developer.hashicorp.com/terraform">Terraform</a> or <a href="https://docs.aws.amazon.com/cloudformation/">CloudFormation</a>. For example:</p><ol><li>Deploying a new application within a private subnet.</li><li>Provisioning a new Kafka with new consumers.</li><li>Configuring apps to call a new third-party API.</li></ol><p>These examples highlight the importance of (A) a shared architectural baseline among engineers, reducing the need for repeated explanations (especially in PRs), and (B) minimising cognitive load by referencing diagrams instead of re-drawing parts of the architecture.</p><h3>3. Encourage asynchronous communication</h3><p>One common mistake in team collaboration is relying on a single engineer who holds architectural knowledge, repeatedly asking them questions via Slack or 1:1 meetings. This synchronous communication creates a knowledge bottleneck and a single point of failure, especially when that engineer is on PTO or leaves the company.</p><p>A better approach is documenting infrastructure knowledge in <a href="https://github.com/joelparkerhenderson/architecture-decision-record">ADRs</a> (Architecture Decision Records) and architecture diagrams. Engineers can revisit these documents at any time, leave comments or ask questions asynchronously, and not be blocked by a single person. This empowers teams to make design decisions independently and reduces dependency on individual engineers.</p><h3>4. Documentation-first culture</h3><p>Encouraging engineers to create and maintain architectural diagrams fosters a documentation-first culture. It makes it easier to search for answers, and, in some setups, allows engineers to query systems that support MCP servers (for example, check out <a href="https://icepanel.io/blog/2025-05-15-new-mcp-server">IcePanel MCP</a>). A documentation-first culture begins with writing product requirements, ADRs, engineering proposals, and diagramming systems. This approach is similar to <a href="https://www.larksuite.com/en_us/blog/amazon-6-pager">Amazon’s 6-pager</a> culture, where new ideas or projects are discussed in short, structured documents. If a proposal isn’t documented, it doesn’t enter discussion. Architecture diagrams serve as valuable references in these 1-pagers and 6-pagers, reducing back-and-forth clarification about the current system and keeping discussions focused on the post-delivery.</p><p>Here’s a summary below of Amazon’s writing culture.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qCjaQUtr6xuuoVobn2gwqA.png" /></figure><h3>Conclusion</h3><p>Shipping engineering projects requires a clear understanding of a team’s software architecture. Documenting architectures is an indicator of strong engineering collaboration and a documentation-driven culture. It empowers engineers to move quickly from feature idea to implementation, and discuss design trade-offs with a shared understanding of their systems.</p><p>Teams that invest time in having architecture diagrams reduce cognitive load, onboard engineers faster, and prevent accidental complexity when making changes. Over time, this leads to more reliable systems and stronger engineering-product collaboration.</p><p>To recap, architecture diagrams help engineers:</p><ol><li>Establish a common baseline for discussing systems</li><li>Reduce review time and cognitive load</li><li>Enable asynchronous communication</li><li>Build a documentation-first culture</li></ol><h3>📚 Resources</h3><ul><li><a href="https://www.larksuite.com/en_us/blog/amazon-6-pager">https://www.larksuite.com/en_us/blog/amazon-6-pager</a></li><li><a href="https://c4model.com/">https://c4model.com</a></li><li><a href="https://en.wikipedia.org/wiki/Sequence_diagram">https://en.wikipedia.org/wiki/Sequence_diagram</a></li><li><a href="https://en.wikipedia.org/wiki/Activity_diagram">https://en.wikipedia.org/wiki/Activity_diagram</a></li><li><a href="https://learn.microsoft.com/en-us/devops/deliver/what-is-infrastructure-as-code">https://learn.microsoft.com/en-us/devops/deliver/what-is-infrastructure-as-code</a></li><li><a href="https://developer.hashicorp.com/terraform">https://developer.hashicorp.com/terraform</a></li><li><a href="https://docs.aws.amazon.com/cloudformation">https://docs.aws.amazon.com/cloudformation</a></li><li><a href="https://en.wikipedia.org/wiki/Model_Context_Protocol">https://en.wikipedia.org/wiki/Model_Context_Protocol</a></li><li><a href="https://github.com/joelparkerhenderson/architecture-decision-record">https://github.com/joelparkerhenderson/architecture-decision-record</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c3ff75ab5a66" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Design eBay using IcePanel]]></title>
            <link>https://icepanel.medium.com/design-ebay-using-icepanel-b87d89956027?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/b87d89956027</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[technolog]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Thu, 18 Dec 2025 23:32:03 GMT</pubDate>
            <atom:updated>2025-12-18T23:32:03.349Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RxLMEIULKzvFxs424DZkAw.png" /></figure><h3>📝 Introduction</h3><p>In this post, we’ll share an example architecture for <strong>eBay</strong> — one of the largest online auction and marketplace platforms where users can buy and sell items or make direct purchases. We’ll design this as software architects and create four hierarchical diagrams: Context, Container, Component, and Code (not sure what these are? Read <a href="https://icepanel.io/blog/2024-07-18-what-is-the-c4-model">this</a>). We’ll annotate the building blocks and highlight user interaction (data flow) within the system using IcePanel <a href="https://docs.icepanel.io/visual-storytelling/flows">Flows</a>.</p><p>Let’s first define the scope by writing the functional and non-functional requirements of the system. Afterwards, we’ll go through each layer of the C4 model.</p><p>You can view the final architecture at this link: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/eYV5">https://s.icepanel.io/DWnaysJ3cbCQqg/eYV5</a></p><h3>🔎 Scope</h3><p>For an online auction like eBay, users should be able to:</p><ol><li>Sell an item or post it for auction with a starting price.</li><li>Buy an item or place a bid with a price higher than the current bid.</li><li>View an auction for an item with the current highest bid.</li></ol><p>For non-functional requirements, the system should have:</p><ul><li>Strong consistency with bidding to make sure all buyers can see the same price.</li><li>Real-time notifications and scalable to ~1 million concurrent auctions.</li><li>Fault-tolerant and durable (i.e., we can’t drop any bids from buyers)</li></ul><p>Let’s start with the first diagram, Context.</p><h3>Level 1 — Context</h3><p>This context view shows the interaction between end users, our main system (eBay), and the external systems it integrates with. In this design, we have two actors:</p><ul><li>Seller: User who sells items on eBay in an auction or with a fixed price.</li><li>Bidder: User who buys items or places bids on eBay.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WA8KyNBZeetX739sanXIyQ.png" /></figure><p>Ebay also depends on two external systems:</p><ul><li><strong>Payment Provider (Stripe)</strong>: Responsible for processing payment transactions and managing the complete payment lifecycle. When a winning bidder needs to complete payment or when a seller receives funds, they are redirected to the payment provider’s secure interface, where card details are collected and processed.</li><li><strong>SMS Provider (Twilio)</strong>: Manages fast SMS delivery to users, mainly bidders. Our system publishes new bid events to a Kafka topic, where our notification service consumes that message and then forwards it to the SMS provider for notifying users.</li></ul><h3>Level 2 — Container</h3><p>This diagram is where we model a collection of independently deployable or runnable applications or data stores that are essential for the overall software system to function. This could be a web application, server, datastore, or a streaming data platform like <a href="https://kafka.apache.org/documentation/">Apache Kafka</a>.</p><p>This system is an <strong>event-based</strong> architecture. This approach is ideal for high-throughput bidding scenarios where services process messages asynchronously whenever an item receives a bid. Events are triggered using Kafka topics, allowing the system to handle traffic spikes gracefully while maintaining strong consistency guarantees.</p><p>Our system is composed of the following Containers:</p><ol><li><strong>Auction Service</strong>: Manages the complete auction lifecycle, including creating new auctions when sellers list items, reading auction details and current bid status, and updating auction metadata (start time, end time, status).</li><li><strong>Bid Producer</strong>: Responsible for accepting and validating incoming bids. It validates bid amounts with atomic checks on Redis, publishes bids to Kafka for asynchronous processing, and atomically updates the bid cache.</li><li><strong>Bid Service</strong>: Consumes bid events from Kafka and provides durable persistence. It consumes bid events from a Kafka topic, persists all bids to the Auction Database (bids table) for audit trail, and updates the auction’s current price in the database.</li><li><strong>Notification Service</strong>: Manages all user communications. It consumes bid events and auction lifecycle events from Kafka, sends real-time notifications when users are outbid, and sends winning bid confirmations.</li></ol><p><strong>Note:</strong> Real-time solutions like WebSocket connections for live auction updates and publish/subscribe patterns are outside the scope of this design. This architecture focuses on the core bidding flow, auction management, and durable event processing.</p><p>In this architecture, we use the following technologies:</p><ol><li><strong>AWS API Gateway</strong>: A scalable and secure entry point for all API requests coming from the frontend. This object is represented using <a href="https://icepanel.io/blog/2025-12-15-new-releases-nested-groups-connection-via">connection via</a> property.</li><li><strong>AWS EC2: </strong>Web service that provides reliable and secure compute for the different microservices (Auction Service, Bid Producer, Bid Service, Notification Service, Payment Service).</li><li><strong>Apache Kafka</strong>: A distributed event streaming platform that provides high throughput (millions of messages per second), durability (persists all messages to disk with replication), and ordering guarantees (partitioning by auction_id ensures sequential processing). Perfect for handling high-volume bidding periods while ensuring no bids are lost. This object is represented using a <a href="https://icepanel.io/blog/2025-12-15-new-releases-nested-groups-connection-via">connection via</a> property.</li><li><strong>PostgreSQL</strong>: An ACID-compliant relational database that ensures data integrity and strong consistency. Ideal for structured data like auctions and bids tables where transactional guarantees are critical.</li><li><strong>Redis</strong>: A fast in-memory cache that improves response times (sub-millisecond latency) and reduces database load. Essential for serving current bid prices to 1 million concurrent auctions.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iXBber3qYoMLRzDgg_53OA.png" /></figure><p>We’ve designed two common data flows using IcePanel. Check out these flows and play them step by step to see how our system works:</p><ol><li>Create a new auction listing: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/SpZW">https://s.icepanel.io/DWnaysJ3cbCQqg/SpZW</a></li><li>Place a bid on an auction: <a href="https://s.icepanel.io/DWnaysJ3cbCQqg/rmpv">https://s.icepanel.io/DWnaysJ3cbCQqg/rmpv</a></li></ol><h3>Level 3 — Component</h3><p>In the C4 model, a component is a grouping of related functionality encapsulated behind a well-defined interface. For example, a collection of classes behind an interface. Let’s look at the Components in eBay’s auction system.</p><h4>1. Bid Producer</h4><p>The diagram below shows how a user interacts with the Bid Producer to place a bid on an auction. When a user sends a POST /bid request, the Bid API first validates the request and extracts the auction_id and bid_amount. It then retrieves the current highest bid from the cache (using <a href="https://medium.com/@hanifmaliki/concurrency-in-go-pessimistic-optimistic-and-redis-distributed-locks-explained-77125355594d">optimistic locking</a>) and checks if the new bid amount exceeds it. If the bid is too low, an error is returned to the bidder. This prevents race conditions when multiple bidders submit bids simultaneously.</p><p>Once the Redis lock is acquired, the Bid Kafka Publisher sends a new bid event to the bid-events topic in Kafka. The bid event includes auction_id, user_id, bid_amount, and timestamp. After publishing to Kafka, the service atomically updates the current highest bid in Redis (auction:{id}:price) before releasing the lock.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*07uG-8nWCRuAzPJDNyF53g.png" /></figure><h4>2. Auction Service</h4><p>The Auction Service manages the complete auction lifecycle and provides read/write access to auction data. When a user requests auction information via GET /auctions/:auctionId, the Auction API first checks the Auction Cache (Redis) to retrieve hot auction data with sub-millisecond latency. If the data isn’t cached, the Auction Controller queries the Auction Repository, which fetches auction details from the Auction Database (PostgreSQL).</p><p>The Redis Client manages all cache operations, storing frequently accessed auction data with time-to-live (TTL) values to reduce database load. The Auction Repository handles all database interactions, including creating new auction listings when sellers post items, updating auction metadata (start time, end time, reserve price), and querying active auctions with filters.</p><p>When an auction ends, the Auction Controller determines the winning bidder by querying the highest bid from the database. It then triggers the Auction Payment Controller, which initiates the payment flow by calling the Payment Service. The Payment Controller handles payment confirmations, failures, and refund processing for cancelled auctions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7mV83q_3Kbbm1Q2W8Txi4A.png" /></figure><h4>3. Bid Service</h4><p>The Bid Service handles all bid processing in our online auction system. When a bid event is published to Kafka, the Bid Consumer polls messages from the bid topic and processes each bid event asynchronously. It interfaces with the Bid Repository, which serves as the data access layer for storing and retrieving bid information. The Bid Repository executes SQL queries against the Auction Database (PostgreSQL) to persist bids into the database and maintain bid history.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pvUant2dlSJ2LYqD8MeGJA.png" /></figure><p>Let’s go one level deeper with the source code in the Code layer.</p><h3>Level 4 — Code</h3><p>This is where we can view implementation details at the code level. We don’t recommend creating extensive diagrams for this; instead, we link directly to the code. However, here’s the general structure of these components for reference. We’ll briefly go over two Components: <strong>Auction </strong>and <strong>Bid Producer</strong>.</p><h3>Classes in “Auction Service”</h3><p>This component manages the auction lifecycle and real-time auction data access. The Auction API class exposes RESTful endpoints for retrieving auction details, current high bids, and auction status. The API first checks Redis cache for hot auction data before querying the database. The Auction Controller coordinates between cache, repository, and payment processing. The Auction Repository serves as the data layer for fetching auction information from the Auction Database.</p><p><strong>Auction Controller</strong></p><ul><li>GET /auctions/:auctionId — Retrieve auction details (item, description, current bid, etc.)</li><li>GET /auctions/:auctionId/bids — Get bid history for specific auction</li><li>POST /auctions — Create a new auction listing</li><li>PATCH /auctions/:auctionId — Update auction details</li><li>DELETE /auctions/:auctionId — Cancel auction</li></ul><p><strong>Redis Client</strong></p><ul><li>getCachedAuction(auctionId) — Retrieve auction data and current high bid from cache</li><li>cacheAuction(auctionId, auctionData, ttl) — Store auction data with time-to-live</li></ul><p><strong>Auction Repository</strong></p><ul><li>getAuctionById(auctionId) — Fetch complete auction details from database</li><li>getCurrentHighBid(auctionId) — Retrieve current winning bid amount and bidder</li><li>updateAuctionStatus(auctionId, status) — Change auction state (active, ended, cancelled)</li><li>getActiveAuctions(filters) — Query active auctions with filtering and pagination</li></ul><p><strong>Auction Payment Controller</strong></p><ul><li>initiatePayment(auctionId, winnerId) — Start payment process for auction winner</li><li>refundBid(bidId) — Process refunds for cancelled auctions or failed transactions</li></ul><h3>Classes in “Bid Producer”</h3><p>This component handles the bid submission workflow with strong consistency guarantees. The Bid API class provides RESTful endpoints for users to place bids and check bid status. The Bid Validator ensures bid amounts meet minimum requirements and auction eligibility rules. The Optimistic Lock Manager implements Redis-based locking to prevent race conditions during concurrent bidding. The Kafka Producer handles asynchronous event publishing for downstream bid processing and notifications.</p><p>These classes have roughly the following methods:</p><p><strong>Bid API</strong></p><ul><li>POST /bids — Place a new bid on an active auction</li><li>GET /bids/:bidId — Retrieve details of a specific bid</li><li>GET /auctions/:auctionId/bids — Get all bids for an auction</li></ul><p><strong>Cache Client</strong></p><ul><li>getCurrentBid(auctionId) — Retrieve current bid for specific auction</li><li>updateCurrentBid(auctionId, bidAmount) — Update cached high bid in real-time</li></ul><p><strong>Kafka Producer</strong></p><ul><li>publishBidPlacedEvent(bidData) — Send bid creation event to Kafka topic</li><li>publishBidOutbidEvent(userId, auctionId) — Notify when user is outbid</li></ul><h3>Conclusion</h3><p>In this post, we designed an online auction platform (eBay) using the C4 model on IcePanel. We began with the core requirements like strong consistency, real-time updates, and fault tolerance, and modeled the system from the top down, starting with the Context layer, followed by the Container, Component, and finally the Code layer.</p><p>If you enjoyed this post, check out our previous design deep dives using IcePanel:</p><ol><li><a href="https://icepanel.io/blog/2025-11-18-design-youtube-using-icepanel">Design YouTube</a></li><li><a href="https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel">Design Ticketmaster</a></li></ol><h3>📚 Resources</h3><ul><li><a href="https://aws.amazon.com/msk/">https://aws.amazon.com/msk/</a></li><li><a href="https://kafka.apache.org/documentation/">https://kafka.apache.org/documentation/</a></li><li><a href="https://redis.io/open-source/">https://redis.io/open-source</a></li><li><a href="https://aws.amazon.com/microservices">https://aws.amazon.com/microservices</a></li><li><a href="https://pyemma.github.io/How-to-design-auction-system/">https://pyemma.github.io/How-to-design-auction-system/</a></li><li><a href="https://icepanel.io/blog/2025-11-18-design-youtube-using-icepanel">https://icepanel.io/blog/2025-11-18-design-youtube-using-icepanel</a></li><li><a href="https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel">https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b87d89956027" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s the purpose of software architecture diagramming?]]></title>
            <link>https://icepanel.medium.com/whats-the-purpose-of-software-architecture-diagramming-d76eac75bbeb?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/d76eac75bbeb</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Tue, 09 Dec 2025 19:20:37 GMT</pubDate>
            <atom:updated>2025-12-09T19:20:37.221Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ziS06AQpAgQTW_E2.png" /></figure><h3>Introduction</h3><p>The concept of software architecture started in the 1960s, during the time when the idea of object-oriented programming (OOP) was introduced. Before that, programming was low-level and written in assembly language. In the 1970s, higher-level programming like C/C++ started to gain popularity, programmers began theorising about how to structure software, exploring ideas around modularity and introducing different architectural styles. Some of the most well-known architectures include <a href="https://www.ibm.com/think/topics/monolithic-architecture">monolithic</a>, <a href="https://medium.com/@soumyaroy172003/microkernel-architecture-f2443c8ba915">microkernel</a>, and <a href="https://en.wikipedia.org/wiki/Microservices">microservices</a>.</p><p>Diagramming became an essential engineering practice for designing software. It started with a modelling language called <a href="https://en.wikipedia.org/wiki/Unified_Modeling_Language">Unified Modelling Language (UML)</a> for object-oriented programming, then evolved to include more flexible approaches, like ArchiMate for enterprise architecture, and <a href="https://icepanel.io/c4-model">C4 Model</a> for modern software systems. Teams in non-enterprise environments often default to pragmatic approaches for communicating architecture, using simple boxes and arrows as the basis for diagramming.</p><h3>Purpose of software architecture</h3><p>Some engineers perceive architectural diagramming as a secondary piece of documentation that they optionally produce and the intended audience is their teams only. This is a common misconception that undervalues the real purpose of software architecture. In reality, architectural diagramming is:</p><ol><li>Not secondary: Designing architecture is as important as writing code that runs the system.</li><li>Not optional: it should be defined before building a new system or implementing a feature as it clarifies dependencies and interactions.</li><li>Not only: Architecture diagrams also serve the wider organisation and other stakeholders by documenting the key architectural decisions to maintain the system.</li></ol><p>Martin Fowler, Chief Scientist at Thoughtworks, is one of the most influential people in software architecture. He emphasised the importance of software design through his books like <a href="https://www.amazon.co.uk/Enterprise-Application-Architecture-Addison-Wesley-Signature/dp/0321127420">Patterns of Enterprise Application Architecture</a> and <a href="https://www.amazon.co.uk/Refactoring-Improving-Design-Existing-Technology/dp/0201485672">Refactoring</a>. In a well-known <a href="https://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf">email exchange with Ralph Johnson</a>, he defined architecture as the shared understanding that the expert developers have of the system design. Check out his 15-minute talk on <a href="https://www.youtube.com/watch?v=DngAZyWMGR0">YouTube</a> where he explains what architecture is and why it matters.</p><p>Fundamentally, software architecture defines the organisation of a system: how components communicate and, when grouped together, ultimately deliver value to users. Think of it as the difference between a booking system (architecture) versus an individual payment (component within architecture). Here is an example of an AWS architecture below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/0*2emaOHOIIMGlQUHv.png" /></figure><p>To document software architectures, diagramming is an important exercise for visually representing component relationships and communicating architectural decisions clearly. That’s why system design interviews are widely used to assess a candidate’s ability to think architecturally and communicate trade-offs when designing scalable systems.</p><h3>Common Mistakes</h3><p>Some mistakes people make when designing software architectures are:</p><h3>1. Focusing on too much detail.</h3><p>Some engineers tend to approach diagramming as a way to enumerate every component and all of its edge cases. For example, say there is a web service that calls multiple endpoints to complete a specific flow (e.g., a checkout flow). Some engineers will want to highlight this flow in their architecture with all the edge cases to make it comprehensive. However, that is not the goal of the architecture, that belongs in an <a href="https://www.visual-paradigm.com/guide/uml-unified-modeling-language/what-is-activity-diagram/">activity diagram</a>. The purpose of a software architecture diagram is to highlight the current state of the system and the key decisions behind the design.</p><h3>2. Serving all stakeholders with a single diagram.</h3><p>Each type of audience has a requirement from the architectural diagrams. Product and design want a brief, high-level understanding of how the major pieces fit together. Engineers want to see more than high-level, they want to understand the technical details and decisions made behind each component. For example, product managers might want to understand the mobile app integration project through the Context layer or Container layer of the C4 model, while engineers need more details like the authentication flow in the Component layer.</p><p>Even with AWS diagrams, architecture can be split into layers of abstraction similar to the C4 model. Product teams can view high-level diagrams that explain the customer onboarding process for their new SaaS product (e.g., user dashboard, analytics, or named business services), while engineers can reference low-level architecture diagrams that focus on networking components (such as VPCs, subnets, and data access patterns) and services (such as EC2 and ECS) that run the infrastructure.</p><p>A single diagram cannot effectively serve all audiences, it will either be too simplistic or too complex for at least one group.</p><h3>3. Mixing levels of abstraction.</h3><p>Mixing levels of abstraction is a common trap in architecture diagramming. Some engineers tend to show high-level components like web services or datastores alongside lower-level details like OS processes or network connections, often making it unclear what the viewer should focus on or what is important. A better approach is to be intentional about the level of detail you’re presenting. High-level diagrams should communicate the overall system structure and architectural decisions, while separate, detailed diagrams can expand on specific modules or flows. This way, each diagram has a clear purpose and is easier for its intended audience to understand. A good way to avoid mixing abstractions is to follow a structured approach like the C4 Model.</p><h3>Future of software architecture with AI</h3><p>TL;DR: a “vibe-diagramming” phase will soon disrupt the industry, but the need for software architects will still exist.</p><p>Current LLMs like GPT-5.1, Gemini 3 Pro, Claude Sonnet 4.5 are the state-of-the-art models. They excel at generating production-quality code, interpreting large contexts (e.g., monorepos), and building deep understanding and reasoning within enterprise systems. However, they still struggle with nuanced design and architectural decision-making (try to ask it to <a href="https://icepanel.io/blog/2025-10-20-design-ticketmaster-using-icepanel">design a Ticketmaster</a>). For now, LLMs can generate simple language-based diagrams like Mermaid.js and help interpret existing architectures, but designing and maintaining the overall architecture of a complex system still requires human expertise.</p><p>The past few years have been a disruptive shift to the software engineering industry, with predictions that AI would replace software developers entirely. That hasn’t happened. Human involvement remains essential for strategic thinking and problem-solving. We believe the same pattern will apply for software architects.</p><p>AI will eventually transform the software architecture domain, but the fundamentals won’t change. Even as LLMs improve at diagramming, software architects will still be needed for understanding business constraints, making trade-offs, and aligning technical decisions with business goals. The future with AI will be an accelerator for architects, not a replacement.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*HQmXDW_QaGkarHn5.png" /></figure><p>For interpretation, you can explore architecture diagrams by querying an MCP server (e.g., see <a href="https://icepanel.io/blog/2025-05-15-new-mcp-server">IcePanel’s MCP</a>). However, designing or maintaining architectures with AI is still in its early stage. Software architects can use AI tools to interpret architecture, but not yet to create it.</p><h3>Conclusion</h3><p>Software architecture diagramming has evolved from early theories of software design in the 1960s and formal modeling languages like UML to the flexible, pragmatic approaches that serve modern development teams today. The core purpose remains unchanged: to visually communicate how systems are organised, document key architectural decisions, and create shared understanding across teams.</p><p>While we’ve discussed common mistakes to avoid and good practices to follow, the landscape is shifting as AI tools begin to enter the architectural workflow. The question isn’t whether AI will impact how architects diagram and design systems, but rather how architects can best leverage these emerging capabilities to enhance their work.</p><p>As AI tools continue to advance, they’ll augment architects’ capabilities in interpreting and generating diagrams, but human involvement will remain necessary. The future belongs to architects who leverage AI as a design assistant while maintaining their role as strategic technical leaders who understand business constraints, evaluate trade-offs, and align technical decisions with organisational goals.</p><p>If you enjoyed this piece, check out our related post on how AI is redefining the role of a software architect: <a href="https://icepanel.io/blog/2025-07-21-how-ai-is-redefining-the-role-of-a-software-architect">https://icepanel.io/blog/2025-07-21-how-ai-is-redefining-the-role-of-a-software-architect</a></p><h3>📚 Resources</h3><ul><li><a href="https://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf">https://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf</a></li><li><a href="https://www.youtube.com/watch?v=DngAZyWMGR0">https://www.youtube.com/watch?v=DngAZyWMGR0</a></li><li><a href="https://www.visual-paradigm.com/guide/uml-unified-modeling-language/what-is-activity-diagram/">https://www.visual-paradigm.com/guide/uml-unified-modeling-language/what-is-activity-diagram/</a></li><li><a href="https://icepanel.io/blog/2025-05-15-new-mcp-server">https://icepanel.io/blog/2025-05-15-new-mcp-server</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d76eac75bbeb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The best alternatives to Miro for software architecture diagrams]]></title>
            <link>https://icepanel.medium.com/the-best-alternatives-to-miro-for-software-architecture-diagrams-3879667d8171?source=rss-7709f5c2ae4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/3879667d8171</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[c4-model]]></category>
            <category><![CDATA[saas]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[IcePanel]]></dc:creator>
            <pubDate>Tue, 25 Nov 2025 18:25:18 GMT</pubDate>
            <atom:updated>2026-02-18T21:36:08.466Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4slbkYX5gyZGwZEDlnNTkg.png" /></figure><h3>1. LucidChart</h3><ul><li>Started in 2008</li><li>Similar to <a href="http://Draw.io">Draw.io</a></li><li>Pricing: Free and paid plans (starting at $12/mo/user for teams)</li><li>Best for medium-sized technical teams</li></ul><h3>What is LucidChart?</h3><p><a href="https://www.lucidchart.com/">LucidChart</a> is a general-purpose diagramming tool to create everything from flowcharts, org charts, and architecture diagrams. Easy to use, collaborative, and capable of doing many different things. If you’re coming from Miro, you’ll find the LucidChart experience similar, perhaps slightly more difficult in terms of usability.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a9EaUPYHshA5Et9GCA0yuw.png" /></figure><h3>Main features</h3><ul><li>👍 Easy to use with lots of customization for shapes and lines</li><li>📊 Supports many different diagram types (UML, C4 model, mind maps, flowcharts)</li><li>🫂 Real-time collaboration and integrations with a variety of tools (Atlassian, Teams, Slack)</li><li>⏬ Import from <a href="http://Draw.io">Draw.io</a>, Visio, Gliffy, and other similar tools</li></ul><h3>How does LucidChart compare to Miro?</h3><h4>Pricing</h4><ul><li><strong>LucidChart:</strong> Free and paid plans for teams starting at <strong>$12/mo/user</strong> (minimum 3 seats on Team plan).</li><li><strong>Miro:</strong> Free and paid plans for teams starting at <strong>$10/user/mo</strong>.</li></ul><h4>Shape and Templates Library</h4><ul><li><strong>LucidChart:</strong> Premium shape &amp; template library on Team plan; custom shapes available.</li><li><strong>Miro:</strong> Premium shape &amp; template library on Business plan; custom shapes available.</li></ul><h4>Integrations</h4><ul><li><strong>LucidChart:</strong> Integrates with Atlassian (Confluence, JIRA), Google Drive, Teams, Slack, and more.</li><li><strong>Miro:</strong> Integrates with Atlassian, Google, Microsoft 365, and more.</li></ul><h4>UI/UX</h4><ul><li><strong>LucidChart:</strong> Simple UI, but slightly harder to use than Miro.</li><li><strong>Miro:</strong> Easy-to-use drag-and-drop UI.</li></ul><h4>Collaboration</h4><ul><li><strong>LucidChart:</strong> Real-time collaboration with commenting.</li><li><strong>Miro:</strong> Real-time collaboration with commenting.</li></ul><h4>AI Features</h4><ul><li><strong>LucidChart:</strong> Generate, iterate, and summarize diagrams with AI.</li><li><strong>Miro:</strong> Generate, iterate, and edit text with AI; agents with “sidekicks.”</li></ul><h4>Enterprise</h4><ul><li><strong>LucidChart:</strong> Enterprise plan available.</li><li><strong>Miro:</strong> Enterprise plan available.</li></ul><p><strong>Best for:</strong> Teams looking for a general diagramming tool that can do a bit of everything. Ideal if software architecture diagrams are ephemeral and don’t need to exist for long-term use.</p><h3>2. Draw.io (<a href="http://diagrams.net">diagrams.net</a>)</h3><ul><li>Started in 2000</li><li>Similar to LucidChart</li><li>Pricing: Free (open-source), but paid on Atlassian after 10+ users</li><li>Best for small teams on the free option. Good for large teams with Atlassian</li></ul><h3>What is Draw.io?</h3><p><a href="http://Draw.io">Draw.io</a> is an open-source diagramming tool with a drag-and-drop UI and large shape library, allowing you to create different types of architecture diagrams. The company’s mission is to “provide free, high quality diagramming software for everyone.” Using the open-source version allows you to freely create, edit, and save diagrams in your preferred workspace. For team’s already using Atlassian products (Confluence), you can also download/purchase the Draw app from their marketplace and use it natively.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NmYA20yQlWd6jufD6f-5dA.png" /></figure><h3>Main features</h3><ul><li>🖌️ Intuitive drag-and-drop editor with customization options.</li><li>📦 Flexible diagram storage. Diagrams can be saved in Google Drive, Microsoft OneDrive, or locally on the desktop app.</li><li>👥 Real-time collaboration with commenting.</li><li>🤝 Atlassian (Confluence and JIRA) integration. Work directly in the tool without leaving.</li><li>💰 Free and paid options with enterprise-level security</li></ul><h3>How does Draw.io compare to Miro?</h3><h4>Pricing</h4><ul><li><strong>Draw.io:</strong> Generous free option with paid plans in the Atlassian marketplace.</li><li><strong>Miro:</strong> Free and paid plans for teams starting at <strong>$10/user/mo</strong>.</li></ul><h4>Shape and Templates Library</h4><ul><li><strong>Draw.io:</strong> Large shape library for architecture diagrams (UML, C4, etc.).</li><li><strong>Miro:</strong> Premium shape and template library on Business plan; custom shapes available.</li></ul><h4>Integrations</h4><ul><li><strong>Draw.io:</strong> Integrates with Google Drive, OneDrive, GitHub, Confluence, and Notion.</li><li><strong>Miro:</strong> Integrates with Atlassian, Google, Microsoft 365, and more.</li></ul><h4>UI/UX</h4><ul><li><strong>Draw.io:</strong> Simple and easy-to-use UI.</li><li><strong>Miro:</strong> Easy drag-and-drop UI.</li></ul><h4>Collaboration</h4><ul><li><strong>Draw.io:</strong> Real-time collaboration with commenting via Google Drive, OneDrive, or Atlassian.</li><li><strong>Miro:</strong> Real-time collaboration with commenting.</li></ul><h4>AI Features</h4><ul><li><strong>Draw.io:</strong> AI-driven smart templates and generated diagrams, more basic.</li><li><strong>Miro:</strong> Generate, iterate, and edit text with AI; agents with “sidekicks.”</li></ul><h4>Enterprise</h4><ul><li><strong>Draw.io:</strong> Enterprise security available via Atlassian standards.</li><li><strong>Miro:</strong> Enterprise plan available.</li></ul><p><strong>Best for:</strong> Teams wanting a free, versatile diagramming tool that can be saved in their existing workspace. Also great for teams working in Confluence or JIRA who want something that feels native.</p><h3>3. IcePanel</h3><ul><li>Started in 2021</li><li>Similar to LucidChart and Miro</li><li>Pricing: Free and paid options (Starting at $40/mo/editor annually)</li><li>Best for medium to large teams</li></ul><h3>What is IcePanel?</h3><p><a href="https://icepanel.io/">IcePanel</a> is a collaborative diagramming and modelling tool based on the C4 model. It allows you to create hierarchical diagrams while maintaining a single source of truth in a model. It’s a lightweight tool that helps teams design software architecture at scale with structure and consistency. Compared to Miro and other diagramming tools, it’s mainly built for software architecture design and docs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oYFtWSGxCrKM766tGTV11g.png" /></figure><h3>Main features</h3><ul><li>🔢 C4 model diagrams (Level 1 to Level 3)</li><li>🔀 Communicate user journeys with Flows and Tags</li><li>🧱 Maintain and reuse objects with a model</li><li>💡 Collaborate on ideas in Drafts and track changes with Versions</li><li>🤖 Export and connect model with LLMs with MCP and LLMs.txt exports</li></ul><h3>How does IcePanel compare to Miro?</h3><h4>Pricing</h4><ul><li><strong>IcePanel:</strong> Free and paid plans for teams starting at <strong>$40/mo/user annually</strong>.</li><li><strong>Miro:</strong> Free and paid plans for teams starting at <strong>$10/user/mo</strong>.</li></ul><h4>Model-based</h4><ul><li><strong>IcePanel:</strong> Yes — provides a single source of truth.</li><li><strong>Miro:</strong> No.</li></ul><h4>Architecture Design</h4><ul><li><strong>IcePanel: </strong>Create Flows to communicate data flows and user journeys. Layered diagrams for consistent structure. Draft future-state views of architecture.</li><li><strong>Miro:</strong> None.</li></ul><h4>Integrations</h4><ul><li><strong>IcePanel:</strong> Embed diagrams in Confluence, Notion, Miro, SharePoint via iFrame.</li><li><strong>Miro:</strong> Integrates with Atlassian, Google, Microsoft 365, and more.</li></ul><h4>UI/UX</h4><ul><li><strong>IcePanel:</strong> Easy-to-use drag-and-drop UI.</li><li><strong>Miro:</strong> Easy-to-use drag-and-drop UI.</li></ul><h4>Collaboration</h4><ul><li><strong>IcePanel:</strong> Real-time collaboration with commenting.</li><li><strong>Miro:</strong> Real-time collaboration with commenting.</li></ul><h4>AI Features</h4><ul><li><strong>IcePanel:</strong> Export diagrams as LLMs.txt and MCP integration.</li><li><strong>Miro:</strong> Generate, iterate, and edit text with AI; agents with “sidekicks.”</li></ul><h4>Enterprise</h4><ul><li><strong>IcePanel:</strong> Enterprise-level security available on Scale plan.</li><li><strong>Miro:</strong> Enterprise plan available.</li></ul><p><strong>Best for:</strong> Teams that want to consistently design and document their software architecture without the complexity of learning a new syntax.</p><h3>4. Eraser</h3><ul><li>Started in 2020</li><li>Similar to <a href="http://Draw.io">Draw.io</a></li><li>Pricing: Free and paid plans (starting at $12/mo/user monthly)</li><li>Best for small to medium-sized teams</li></ul><h3>What is Eraser?</h3><p><a href="https://www.eraser.io/">Eraser</a> is an AI-based diagramming and docs tool for technical teams. Eraser lets you generate diagrams from prompts, connect diagrams to code to keep them in sync, and create docs in context with diagrams.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ck8OId_ezNmlkR5enIyzdg.png" /></figure><h3>Main features</h3><ul><li>👍 Drag-and-drop UI and diagrams-as-code support</li><li>💼 Focused on technical design and docs</li><li>🤖 AI features to generate and iterate on designs</li><li>🫂 Real-time collaboration and commenting</li><li>🔁 Integrations with GitHub, Notion, Confluence, and VS code extension</li></ul><h3>How does Eraser compare to Miro?</h3><h4>Pricing</h4><ul><li><strong>Eraser:</strong> Free and paid plans for teams starting at <strong>$12/user/mo</strong>.</li><li><strong>Miro:</strong> Free and paid plans for teams starting at <strong>$10/user/mo</strong>.</li></ul><h4>Shape and Templates Library</h4><ul><li><strong>Eraser:</strong> Core shapes and architecture templates; custom shapes available on paid plans.</li><li><strong>Miro:</strong> Premium shape and template library on Business plan; custom shapes available.</li></ul><h4>Integrations</h4><ul><li><strong>Eraser:</strong> Embed diagrams in Notion and Confluence; commit files and diagrams to GitHub.</li><li><strong>Miro:</strong> Integrates with Atlassian, Google, Microsoft 365, and more.</li></ul><h4>UI/UX</h4><ul><li><strong>Eraser:</strong> Drag-and-drop UI with diagram-as-code; harder to use than Miro.</li><li><strong>Miro:</strong> Easy-to-use drag-and-drop UI.</li></ul><h4>Collaboration</h4><ul><li><strong>Eraser:</strong> Real-time collaboration with commenting.</li><li><strong>Miro:</strong> Real-time collaboration with commenting.</li></ul><h4>AI Features</h4><ul><li><strong>Eraser:</strong> Generate and iterate using AI.</li><li><strong>Miro:</strong> Generate, iterate, and edit text with AI; agents with “sidekicks.”</li></ul><h4>Enterprise</h4><ul><li><strong>Eraser:</strong> Enterprise plan available.</li><li><strong>Miro:</strong> Enterprise plan available.</li></ul><p><strong>Best for:</strong> Teams that are looking for a technical solution to design and docs with AI features. Ideal for teams looking for a tool that leans more on diagrams-as-code.</p><h3>5. Excalidraw</h3><ul><li>Started in 2020</li><li>Similar to <a href="http://Draw.io">Draw.io</a></li><li>Pricing: Free (open source) and paid plans (starting at $7/mo)</li><li>Best for small teams to medium sized teams.</li></ul><h3>What is Excalidraw?</h3><p><a href="https://plus.excalidraw.com/">Excalidraw</a> is a simple white boarding tool with real-time collaboration. It’s informal visual style makes it a popular choice for running meetings, brainstorms, or doing quick and dirty diagrams. The free plan requires no sign-up, and is a great option if you need to sketch something out quickly. The paid (Plus) plan offers similar functionality to Miro, at a slightly lower price point with less security and AI features.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*2en8W9TxW0Ca1t0L.png" /></figure><h3>Main features</h3><ul><li>🖌️ Simple and intuitive UI/UX</li><li>🫂 Real-time collaboration and commenting (on paid plan)</li><li>📚 Public library for shapes and templates</li><li>🤖 Gen AI capabilities (text to diagram, wireframe to code)</li></ul><h3>How does Excalidraw compare to Miro?</h3><h4>Pricing</h4><ul><li><strong>Excalidraw:</strong> Free and paid plans for teams starting at <strong>$6/user/mo</strong>.</li><li><strong>Miro:</strong> Free and paid plans for teams starting at <strong>$10/user/mo</strong>.</li></ul><h4>Shape and Templates Library</h4><ul><li><strong>Excalidraw:</strong> Shapes and templates available from the public library.</li><li><strong>Miro:</strong> Premium shape and template library on Business plan; custom shapes available.</li></ul><h4>Integrations</h4><ul><li><strong>Excalidraw:</strong> Integrates with Notion and Obsidian.</li><li><strong>Miro:</strong> Integrates with Atlassian, Google, Microsoft 365, and more.</li></ul><h4>UI/UX</h4><ul><li><strong>Excalidraw:</strong> Easy-to-use drag-and-drop UI.</li><li><strong>Miro:</strong> Easy-to-use drag-and-drop UI.</li></ul><h4>Collaboration</h4><ul><li><strong>Excalidraw:</strong> Real-time collaboration with commenting.</li><li><strong>Miro:</strong> Real-time collaboration with commenting.</li></ul><h4>AI Features</h4><ul><li><strong>Excalidraw:</strong> Text-to-diagram and wireframe-to-code.</li><li><strong>Miro:</strong> Generate, iterate, and edit text with AI; agents with “sidekicks.”</li></ul><h4>Enterprise</h4><ul><li><strong>Excalidraw:</strong> None — no SSO.</li><li><strong>Miro:</strong> Enterprise plan available.</li></ul><p><strong>Best for:</strong> Teams looking for quick ad-hoc architecture diagrams at an affordable price.</p><h3>Choosing the right alternative</h3><p>Ultimately, the right tool for you depends on your needs, budget, and team’s willingness to learn a new tool.</p><ul><li>If you’re constrained by <strong>budget,</strong> <a href="http://Draw.io">Draw.io</a> or Excalidraw offer free solutions.</li><li>If you want a tool that’s <strong>lightweight</strong>, easier to <strong>maintain</strong>, and <strong>structured</strong>, try IcePanel.</li><li>If your team’s already using <strong>Atlassian</strong> products, <a href="http://Draw.io">Draw.io</a> is a good option.</li><li>If you want to <strong>automate</strong> and <strong>version</strong> your diagrams, try Eraser.</li></ul><p>Any tools that we missed? Let us know!</p><p>Stay Chill 🤙</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3879667d8171" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>