<?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 Benjamin Cane on Medium]]></title>
        <description><![CDATA[Stories by Benjamin Cane on Medium]]></description>
        <link>https://medium.com/@madflojo?source=rss-96013faddf78------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*mu9eLLugJ68QrlRwLPBmwA@2x.jpeg</url>
            <title>Stories by Benjamin Cane on Medium</title>
            <link>https://medium.com/@madflojo?source=rss-96013faddf78------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 10 Jun 2026 17:23:36 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@madflojo/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[Your coding agent is missing one thing: architectural context]]></title>
            <link>https://itnext.io/your-coding-agent-is-missing-one-thing-architectural-context-4d5d33d2110a?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/4d5d33d2110a</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 28 May 2026 00:00:14 GMT</pubDate>
            <atom:updated>2026-06-06T16:45:48.610Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*o71fQkzE6hVGFsGh" /><figcaption>Photo by <a href="https://unsplash.com/@sxoxm?utm_source=medium&amp;utm_medium=referral">Sven Mieke</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Your coding agent is missing one thing: architectural context.</p><p>I’ve been a big believer in Architecture Decision Records ( ADRs) long before coding agents came along.</p><p>Documenting decisions gives engineers context:</p><p>Why is the system designed a certain way? What constraints existed at the time? What tradeoffs were made?</p><p>That context matters. It also matters for agents.</p><h3>🤖 Agents Need Context Too</h3><p>Unlike human engineers, agents don’t get context from hallway conversations, shadowing others, or tribal knowledge.</p><p>They only know what you capture. The best way to capture architectural context? Write it down as a decision record-and make it accessible to agents.</p><p>The only question is, what’s the best way to make decision records accessible?</p><h3>🏗️ Option 1: MCP Server</h3><p>If your ADRs live in a wiki or documentation system, you can expose them through an MCP server.</p><p>This works well when documentation is spread across teams or multiple systems that need to be aggregated.</p><p>You want a unified interface for agents. MCP is a good approach, but it comes with some infrastructure overhead.</p><h3>🧱 Option 2: Keep ADRs in Git</h3><p>I’ve long preferred storing ADRs in Git.</p><p>It provides versioning, review workflows, automated validation, and is where engineering work happens. Storing ADRs in Git, ideally alongside your code, is the fastest way to give agents usable context.</p><p>The challenge is that architecture often spans multiple services and repositories. So many centralize their architecture into a single repository, which is not where your code lives.</p><h3>🌉 Bridging the Gap</h3><p>Most modern coding agents let you include additional directories or sources at runtime, either through slash commands or CLI options.</p><p>That means you can: open your codebase, include your architecture repository, and run the agent with context.</p><p>Just adding another directory gives your agent an understanding of system constraints, architecture decisions, technology choices, and surrounding systems. These are not things an agent can reliably infer from code alone.</p><h3>💡 Final Thought: Why Context Matters</h3><p>With architectural context, agents produce code that aligns with your system.</p><p>When engineers understand the system end to end, they make better decisions. The same applies to agents.</p><p>If you want better results, give better context.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-05-28/"><em>https://bencane.com</em></a><em> on May 28, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4d5d33d2110a" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/your-coding-agent-is-missing-one-thing-architectural-context-4d5d33d2110a">Your coding agent is missing one thing: architectural context</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Health-check the listener your gRPC traffic actually uses]]></title>
            <link>https://madflojo.medium.com/health-check-the-listener-your-grpc-traffic-actually-uses-60ef491ffd7f?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/60ef491ffd7f</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 21 May 2026 00:00:30 GMT</pubDate>
            <atom:updated>2026-06-01T17:31:00.692Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DJBFlzB4uHGqHIy9" /><figcaption>Photo by <a href="https://unsplash.com/@joshua_chehov?utm_source=medium&amp;utm_medium=referral">Joshua Chehov</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>One of the easiest ways to break a gRPC service in production is health-checking the wrong listener.</p><p>A common issue I see teams run into when adopting gRPC is leaving readiness checks pointed at their HTTP listener while production traffic actually flows through gRPC.</p><p>Everything looks fine until it suddenly doesn’t.</p><h3>🤔 The Problem</h3><p>Many gRPC services run two listeners: one for HTTP and one for gRPC.</p><p>The HTTP listener often exists for metrics, liveness checks, and management APIs. Teams moving to gRPC often reuse the HTTP health checks they set up for their REST-based services.</p><p>It’s generally a good idea to reuse what you already have, but in this case, it can be misleading.</p><h3>⚠️ Health-Check What Serves Traffic</h3><p>If customers connect through gRPC, your first readiness check should too.</p><p>Your HTTP listener can be perfectly healthy while the gRPC listener is misconfigured, hung, or otherwise failing.</p><p>Meanwhile, Kubernetes, load balancers, and dashboards might all show green. ✅</p><p>This happens more often than people think.</p><h3>🩺 Better Ways to Monitor gRPC</h3><p>There are better ways to monitor your gRPC service.</p><h3>gRPC Health Probe ✅</h3><p>Use a real gRPC health check request against the listener.</p><p>This validates the actual serving path and confirms the service can respond over gRPC.</p><p>A strong default option.</p><h3>Build a Status gRPC Service 📋</h3><p>Expose an internal status method in your gRPC API.</p><p>This gives you flexibility to check deeper dependencies, such as database readiness, downstream systems, internal state, and maintenance toggles.</p><p>It’s more work, but more control.</p><h3>Use a Single Shared Listener ☝️</h3><p>Because gRPC runs on top of HTTP/2, many languages and frameworks can serve HTTP and gRPC traffic on the same listener.</p><p>That means an HTTP health endpoint may be acceptable because it checks the same network path. It still does not fully validate gRPC behavior, but it is better than checking an entirely separate listener.</p><h3>🧠 Final Thoughts</h3><p>gRPC is awesome.</p><p>But making a service production-ready means revisiting configurations inherited from REST services.</p><ul><li>Health checks</li><li>Load balancing behavior</li><li>Connection management</li><li>Contracts</li><li>Operational tooling</li></ul><p>None of these changes are difficult. They’re just easy to miss.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-05-21/"><em>https://bencane.com</em></a><em> on May 21, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=60ef491ffd7f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Weighted load balancing has saved me more times than I can count]]></title>
            <link>https://itnext.io/weighted-load-balancing-has-saved-me-more-times-than-i-can-count-2d9ecfc510e4?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d9ecfc510e4</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 14 May 2026 00:00:51 GMT</pubDate>
            <atom:updated>2026-05-30T20:48:24.872Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PaWPXhH4_RRZaIo_" /><figcaption>Photo by <a href="https://unsplash.com/@julianhochgesang?utm_source=medium&amp;utm_medium=referral">Julian Hochgesang</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Weighted load balancing has saved me more times than I can count.</p><p>Many engineers think of load balancers as simple traffic distributors.</p><p>Send requests across servers. Keep systems available. Move on.</p><p>But one of their most valuable capabilities is often overlooked. Weighted load balancing.</p><h3>🤨 What Is Weighted Load Balancing?</h3><p>From enterprise hardware appliances to software load balancers like HAProxy and Envoy Proxy, nearly all modern load balancers support some form of weighted routing.</p><p>Start with a standard balancing algorithm, such as round-robin. Then apply weights so some targets receive more traffic than others.</p><p>For example, if two targets are weighted at 90 and 10, roughly 90% of traffic goes to one target and 10% to the other. If targets have equal weights, traffic is typically distributed evenly.</p><p>Simple idea, critical feature.</p><h3>🤔 Why It Matters</h3><p>Weighted load balancing turns migrations from risky big-bang cutovers into small, adjustable dials.</p><p>Instead of flipping traffic all at once, you can gradually shift production traffic while observing behavior in real time.</p><p>That means a smaller blast radius, easier rollbacks, and safer production migrations.</p><h3>🧰 What I Actually Use It For</h3><p>I’ve rarely used weighted load balancing because one server had more capacity than another.</p><p>What I’ve used it for repeatedly is change management.</p><p>Ten years ago, to migrate from a legacy file transfer platform to newer platforms. We used weighted load balancing to introduce the new platform gradually.</p><p>Six years ago, to control which transactions were routed to our old card payments platform versus the new platform, we introduced weighted load balancing in our global transaction router.</p><p>Last night, to run a canary deployment, we adjusted our service mesh using weighted routing via xDS.</p><p>Different eras, different platforms, same core concept.</p><h3>🕰️ Standing the Test of Time</h3><p>Weighted load balancing is not new. It has existed for a long time.</p><p>Foundational patterns often become the enablers for newer platform practices. Canary releases, blue/green deployments, service mesh traffic shifting.</p><p>Many of those ideas rely on the same underlying capability: <strong>controlling traffic through percentages and weighting.</strong></p><p>Good patterns tend to survive generations of technology.</p><h3>🧠 Final Thoughts</h3><p>Many software engineers will never build a load balancer. They will never configure one themselves.</p><p>But understanding what these systems can do is still an advantage.</p><p>Because migrations are often less about code and more about traffic control.</p><p>Writing good software isn’t enough. Knowing when and how to shift 1% of traffic can make or break a migration.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-05-14/"><em>https://bencane.com</em></a><em> on May 14, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d9ecfc510e4" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/weighted-load-balancing-has-saved-me-more-times-than-i-can-count-2d9ecfc510e4">Weighted load balancing has saved me more times than I can count</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[YOLO Is a Terrible Strategy for Validating Production Changes]]></title>
            <link>https://itnext.io/yolo-is-a-terrible-strategy-for-validating-production-changes-a157369a0382?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/a157369a0382</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 07 May 2026 00:00:17 GMT</pubDate>
            <atom:updated>2026-05-15T22:06:58.775Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*OESeq5QAldRa4xuf" /><figcaption>Photo by <a href="https://unsplash.com/@bijesh33?utm_source=medium&amp;utm_medium=referral">bijesh regmi</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>YOLO is a terrible strategy for validating production changes.</p><p>How many times have you seen it?</p><p>Your platform is running smoothly. No alerts, no issues. Then suddenly, something breaks.</p><p>After digging in, you discover the cause: another system you depend on made a change, and that change broke your platform.</p><p>They didn’t notice it broke. You did, much too late…</p><p>How many times have you been the cause of another platform breaking?</p><h3>🥶 Cold Reality</h3><p>I wish the above scenario were rare, but it happens constantly across the technology industry.</p><p>It happens between internal teams, third-party integrations, and shared infrastructure teams.</p><p>These scenarios make you wonder, “How was that change validated?”</p><p>Maybe they tested it, and their validation had gaps. Maybe they did little validation at all. If any.</p><p>Either way, the result is the same: <strong>they validated their change with 100% of production traffic.</strong> Bad plan.</p><h3>💡 Better Ways to Validate Changes</h3><p>There are many ways teams can reduce production risk when rolling out changes, and the best teams combine the following approaches.</p><h3>Canary Releases 🐤</h3><p>I talk about canary deployments often.</p><p>Instead of moving 100% of traffic at once, move small percentages gradually and observe behavior closely.</p><p><strong>That observed part matters.</strong> Look at error rates, latency changes (beyond normal platform warmup), resource spikes, and unexpected retries. All of these indicate customer impact.</p><p>Canary deployments are one of the best ways to reduce the blast radius of changes, identify problems quickly, and self-correct.</p><h3>Shadow Traffic 🪞</h3><p>Traffic mirroring sends production traffic to a new version before routing live traffic there.</p><p>Responses are ignored, but you observe behavior and monitor the same signals you would with a canary release without sacrificing a customer request.</p><h3>Synthetic Traffic 🤖</h3><p>Synthetic traffic simulates user behavior continuously. It’s great for monitoring customer experience, but also a great way to validate new deployments.</p><p>Route synthetic traffic to upgraded instances first and verify behavior before moving real traffic. If it fails with synthetic traffic, it likely won’t survive real traffic.</p><h3>Smoke Tests 😶‍🌫️</h3><p>The classic approach. After deployment, run a small set of fast tests to confirm the platform is fundamentally working.</p><p>Smoke tests don’t need to be fancy; they can be shell scripts, API calls, read-only requests, a test file, or full end-to-end validation.</p><p>Their purpose is simple: to quickly catch obvious breakage.</p><h3>🧠 Final Thoughts</h3><p>Don’t think of the above methods as mutually exclusive choices. Combine them.</p><p>Some platforms I work on combine canary releases, shadow traffic, and synthetic traffic. Others use smoke tests plus canary releases.</p><p>The more layers of validation you have, the more likely you are to catch issues before your customers do. Because having your customers validate changes for you is a poor strategy.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-05-07/"><em>https://bencane.com</em></a><em> on May 7, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a157369a0382" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/yolo-is-a-terrible-strategy-for-validating-production-changes-a157369a0382">YOLO Is a Terrible Strategy for Validating Production Changes</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deterministic routing is one of the most effective ways distributed systems reduce consistency…]]></title>
            <link>https://itnext.io/deterministic-routing-is-one-of-the-most-effective-ways-distributed-systems-reduce-consistency-d60634c9d481?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/d60634c9d481</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[coding]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 30 Apr 2026 00:00:44 GMT</pubDate>
            <atom:updated>2026-05-09T17:57:08.608Z</atom:updated>
            <content:encoded><![CDATA[<h3>Deterministic routing is one of the most effective ways distributed systems reduce consistency problems at scale</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*D-jUadmu1JhfeJnl" /><figcaption>Photo by <a href="https://unsplash.com/@vonshnauzer?utm_source=medium&amp;utm_medium=referral">Egor Myznik</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Deterministic routing is one of the most effective ways distributed systems reduce consistency problems at scale.</p><p>It is a foundational technique used by many modern databases, caches, and large-scale platforms. Understand how it works and you can apply the same pattern in your own systems.</p><h3>🤔 Understanding the Problem</h3><p>At some point, every successful system hits the limits of a single database instance.</p><p>A single server can only handle so many connections, queries, writes, storage capacity, or CPU/memory demands. Even with the best hardware, performance eventually degrades. So systems scale horizontally.</p><p>Instead of sending all traffic to a single database server, requests are distributed across multiple nodes.</p><p>At the same time, resiliency matters. If one server fails and all data resides there, the outage can be severe.</p><p>So modern databases spread data across multiple nodes, availability zones, and regions.</p><p>Distributing load and data solves both capacity and resiliency problems. But it introduces another challenge.</p><p>How do you keep request behavior consistent when data is distributed across multiple systems?</p><h3>⚠️ Why Replication Is Not Enough</h3><p>Replication helps, but it does not solve every consistency problem.</p><p>Imagine a write lands on Server 1. Immediately after, a read request for the same data lands on Server 67. Will Server 67 have the latest version? Maybe, but often not.</p><h3>Asynchronous Replication</h3><p>With asynchronous replication, Server 1 will accept the write and replicate the data to other servers in the background. That means a follow-up read on any other node may return stale data.</p><h3>Synchronous Replication</h3><p>With synchronous replication, the write on Server 1 will wait for an acknowledgment from all replicas before returning a success. While this improves consistency guarantees, it increases latency.</p><p>The farther apart a replica is, the worse this gets. Local writes may be fast, but cross-region writes will be slow. Plus, is it really feasible to replicate data across every single node?</p><p>So the question becomes: <em>How do you preserve consistency, without paying latency taxes?</em></p><h3>🔀 Route Requests to the Data</h3><p>A highly effective answer is deterministic routing.</p><p>Instead of moving data to where requests might land, move requests to where the data already exists.</p><p>If requests for the same key can go to the same node, you gain predictable ownership, reduced stale reads, lower coordination overhead, and easier horizontal scaling.</p><h3>👨‍🏫 How Deterministic Routing Works</h3><p>At a high level, the system needs a repeatable way to decide where requests should go.</p><p>A common approach is hashing.</p><ul><li>A hash of user123 always goes to Node 7</li><li>A hash of user456 always goes to Node 42</li></ul><p>As long as the same key produces the same result, requests can be consistently routed to the same owner. Many modern databases implement deterministic routing through techniques like consistent hashing, partition maps, and shard ranges.</p><h3>🗺️ Where Routing Logic Lives</h3><p>Different systems solve routing in different places.</p><h3>Client-side Routing</h3><p>The client library knows the partition map and sends requests directly to the correct node. Used by many distributed caches and databases.</p><h3>Proxy / Router Tier</h3><p>A small router sits in front of nodes and forwards traffic appropriately. Useful when client behavior cannot be influenced.</p><h3>Server-side Forwarding</h3><p>Requests land anywhere, and the receiving node forwards internally to the owning node. Simple for clients, doesn’t introduce a proxy failure point, but introduces complex cluster discovery/health monitoring.</p><p>Each model has tradeoffs.</p><h3>🧰 Routing Does Not Replace Replication</h3><p>Deterministic routing is powerful, but not magic. What happens when the owning node is down? You still need replication.</p><p>Modern databases combine both: deterministic routing for performance and ownership, plus replication for durability and failover.</p><h3>🧠 Why This Matters Beyond Databases</h3><p>Distributed databases use this approach, but it is not unique to them.</p><p>Deterministic routing can be used to solve: session ownership, user affinity, in-memory workflow coordination, work queue partitioning, and more.</p><p>I’ve used deterministic routing many times to solve load distribution and consistency problems.</p><p>At scale, the answer is not always more/better hardware. Consistency and availability problems are not always solved with replication alone.</p><p>Sometimes the best answer is simply to send the request to the right place.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-04-30/"><em>https://bencane.com</em></a><em> on April 30, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d60634c9d481" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/deterministic-routing-is-one-of-the-most-effective-ways-distributed-systems-reduce-consistency-d60634c9d481">Deterministic routing is one of the most effective ways distributed systems reduce consistency…</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[When you think of microservices, you probably think of centralized shared services]]></title>
            <link>https://itnext.io/when-you-think-of-microservices-you-probably-think-of-centralized-shared-services-0c174b377b63?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/0c174b377b63</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 23 Apr 2026 00:00:27 GMT</pubDate>
            <atom:updated>2026-05-09T17:57:43.245Z</atom:updated>
            <content:encoded><![CDATA[<h3>When you think of microservices, you probably think of centralized shared services. But there’s another valid pattern that is rarely discussed</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qdVIzY9gGt7q9Qpk" /><figcaption>Photo by <a href="https://unsplash.com/@framesforyourheart?utm_source=medium&amp;utm_medium=referral">Frames For Your Heart</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>When you think of microservices, you probably think of centralized shared services. But there’s another valid pattern that is rarely discussed: running the same microservice inside multiple platforms.</p><h3>🧩 How It Usually Works</h3><p>Most microservice designs follow the same model:</p><ul><li>Break systems into capabilities, teams, or functions</li><li>Deploy one shared service for each capability</li><li>Any platform that needs it calls that centralized service</li></ul><p>That works well for many cases, but it’s not the only model.</p><h3>🏗️ How We Got Here</h3><p>Before microservices, many organizations used Service-Oriented Architecture (SOA).</p><p>Despite being labeled as antiquated, SOA and microservices are not that different. Both break down systems into capabilities that communicate with each other. The biggest difference is scope.</p><p>In SOA, a “Payments Service” might own:</p><ul><li>Message parsing</li><li>Validation</li><li>Balance checks</li><li>Currency conversion</li><li>Settlement logic</li></ul><p>While other SOA services would own “Users” or “Accounting”. Today, that payment service would be considered an entire platform, with each of those capabilities implemented as microservices within that domain.</p><p>Microservices are often the same idea as SOA, just at a more granular level.</p><h3>🎯 Why Centralization Became the Default</h3><p>One reason microservices gained traction was the need to avoid duplication. Capabilities were often rebuilt across multiple systems. For example, Currency Conversion is needed in Payments, Accounting, and many other platforms.</p><p>Duplication is not just wasteful, it creates real problems: logic drift, coordination overhead, and inconsistent outcomes across systems. Packaging that capability as a standalone service solved real problems: build once, reuse everywhere.</p><h3>⚠️ The Downside of Centralization</h3><p>In cell-based architectures, platforms are usually designed to be self-contained and failure-isolated. That means a mission-critical platform depending on a centralized service shared by other platforms can become a design smell.</p><ul><li>Cross-cell dependencies</li><li>Added latency</li><li>Shared failure domains</li><li>Complex failover scenarios</li></ul><p>So teams, once again, solve these problems by rebuilding the same capability locally.</p><h3>🔁 Another Option</h3><p>Instead of rebuilding the capability each time, deploy the same microservice codebase inside multiple platforms. If both Payments and Accounting need a currency conversion service, deploy the same service within each platform.</p><p>It’s the same codebase and capability, but with local ownership and resilience. You get reuse without forced centralization.</p><h3>🧪 Caveats from Experience</h3><p>This pattern works when applied carefully.</p><h4>1️⃣ Strong Ownership</h4><p>A shared codebase still needs a clear owning team. Others can contribute, but someone must own quality, roadmap, and releases.</p><h4>2️⃣ Pick the Right Capabilities</h4><p>Not everything is a great fit. Something like currency conversion is well-scoped, relatively stateless, and doesn’t have unique business logic based on which platform is calling it. It’s a strong example.</p><p>But other services that have unique logic for each platform domain or require consistency across different platforms are less of a fit.</p><h4>3️⃣ Operational Discipline</h4><p>Using the same codebase doesn’t automatically solve all problems; you can still run into drift across platforms if each is running a different version. Changes in behavior still sometimes need coordination.</p><p>But with a single codebase, these issues are far easier to address.</p><h3>💭 Final Thoughts</h3><p>Microservices gave us reusable building blocks. Sometimes the best use of a microservice is not one centralized deployment. Sometimes it’s many local deployments of the same capability.</p><p>Just reuse the software while maintaining autonomy.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-04-23/"><em>https://bencane.com</em></a><em> on April 23, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0c174b377b63" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/when-you-think-of-microservices-you-probably-think-of-centralized-shared-services-0c174b377b63">When you think of microservices, you probably think of centralized shared services</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Are you using traffic mirroring in production? If not, try it out]]></title>
            <link>https://itnext.io/are-you-using-traffic-mirroring-in-production-if-not-try-it-out-e5ca3d926975?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/e5ca3d926975</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 16 Apr 2026 00:00:59 GMT</pubDate>
            <atom:updated>2026-04-26T19:38:10.074Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Hc6-_hA0orG6TH_8" /><figcaption>Photo by <a href="https://unsplash.com/@rishabhdharmani?utm_source=medium&amp;utm_medium=referral">Rishabh Dharmani</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Are you using traffic mirroring in production? If not, you might be missing one of the safest ways to test and observe production changes.</p><h3>🚦 What is Traffic Mirroring?</h3><p>Traffic mirroring in Istio or Envoy Proxy lets you send a copy of live traffic to a secondary target.</p><p>When enabled, traffic to /service routes to cluster1 as normal, and a mirrored copy is sent to cluster2.</p><p><strong>The key:</strong> mirrored traffic is fire-and-forget. Responses are ignored and never impact the primary request.</p><h3>🧪 Why It’s Powerful</h3><h4>1️⃣ Shadow Traffic for Safe Testing</h4><p>The most common use case is shadow traffic.</p><p>When migrating platforms or deploying a new version of an application, you can send real traffic to the new system, observe behavior, and validate responses.</p><p>All without impacting users. No risky cutovers. You see exactly how the new system behaves under real load.</p><h4>2️⃣ Out-of-Band Traffic Inspection</h4><p>Another powerful use case is traffic inspection.</p><p>Inline inspection is risky. It adds latency, introduces new failure points, and becomes part of the critical path.</p><p>With traffic mirroring, you can inspect traffic, analyze requests, and detect anomalies.</p><p>All without impacting the primary path.</p><h3>😶‍🌫️ Reality Check</h3><p>It’s not perfect. There is some overhead.</p><p>Mirroring adds load to the sidecar, which may or may not be acceptable for your system. In my experience, it’s negligible, but it’s something you should measure in your own environment before deploying to production.</p><h3>🧠 Final Thoughts</h3><p>Traffic mirroring is one of the safest ways to validate migrations, test new systems, and observe real production behavior.</p><p>The hard part isn’t mirroring traffic. It’s running two production systems in parallel. That’s the real cost, and the real tradeoff.</p><p>But if you can afford that cost, traffic mirroring is an incredibly powerful tool.</p><p>If you want to dig deeper:</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-04-16/"><em>https://bencane.com</em></a><em> on April 16, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e5ca3d926975" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/are-you-using-traffic-mirroring-in-production-if-not-try-it-out-e5ca3d926975">Are you using traffic mirroring in production? If not, try it out</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agent Skills Are Becoming the Best Way to Capture Institutional Knowledge]]></title>
            <link>https://itnext.io/agent-skills-are-becoming-the-best-way-to-capture-institutional-knowledge-1458b36b4124?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/1458b36b4124</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[coding]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 09 Apr 2026 00:00:55 GMT</pubDate>
            <atom:updated>2026-04-17T21:17:06.311Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*D5khO4oyFs6to0UK" /><figcaption>Photo by <a href="https://unsplash.com/@opernfan17x?utm_source=medium&amp;utm_medium=referral">Rainhard Wiesinger</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Use Agent Skills to capture institutional knowledge and make it usable by coding agents.</p><p>Every organization has institutional knowledge.</p><ul><li>Internal frameworks</li><li>Preferred practices</li><li>Platform-specific capabilities</li></ul><p>It exists everywhere. But it’s often undocumented… or buried in a wiki no one reads.</p><p>As coding agents take on more work, this problem gets worse.</p><p>If you ask an agent to build a new service, you want it to use your internal framework, follow your patterns, and respect your organizational constraints.</p><p>A human engineer would ask questions. An agent won’t, unless you give it that context.</p><h3>📚 Agent Skills as Knowledge Distribution</h3><p>Most people think about Agent Skills as actions:</p><ul><li>Convert markdown to PDF</li><li>Review this pull request</li><li>Commit my changes</li></ul><p>But the more interesting use case is guidance.</p><p>Skills aren’t just for doing things. They’re for shaping agent output.</p><p>Agents discover and use skills based on intent.</p><p>If a user asks: “Create a new Python service.”</p><p>The agent looks for relevant skills:</p><ul><li>Language conventions (PEP 8, etc.)</li><li>Internal frameworks</li><li>Organizational standards</li></ul><p>That’s where institutional knowledge belongs.</p><p>Instead of hoping engineers remember to tell the agent:</p><ul><li>“We use Flask, not Django.”</li><li>“Stick to the standard library.”</li><li>“Follow this service layout.”</li></ul><p>You capture that into a skill. The agent applies it automatically.</p><h3>🧠 Why This Matters</h3><p>Institutional knowledge only works if it’s:</p><ul><li>Discoverable</li><li>Applied consistently</li></ul><p>Agent Skills give you both.</p><p>They turn tribal knowledge into something agents can find, understand, and use.</p><h3>⚠️ The Tradeoff (For Now)</h3><p>Right now, this introduces duplication.</p><p>Most teams already have internal docs, style guides, &amp; wikis.</p><p>And now you’re putting the same information into skills. Which feels like extra work.</p><p>But it poses an interesting question:</p><p>As agents become the primary interface… Will engineers read the wiki? Or ask the agent?</p><h3>🧠 Final Thoughts</h3><p>As agents take on more of the implementation work, where you store knowledge becomes more important. Making that knowledge accessible to agents becomes essential.</p><p>Agent Skills aren’t just automation tools.</p><p>They are becoming the interface for standards, practices, and institutional knowledge.</p><p>And teams that embrace that early will see more consistent output from both humans and agents.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-04-09/"><em>https://bencane.com</em></a><em> on April 9, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1458b36b4124" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/agent-skills-are-becoming-the-best-way-to-capture-institutional-knowledge-1458b36b4124">Agent Skills Are Becoming the Best Way to Capture Institutional Knowledge</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Saved Prompts Are Dead. Agent Skills Are the Future]]></title>
            <link>https://itnext.io/saved-prompts-are-dead-agent-skills-are-the-future-7815f23f5183?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/7815f23f5183</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[agentic-development]]></category>
            <category><![CDATA[coding]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 02 Apr 2026 00:00:45 GMT</pubDate>
            <atom:updated>2026-04-11T20:09:22.812Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*n5z8ao_FdG16F5aQ" /><figcaption>Photo by <a href="https://unsplash.com/@onurbuz?utm_source=medium&amp;utm_medium=referral">Onur Buz</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Saved prompts are dead. Agent Skills are the next step.</p><p>If you’ve been around for a while, you probably have a file full of bash one-liners.</p><p>Small scripts or commands you saved because they solved a problem you didn’t want to automate properly.</p><p>When coding agents arrived, prompts became the new one-liners.</p><p>Useful prompts were saved, reused, and eventually turned into “prompt files”, then slash commands like /do-something.</p><p>But that model has already evolved.</p><h3>⚙️ Agent Skills</h3><p>Agent Skills are the next iteration.</p><p>At a basic level, a skill looks a lot like a saved prompt: a directory with a markdown file.</p><p>What makes it different is how it’s used.</p><p>Skills include metadata like name and description, allowing agents to discover them.</p><p>Instead of explicitly calling a prompt every time, the agent can determine when to use a skill based on intent.</p><p>This is referred to as progressive disclosure:</p><ul><li>Agent loads skill metadata</li><li>Matches it to your task</li><li>Then loads and executes the full skill when needed</li></ul><p>You can still call skills directly (/, $, @), but you don&#39;t always have to.</p><h3>🧠 More Than Just Prompts</h3><p>The real differentiator is that skills aren’t just prompts.</p><p>They can include reference documentation, templates, and scripts.</p><p>This means you’re no longer just telling the agent what to do.</p><p>You’re giving it tools and context to execute and validate tasks.</p><p>For more complex workflows, it’s often easier to write a script and teach the agent how to use it than to encode everything in a prompt.</p><h3>⚠️ A Word of Caution</h3><p>This power comes with risk.</p><p>Skills can include executable logic and tell agents to perform tasks.</p><p>That means a shared skill can contain malicious or unsafe behavior.</p><p>Treat them like any script you install:</p><ul><li>Understand what they do</li><li>Know where they come from</li><li>Review before using (watch out for hidden text or obfuscated instructions)</li></ul><h3>🧠 Final Thoughts</h3><p>Agent skills are a meaningful step forward.</p><p>They let you codify workflows, preferences, and repeatable agent tasks in a way that agents can discover.</p><p>They’re a strong productivity accelerator and a powerful way to capture institutional knowledge in a form agents can actually use.</p><p>(More on that in the next post.)</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-04-02/"><em>https://bencane.com</em></a><em> on April 2, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7815f23f5183" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/saved-prompts-are-dead-agent-skills-are-the-future-7815f23f5183">Saved Prompts Are Dead. Agent Skills Are the Future</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Generating Code Faster Is Only Valuable If You Can Validate Every Change With Confidence]]></title>
            <link>https://itnext.io/generating-code-faster-is-only-valuable-if-you-can-validate-every-change-with-confidence-5148a37c2320?source=rss-96013faddf78------2</link>
            <guid isPermaLink="false">https://medium.com/p/5148a37c2320</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Benjamin Cane]]></dc:creator>
            <pubDate>Thu, 26 Mar 2026 00:00:28 GMT</pubDate>
            <atom:updated>2026-04-03T20:26:53.854Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*thcsa3J0HrkMymmk" /><figcaption>Photo by <a href="https://unsplash.com/@alexkondratiev?utm_source=medium&amp;utm_medium=referral">Alex</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Generating code faster is only valuable if you can validate every change with confidence.</p><p>Software engineering has never really been about writing code. Coding is often the easy part.</p><p>Testing is harder, and many teams struggle with it.</p><p>As tools make it easier to generate code quickly, that gap widens. If you can produce changes faster than you can validate them, you eventually create more code than you can safely operate.</p><p>Which begs the question: What does good testing actually look like?</p><h3>🔍 What Good Looks Like</h3><p>One of the biggest challenges I see is that teams struggle to understand what “good” testing means and never define it.</p><p>Pipelines are often built early in a project, when the team is small, and they rarely keep pace with the system and organization as they grow.</p><p>My starting principle is simple:</p><ul><li>At pull request time, you should have strong confidence that the change will not break the service or platform being modified.</li><li>Within a day of merging, you should have strong confidence that the change hasn’t broken the full customer journey that the platform supports.</li></ul><h3>🔁 On Pull Request</h3><p>For backend platforms, I like to see three levels of automated testing before merging.</p><h3>Code Tests (Unit Tests)</h3><p>This level is the foundation. Unit tests validate internal logic, error handling, and edge cases. Techniques such as fuzz testing and benchmarking also reveal issues early. As the test pyramid tells us, this is where the majority of testing and logic validation should take place.</p><h3>Service-Level Functional Tests</h3><p>Too many teams stop at unit tests for pull requests. Functional tests should also be run in CI for every pull request.</p><p>Services should be tested in isolation with functional tests. Dependencies can be mocked, but things like databases should ideally run for real (Dockerized).</p><p>This is where API contracts are validated and regressions can be identified without wondering whether the issue came from this change or another service.</p><h3>Platform-Level Functional Tests</h3><p>Testing a service alone isn’t enough. Changes can break upstream or downstream dependencies. Platform-level tests spin up the entire platform in CI and validate that services interact correctly.</p><p>These tests ensure the platform continues to work as a system.</p><p>For platforms with strict latency or resiliency requirements, I recommend introducing light stress tests at both the service and platform levels. These aren’t full performance tests, but they act as early indicators of performance regressions.</p><p>If these three layers pass, you should have high confidence in the change. But not complete confidence.</p><h3>🌙 Nightly Testing</h3><p>Some failures take time to appear.</p><p>Memory leaks, performance degradation, and cross-platform integration issues may not show up immediately.</p><p>That’s why I like to run a nightly build (or every few hours).</p><p>This environment runs end-to-end customer journey tests, performance tests, and chaos tests.</p><p>These are typically the same tests used during release validation, but running them continuously accelerates feedback. If something breaks, you learn about it early, before the pressure of a release.</p><h3>🧠 Final Thoughts</h3><p>There is no universal approach everyone can follow.</p><p>Different systems have different needs; mission-critical systems may focus heavily on correctness and resilience. Non-mission-critical systems may focus more on validating core functionality.</p><p>Your testing strategy depends heavily on architecture, dependencies, and operational constraints. But if your organization is increasing its ability to generate code quickly, your testing capabilities must evolve at the same pace.</p><p>AI-generated code becomes much easier to review when you already have high confidence in your testing.</p><p><em>Originally published at </em><a href="https://bencane.com/posts/2026-03-26/"><em>https://bencane.com</em></a><em> on March 26, 2026.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5148a37c2320" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/generating-code-faster-is-only-valuable-if-you-can-validate-every-change-with-confidence-5148a37c2320">Generating Code Faster Is Only Valuable If You Can Validate Every Change With Confidence</a> was originally published in <a href="https://itnext.io">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>