<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Microservices on</title><link>/tags/microservices/</link><description>Recent content in Microservices on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 18 Jun 2025 00:00:00 +0000</lastBuildDate><atom:link href="/tags/microservices/index.xml" rel="self" type="application/rss+xml"/><item><title>Lesson 6: API Gateway Patterns — One entry point, many backends</title><link>/post/go/go-micro-api-gateway/</link><pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate><guid>/post/go/go-micro-api-gateway/</guid><description>&lt;p&gt;The first time I connected a mobile frontend directly to 11 microservices, I created 11 places for the mobile team to integrate, 11 different auth schemes to understand, 11 different error formats to handle, and a situation where a single product screen required 6 parallel API calls because the data was spread across 6 services. An API gateway solves all of this: one URL, one auth scheme, one error format, and the ability to aggregate multiple service responses into a single response the client actually needs.&lt;/p&gt;</description></item><item><title>Lesson 8: Monolith-First — Modular monoliths in Rust</title><link>/post/rust/rust-micro-monolith-first/</link><pubDate>Tue, 17 Jun 2025 13:19:00 +0000</pubDate><guid>/post/rust/rust-micro-monolith-first/</guid><description>&lt;p&gt;I&amp;rsquo;m going to tell you something that might sound weird after seven lessons about microservices patterns: don&amp;rsquo;t start with microservices. Start with a monolith. A well-structured, modular monolith that&amp;rsquo;s &lt;em&gt;designed&lt;/em&gt; to be split later.&lt;/p&gt;
&lt;p&gt;This isn&amp;rsquo;t contrarianism for its own sake. I&amp;rsquo;ve seen three teams build microservices from day one. All three regretted it. One team spent more time debugging distributed system issues than building features. Another had seven services that each handled about 50 requests per day — the infrastructure cost was absurd. The third discovered six months in that they&amp;rsquo;d drawn their service boundaries wrong and had to do a painful re-architecture.&lt;/p&gt;</description></item><item><title>Lesson 7: Testing Microservices — Contract tests and integration</title><link>/post/rust/rust-micro-testing/</link><pubDate>Sat, 14 Jun 2025 07:33:00 +0000</pubDate><guid>/post/rust/rust-micro-testing/</guid><description>&lt;p&gt;I deployed a change to the order service that renamed a field from &lt;code&gt;total_amount&lt;/code&gt; to &lt;code&gt;total_cents&lt;/code&gt;. Made perfect sense — cents avoid floating-point nonsense. All unit tests passed. Integration tests passed. Staging looked fine.&lt;/p&gt;
&lt;p&gt;Production broke instantly. The payment service was still expecting &lt;code&gt;total_amount&lt;/code&gt;. It deserialized the response, got &lt;code&gt;None&lt;/code&gt; for the amount, and started processing $0 charges. We caught it in four minutes, but four minutes of free orders adds up.&lt;/p&gt;</description></item><item><title>Lesson 6: Distributed Tracing Across Services — Following requests</title><link>/post/rust/rust-micro-tracing/</link><pubDate>Wed, 11 Jun 2025 10:45:00 +0000</pubDate><guid>/post/rust/rust-micro-tracing/</guid><description>&lt;p&gt;&amp;ldquo;It&amp;rsquo;s slow&amp;rdquo; is the most useless bug report in a microservices world. Slow where? The API gateway? The order service? The database query inside the payment service? The message queue between inventory and shipping? When a single user action touches five services and three databases, &amp;ldquo;it&amp;rsquo;s slow&amp;rdquo; could mean anything.&lt;/p&gt;
&lt;p&gt;I spent an entire afternoon once trying to track down a latency spike. Added timing logs to every service. Correlated timestamps across hosts. Manually stitched together the request flow from six different log streams. Found the culprit: a DNS resolution that was taking 800ms because of a misconfigured resolver — in a service I didn&amp;rsquo;t even know was involved.&lt;/p&gt;</description></item><item><title>Lesson 5: Service Mesh Integration — Istio, Linkerd, and Rust</title><link>/post/rust/rust-micro-service-mesh/</link><pubDate>Mon, 09 Jun 2025 16:21:00 +0000</pubDate><guid>/post/rust/rust-micro-service-mesh/</guid><description>&lt;p&gt;I&amp;rsquo;ll be honest — when someone first pitched &amp;ldquo;service mesh&amp;rdquo; to me, I thought it was over-engineered marketing. You&amp;rsquo;re telling me I need a sidecar proxy bolted onto every pod, a control plane to manage those proxies, and custom CRDs to configure traffic routing&amp;hellip; just to do what a load balancer and some retry logic could handle?&lt;/p&gt;
&lt;p&gt;Then I ran a fleet of 20+ services in production. mTLS between everything? Doing that in application code is painful. Per-route retry policies? Circuit breaking with consistent configuration? Gradual traffic shifting for canary deploys? At that scale, doing it all in app code means doing it differently in every service, with different bugs in each implementation.&lt;/p&gt;</description></item><item><title>Lesson 4: Saga Pattern — Distributed transactions without 2PC</title><link>/post/rust/rust-micro-saga/</link><pubDate>Sat, 07 Jun 2025 08:48:00 +0000</pubDate><guid>/post/rust/rust-micro-saga/</guid><description>&lt;p&gt;Here&amp;rsquo;s a scenario that&amp;rsquo;ll ruin your week. A customer places an order. Your order service saves it. Your payment service charges their card. Your inventory service reserves the items. Your shipping service schedules a pickup. Then the shipping service discovers the item is oversized and can&amp;rsquo;t be shipped to that address.&lt;/p&gt;
&lt;p&gt;Now what? The card&amp;rsquo;s been charged. The inventory&amp;rsquo;s been reserved. The order exists. You need to undo three things across three services, each with their own database, each with their own failure modes. Welcome to distributed transactions.&lt;/p&gt;</description></item><item><title>Lesson 3: Event-Driven Architecture in Rust — Decoupled systems</title><link>/post/rust/rust-micro-event-driven/</link><pubDate>Thu, 05 Jun 2025 11:02:00 +0000</pubDate><guid>/post/rust/rust-micro-event-driven/</guid><description>&lt;p&gt;The worst production incident I ever dealt with was a cascading failure triggered by a single slow database query. Service A called Service B synchronously, which called Service C, which ran a query that usually took 2ms but on that particular Tuesday took 45 seconds because of a missing index on a new column. Service A&amp;rsquo;s thread pool exhausted, its health check failed, Kubernetes restarted it, and for twenty minutes the entire checkout flow was down — because of a read query in a recommendation engine.&lt;/p&gt;</description></item><item><title>Lesson 2: gRPC Microservices with tonic — Production-grade RPC</title><link>/post/rust/rust-micro-grpc-services/</link><pubDate>Tue, 03 Jun 2025 14:37:00 +0000</pubDate><guid>/post/rust/rust-micro-grpc-services/</guid><description>&lt;p&gt;The first time I used gRPC in production was on a Go project. The experience was fine — &lt;code&gt;protoc&lt;/code&gt; generated stubs, you implemented an interface, done. Then I tried &lt;code&gt;tonic&lt;/code&gt; in Rust, and I realized what gRPC was &lt;em&gt;supposed&lt;/em&gt; to feel like. Type-safe request/response types generated at compile time, streaming that works with Rust&amp;rsquo;s async model, and interceptors built on the same Tower middleware stack as Axum. It&amp;rsquo;s gRPC done right.&lt;/p&gt;</description></item><item><title>Lesson 1: Service Boundaries and API Contracts — Where to draw the lines</title><link>/post/rust/rust-micro-service-design/</link><pubDate>Sun, 01 Jun 2025 09:14:00 +0000</pubDate><guid>/post/rust/rust-micro-service-design/</guid><description>&lt;p&gt;I once joined a team that had 47 microservices for what was essentially a CRUD app with a payment flow. Forty-seven. Each one had its own database, its own deployment pipeline, its own on-call rotation. When a customer placed an order, the request bounced through eleven services before a confirmation email went out. Latency was terrible, debugging was a nightmare, and nobody could explain why the &amp;ldquo;UserPreferences&amp;rdquo; service existed separately from the &amp;ldquo;UserProfile&amp;rdquo; service.&lt;/p&gt;</description></item><item><title>Lesson 5: Saga Pattern — Distributed transactions without two-phase commit</title><link>/post/go/go-micro-sagas/</link><pubDate>Fri, 18 Apr 2025 00:00:00 +0000</pubDate><guid>/post/go/go-micro-sagas/</guid><description>&lt;p&gt;Two-phase commit is theoretically elegant and operationally painful. I&amp;rsquo;ve seen it cause system-wide deadlocks during network partitions, coordinator failures that required manual database recovery, and deployment coupling so tight that every service had to be upgraded in lockstep. The saga pattern is the alternative — it trades atomicity for availability, compensates for failures with explicit rollback actions, and keeps each service&amp;rsquo;s transactions entirely local. It&amp;rsquo;s the pattern I reach for whenever I need &amp;ldquo;all of this must succeed together&amp;rdquo; across more than one database.&lt;/p&gt;</description></item><item><title>Lesson 4: Distributed Tracing — Follow the request across 5 services</title><link>/post/go/go-micro-tracing/</link><pubDate>Tue, 28 Jan 2025 00:00:00 +0000</pubDate><guid>/post/go/go-micro-tracing/</guid><description>&lt;p&gt;Debugging a microservices system with only logs is like debugging a multi-threaded program with only print statements — possible, but painful in ways that are entirely avoidable. The first time I had to trace a slow request through six services using log grep, I understood why distributed tracing exists. An hour of log correlation that should have been a 10-second click on a flame chart. Distributed tracing gives you that flame chart.&lt;/p&gt;</description></item><item><title>Lesson 3: Service Discovery — Finding services without hardcoding URLs</title><link>/post/go/go-micro-discovery/</link><pubDate>Wed, 06 Nov 2024 00:00:00 +0000</pubDate><guid>/post/go/go-micro-discovery/</guid><description>&lt;p&gt;When I first started building Go microservices, every service had a config file with a list of URLs. &lt;code&gt;order-service-url: http://10.0.1.42:8080&lt;/code&gt;. That worked fine until the service moved, scaled out, or the IP changed during a deployment. Then the deployment would fail, someone would update the config, redeploy, and we&amp;rsquo;d write a Jira ticket to &amp;ldquo;fix the discovery mechanism eventually.&amp;rdquo; Service discovery is that fix — it&amp;rsquo;s how services find each other without hardcoding network locations.&lt;/p&gt;</description></item><item><title>Lesson 2: Inter-Service Communication — HTTP, gRPC, or events? It depends on the coupling.</title><link>/post/go/go-micro-communication/</link><pubDate>Tue, 10 Sep 2024 00:00:00 +0000</pubDate><guid>/post/go/go-micro-communication/</guid><description>&lt;p&gt;Every time I&amp;rsquo;ve seen a team choose their inter-service communication protocol by default — &amp;ldquo;we&amp;rsquo;ll use REST for everything&amp;rdquo; or &amp;ldquo;we&amp;rsquo;re going gRPC-native&amp;rdquo; — they&amp;rsquo;ve ended up with a transport mechanism that fights against some of their use cases. The choice between HTTP, gRPC, and event-driven messaging is a question about coupling: how tightly do these services need to be synchronized? The answer to that question selects your transport, not the other way around.&lt;/p&gt;</description></item><item><title>Lesson 1: Service Boundaries — Split by business capability, not by technical layer</title><link>/post/go/go-micro-boundaries/</link><pubDate>Sat, 06 Jul 2024 00:00:00 +0000</pubDate><guid>/post/go/go-micro-boundaries/</guid><description>&lt;p&gt;The most expensive architectural mistake I&amp;rsquo;ve seen teams make with microservices is splitting by technical layer instead of by business capability. I&amp;rsquo;ve seen systems with a &amp;ldquo;UserDataService,&amp;rdquo; a &amp;ldquo;UserLogicService,&amp;rdquo; and a &amp;ldquo;UserNotificationService&amp;rdquo; — three services that all have to be deployed together for any user-related feature to work, that share a database, and that call each other synchronously for every request. They&amp;rsquo;re not microservices; they&amp;rsquo;re a distributed monolith with extra network latency.&lt;/p&gt;</description></item></channel></rss>