<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog on SaaSForge</title><link>https://saasforge.cz/blog/</link><description>Recent content in Blog on SaaSForge</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 04 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://saasforge.cz/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Spring Modulith in Practice: From Code to Living Architecture Diagrams</title><link>https://saasforge.cz/blog/spring-modulith-c4-documentation/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/spring-modulith-c4-documentation/</guid><description>&lt;p&gt;Your architecture diagram in Confluence is six months stale. The one on the wiki still shows the Auth module that was merged into User back in January. The whiteboard in the meeting room? Someone erased it to draw a sprint retrospective.&lt;/p&gt;
&lt;p&gt;Architecture documentation has a fundamental problem: it&amp;rsquo;s maintained by humans, and humans forget. The code changes daily. The diagrams change when someone remembers. Eventually, the gap becomes so large that everyone stops trusting the diagrams and starts reading the code directly — which defeats the purpose of having diagrams at all.&lt;/p&gt;</description></item><item><title>Kamal vs Flux CD: Simplicity or Resilience — Pick One</title><link>https://saasforge.cz/blog/kamal-vs-flux-simplicity-or-resilience/</link><pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/kamal-vs-flux-simplicity-or-resilience/</guid><description>&lt;p&gt;Your container crashed at 3 AM. With Flux CD, the cluster noticed, restarted the pod, and reconciled the desired state from Git. You found out from a Slack notification over morning coffee. With Kamal — nobody noticed. Your app has been down for four hours. The first person to notice was a customer, and they didn&amp;rsquo;t file a bug report. They just left.&lt;/p&gt;
&lt;p&gt;This is the fundamental difference between Kamal and Flux CD, and it matters more than most &amp;ldquo;versus&amp;rdquo; articles admit. It&amp;rsquo;s not about which tool is &amp;ldquo;better.&amp;rdquo; It&amp;rsquo;s about whether your deployment tool is responsible for keeping your app running, or just for putting it there.&lt;/p&gt;</description></item><item><title>Spring Modulith in Practice: Enforcing Architecture in a Growing Monolith</title><link>https://saasforge.cz/blog/spring-modulith-in-practice/</link><pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/spring-modulith-in-practice/</guid><description>&lt;p&gt;Every growing Spring Boot application reaches a point where someone draws module boundaries on a whiteboard. Boxes with clean arrows. &amp;ldquo;Venue depends on Site but not on User internals.&amp;rdquo; Everyone nods. Two sprints later, a developer imports a repository from a module they shouldn&amp;rsquo;t depend on because it&amp;rsquo;s the fastest way to fix a bug. Nobody catches it in review. The whiteboard diagram is now fiction.&lt;/p&gt;
&lt;p&gt;Spring Modulith turns those whiteboard arrows into build failures.&lt;/p&gt;</description></item><item><title>Mise vs SDKMAN: Why I'm Switching After Years of .sdkmanrc</title><link>https://saasforge.cz/blog/mise-vs-sdkman/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/mise-vs-sdkman/</guid><description>&lt;p&gt;A colleague mentioned &lt;a href="https://mise.jdx.dev/"&gt;Mise&lt;/a&gt; today. I&amp;rsquo;ve been a loyal SDKMAN user for years — &lt;code&gt;.sdkmanrc&lt;/code&gt; in every project, &lt;code&gt;sdk use java 21.0.2-tem&lt;/code&gt; committed to muscle memory. It works, it&amp;rsquo;s reliable, I&amp;rsquo;ve never had a reason to look elsewhere.&lt;/p&gt;
&lt;p&gt;Then I actually looked at what Mise does, and I&amp;rsquo;m not sure I can go back.&lt;/p&gt;
&lt;h2 id="the-problem-with-one-tool-per-language"&gt;The Problem with One Tool per Language&lt;/h2&gt;
&lt;p&gt;SDKMAN manages JDKs (and Gradle, Maven, and a few other JVM tools). It does that well. But my projects don&amp;rsquo;t just need Java:&lt;/p&gt;</description></item><item><title>How We Use Claude Code Skills to Codify Our Development Patterns</title><link>https://saasforge.cz/blog/claude-code-skills-guide/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/claude-code-skills-guide/</guid><description>&lt;p&gt;Every codebase has patterns. The way you write tests, structure components, wire up APIs — these conventions live in your team&amp;rsquo;s collective memory, scattered across code reviews, onboarding docs, and tribal knowledge. When you bring an AI coding assistant into the mix, it doesn&amp;rsquo;t know any of this. It will write perfectly valid code that violates every convention you&amp;rsquo;ve established.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.anthropic.com/en/docs/claude-code/skills"&gt;Claude Code Skills&lt;/a&gt; solve this by letting you encode your patterns as reusable templates that Claude automatically picks up when the context is right.&lt;/p&gt;</description></item><item><title>Observing and Optimizing Your GraphQL API</title><link>https://saasforge.cz/blog/dgs-observing-optimizing-graphql/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/dgs-observing-optimizing-graphql/</guid><description>&lt;p&gt;&lt;em&gt;Part 7 of the &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; series — Bonus: Operations&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;GraphQL APIs are invisible to traditional monitoring. Every request hits the same &lt;code&gt;/graphql&lt;/code&gt; endpoint, returns HTTP 200 (even with errors in the body), and carries no URL-based context for your dashboards. If you monitor a GraphQL API the same way you monitor REST, you&amp;rsquo;re flying blind.&lt;/p&gt;
&lt;p&gt;This article covers the observability and optimization layer that sits above your DGS backend: &lt;strong&gt;federation with a GraphQL router&lt;/strong&gt;, &lt;strong&gt;client identification&lt;/strong&gt;, &lt;strong&gt;operation-level metrics&lt;/strong&gt;, &lt;strong&gt;error classification&lt;/strong&gt;, &lt;strong&gt;schema analytics&lt;/strong&gt;, and &lt;strong&gt;performance optimization techniques&lt;/strong&gt; that prevent your API from becoming a bottleneck.&lt;/p&gt;</description></item><item><title>Type-Safe GraphQL on the Frontend</title><link>https://saasforge.cz/blog/dgs-frontend-type-safety/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/dgs-frontend-type-safety/</guid><description>&lt;p&gt;&lt;em&gt;Part 6 of 7 in the &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; series — Bonus: The Client Side&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The previous five articles covered the backend: schema design, data loaders, security, subscriptions, and scaling. But type safety doesn&amp;rsquo;t stop at the API boundary. This article covers how to carry that safety all the way to the Vue (or React) component — and how fragment design prevents the silent performance killer that is overfetching.&lt;/p&gt;</description></item><item><title>DGS at Scale: Testing, Schema Evolution, and Federation</title><link>https://saasforge.cz/blog/dgs-at-scale/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/dgs-at-scale/</guid><description>&lt;p&gt;&lt;em&gt;Part 5 of 7 in the &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; series&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Building a GraphQL API is one thing. Running hundreds of operations in production, testing them reliably, and evolving the schema without breaking clients — that&amp;rsquo;s where the real engineering starts. This final article covers the practices that matter when your DGS API grows beyond a handful of queries.&lt;/p&gt;
&lt;h2 id="testing-dgs-components"&gt;Testing DGS Components&lt;/h2&gt;
&lt;p&gt;DGS data fetchers are Spring beans with injected dependencies. This makes them straightforward to unit test — mock the dependencies, call the method, assert the result.&lt;/p&gt;</description></item><item><title>Virtual Threads Did Not Kill WebFlux</title><link>https://saasforge.cz/blog/virtual-threads-vs-webflux/</link><pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/virtual-threads-vs-webflux/</guid><description>&lt;p&gt;Every few months, someone posts a benchmark showing that virtual threads handle 100,000 concurrent requests with simple imperative code, and concludes that WebFlux is obsolete. The comments fill with &amp;ldquo;finally, no more reactive spaghetti.&amp;rdquo; Managers forward the article to their teams: &amp;ldquo;Can we rewrite this in virtual threads?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;No. Well — it depends on what &amp;ldquo;this&amp;rdquo; does. But probably no.&lt;/p&gt;
&lt;p&gt;Virtual threads and WebFlux solve different problems. The confusion comes from the fact that they both appear in the sentence &amp;ldquo;handle many concurrent requests efficiently.&amp;rdquo; But that&amp;rsquo;s like saying a hammer and a screwdriver are competitors because they both &amp;ldquo;join things together.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Real-time and Reactive Patterns with Netflix DGS</title><link>https://saasforge.cz/blog/dgs-realtime-reactive-patterns/</link><pubDate>Thu, 19 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/dgs-realtime-reactive-patterns/</guid><description>&lt;p&gt;&lt;em&gt;Part 4 of 7 in the &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; series&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;REST APIs are request-response: the client asks, the server answers, the connection closes. GraphQL subscriptions break that pattern — the server pushes updates to the client as they happen. This article covers how DGS implements subscriptions, how reactive types work throughout the framework, and how to observe it all in production.&lt;/p&gt;
&lt;h2 id="graphql-subscriptions"&gt;GraphQL Subscriptions&lt;/h2&gt;
&lt;p&gt;Subscriptions let clients receive a stream of updates over a persistent connection. Common use cases: live scoreboards, progress tracking, notifications, collaborative editing.&lt;/p&gt;</description></item><item><title>Stop Demolishing the House to Change the Furniture: Why GitOps Beats Push-Based Deployment</title><link>https://saasforge.cz/blog/gitops-pull-vs-push-deployment/</link><pubDate>Mon, 16 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/gitops-pull-vs-push-deployment/</guid><description>&lt;p&gt;You want to deploy a new version of your API. A one-line change: bump the image tag from &lt;code&gt;v1.4.2&lt;/code&gt; to &lt;code&gt;v1.4.3&lt;/code&gt;. With a GitOps setup, you push to Git, and 30 seconds later the cluster has reconciled. With the push-based approach I keep seeing in production — Helm charts published by Terraform — you run a pipeline that plans the entire infrastructure, evaluates every resource, waits for approval, and then applies the change. That&amp;rsquo;s demolishing the house to change the furniture.&lt;/p&gt;</description></item><item><title>Securing Your GraphQL API with Netflix DGS</title><link>https://saasforge.cz/blog/dgs-securing-graphql-api/</link><pubDate>Thu, 12 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/dgs-securing-graphql-api/</guid><description>&lt;p&gt;&lt;em&gt;Part 3 of 7 in the &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; series&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;GraphQL gives clients extraordinary flexibility — they choose which fields to fetch, how deeply to nest, and how many operations to batch. That flexibility is also your attack surface. This article covers the three layers of defense every production GraphQL API needs: &lt;strong&gt;authentication and authorization&lt;/strong&gt;, &lt;strong&gt;error sanitization&lt;/strong&gt;, and &lt;strong&gt;query abuse protection&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="layer-1-authentication-and-authorization"&gt;Layer 1: Authentication and Authorization&lt;/h2&gt;
&lt;p&gt;DGS runs inside Spring Boot, which means Spring Security&amp;rsquo;s full toolkit is available. The most practical pattern is &lt;strong&gt;&lt;code&gt;@PreAuthorize&lt;/code&gt; annotations directly on DGS methods&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>Testing Axon 5 Aggregates with Spock: A Practical Guide</title><link>https://saasforge.cz/blog/axon5-spock-aggregate-testing/</link><pubDate>Mon, 09 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/axon5-spock-aggregate-testing/</guid><description>&lt;p&gt;Axon Framework&amp;rsquo;s event-sourcing model pairs naturally with Spock&amp;rsquo;s expressive &lt;code&gt;given-when-then&lt;/code&gt; style. Yet most examples online show JUnit. This guide covers how to test an Axon 5 aggregate&amp;rsquo;s full state machine using Spock and &lt;code&gt;AxonTestFixture&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="the-domain-an-order-aggregate"&gt;The Domain: An Order Aggregate&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll use a simple order lifecycle:&lt;/p&gt;
&lt;div class="mermaid"&gt;stateDiagram-v2
 [*] --&gt; CREATED
 CREATED --&gt; CONFIRMED: confirm
 CONFIRMED --&gt; SHIPPED: ship
 SHIPPED --&gt; DELIVERED: deliver
 CREATED --&gt; CANCELLED: cancel
 CONFIRMED --&gt; CANCELLED: cancel
&lt;/div&gt;
&lt;p&gt;The aggregate tracks status via &lt;code&gt;@EventSourcingHandler&lt;/code&gt; methods that replay stored events:&lt;/p&gt;</description></item><item><title>Solving N+1 with Data Loaders and Field Resolvers</title><link>https://saasforge.cz/blog/dgs-data-loaders-field-resolvers/</link><pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/dgs-data-loaders-field-resolvers/</guid><description>&lt;p&gt;&lt;em&gt;Part 2 of 7 in the &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; series&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;GraphQL gives clients the power to ask for exactly the data they need. That&amp;rsquo;s its strength — and its trap. Without careful backend design, a single query can trigger hundreds of database calls. This article shows how DGS data loaders and field resolvers prevent that from happening.&lt;/p&gt;
&lt;h2 id="the-n1-problem-visualized"&gt;The N+1 Problem, Visualized&lt;/h2&gt;
&lt;p&gt;Consider a simple query that fetches orders with their products:&lt;/p&gt;</description></item><item><title>Schema-First GraphQL with Netflix DGS</title><link>https://saasforge.cz/blog/dgs-schema-first-graphql/</link><pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/dgs-schema-first-graphql/</guid><description>&lt;p&gt;&lt;em&gt;Part 1 of 7 in the &amp;ldquo;Production GraphQL with Netflix DGS&amp;rdquo; series&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If you&amp;rsquo;re building a GraphQL API with Spring Boot, you&amp;rsquo;ve probably noticed two major frameworks competing for your attention: &lt;strong&gt;Netflix DGS&lt;/strong&gt; and &lt;strong&gt;Spring for GraphQL&lt;/strong&gt;. For years, teams had to pick a side. That choice no longer exists — and the story of how these frameworks merged is worth understanding before you write your first &lt;code&gt;@DgsQuery&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="two-frameworks-become-one"&gt;Two Frameworks Become One&lt;/h2&gt;
&lt;p&gt;Netflix open-sourced the Domain Graph Service (DGS) framework in 2021. It was battle-tested at Netflix scale — hundreds of services, thousands of queries — and it offered something Spring didn&amp;rsquo;t have at the time: a polished, annotation-driven programming model for GraphQL.&lt;/p&gt;</description></item><item><title>The Silent Metadata Gap: Why Your Axon 5 Events Have No User Attribution</title><link>https://saasforge.cz/blog/axon5-command-metadata-propagation/</link><pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/axon5-command-metadata-propagation/</guid><description>&lt;p&gt;When we migrated from Axon Framework 4 to 5, we carefully updated aggregates to use &lt;code&gt;EventAppender&lt;/code&gt;, rewrote command handlers with static factory methods, and adjusted our event sourcing handlers. Everything compiled. Tests passed. Events flowed. Then during an internal QA round, we spotted something odd: the aggregate history timeline showed events with no author — just timestamps and event types floating in a void.&lt;/p&gt;
&lt;p&gt;The root cause? &lt;strong&gt;Axon command metadata does not automatically propagate to events.&lt;/strong&gt; And when you&amp;rsquo;re focused on the big Axon 5 migration changes, this is exactly the kind of thing that slips through.&lt;/p&gt;</description></item><item><title>Your MCP Server Works Locally. Then Kubernetes Kills the Session.</title><link>https://saasforge.cz/blog/mcp-stateless-kubernetes/</link><pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/mcp-stateless-kubernetes/</guid><description>&lt;p&gt;We&amp;rsquo;re running a Spring AI MCP server in production on GKE. It serves Claude Code as a client, exposing 60+ tools for managing climbing data — sites, routes, venues, the works. The auth layer is solid: JWT tokens persisted in PostgreSQL, dual validation (HS256 service tokens, RS256 OAuth user tokens), revocation checks on every request.&lt;/p&gt;
&lt;p&gt;Then, intermittently, Claude Code starts throwing this:&lt;/p&gt;
&lt;div class="code-block"&gt;
 &lt;div class="code-block__header"&gt;
 &lt;span class="code-block__lang"&gt;Text&lt;/span&gt;
 &lt;button class="code-block__copy" onclick="let c=this.closest('.code-block').querySelector('pre'),i=this.querySelector('.material-icons-outlined');navigator.clipboard.writeText(c.textContent);i.textContent='check';setTimeout(()=&gt;i.textContent='content_copy',2000)"&gt;&lt;span class="material-icons-outlined"&gt;content_copy&lt;/span&gt;&lt;/button&gt;
 &lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Session not found: f4456324-79fb-4d84-ab2b-eebf27c5a475&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The token is valid. The server is up. The endpoint responds. But the session is gone.&lt;/p&gt;</description></item><item><title>Replacing Flux Bootstrap with the Flux Operator: GitOps on Autopilot Mode</title><link>https://saasforge.cz/blog/flux-operator-gitops/</link><pubDate>Fri, 20 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/flux-operator-gitops/</guid><description>&lt;p&gt;Managing Flux CD in production used to mean running &lt;code&gt;flux bootstrap&lt;/code&gt;, committing hundreds of lines of generated YAML, and then manually coordinating upgrades across clusters. With the &lt;a href="https://github.com/controlplaneio-fluxcd/flux-operator"&gt;Flux Operator&lt;/a&gt;, all of that is replaced by a single Kubernetes custom resource — the &lt;strong&gt;FluxInstance&lt;/strong&gt; — that declares your entire Flux installation as code.&lt;/p&gt;
&lt;p&gt;In this post, we walk through how we migrated from the traditional Flux bootstrap approach to the Flux Operator on a GKE Autopilot cluster, managed entirely with Terraform.&lt;/p&gt;</description></item><item><title>Propagating User Identity in Axon 5 Query Handlers</title><link>https://saasforge.cz/blog/axon5-query-auth-metadata/</link><pubDate>Wed, 18 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/axon5-query-auth-metadata/</guid><description>&lt;p&gt;&lt;strong&gt;Update (March 2026):&lt;/strong&gt; We&amp;rsquo;ve &lt;a href="https://github.com/AxonFramework/AxonFramework/issues/4207"&gt;raised this as an issue&lt;/a&gt; with the Axon Framework team. The core problem — &lt;code&gt;ReactiveSecurityContextHolder&lt;/code&gt; being empty inside &lt;code&gt;@QueryHandler&lt;/code&gt; — is now tracked as &lt;a href="https://github.com/AxonFramework/AxonFramework/issues/4207"&gt;GitHub issue #4207&lt;/a&gt;. See the &lt;a href="https://saasforge.cz/blog/axon5-query-auth-metadata/#update-issue-filed-with-axon-framework"&gt;update section&lt;/a&gt; below.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;During internal testing of our latest release, we hit a puzzling bug: owners couldn&amp;rsquo;t see their own entities on a management page. The error message was simply &amp;ldquo;Unable to load&amp;rdquo; — despite the record clearly existing in the database.&lt;/p&gt;</description></item><item><title>Migrating from Axon Framework 4 to 5: What We Learned</title><link>https://saasforge.cz/blog/axon-framework-4-to-5-migration/</link><pubDate>Mon, 16 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/axon-framework-4-to-5-migration/</guid><description>&lt;p&gt;We run a CQRS/Event Sourcing backend — now happily on Java 25, Spring Boot 4, and Axon Framework 5. But getting here from Axon 4.12 was a journey. The codebase has dozens of aggregates, multiple sagas, over a hundred event types, and hundreds of annotated handler methods.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what we learned along the way.&lt;/p&gt;
&lt;h2 id="why-we-wanted-axon-5"&gt;Why We Wanted Axon 5&lt;/h2&gt;
&lt;p&gt;The motivation was simple: &lt;strong&gt;native reactive support in event handlers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Axon 4.x has a well-known issue with subscribing event processors. When an &lt;code&gt;@EventHandler&lt;/code&gt; returns a &lt;code&gt;Mono&amp;lt;Void&amp;gt;&lt;/code&gt;, the framework never subscribes to it. The reactive chain simply doesn&amp;rsquo;t execute. We discovered this the hard way when projection handlers silently stopped writing to the database.&lt;/p&gt;</description></item><item><title>Why OpenTelemetry Beats Vendor-Locked APM Agents</title><link>https://saasforge.cz/blog/why-opentelemetry-beats-vendor-agents/</link><pubDate>Sat, 14 Feb 2026 00:00:00 +0000</pubDate><guid>https://saasforge.cz/blog/why-opentelemetry-beats-vendor-agents/</guid><description>&lt;p&gt;If you&amp;rsquo;ve ever tried to swap out your APM vendor, you know the pain. Proprietary agents from Datadog, Dynatrace, or New Relic weave themselves deep into your deployment pipeline — different binary agents for each language, vendor-specific configuration, custom SDKs in your application code. Switching means ripping it all out and starting over.&lt;/p&gt;
&lt;p&gt;OpenTelemetry offers a fundamentally different approach: &lt;strong&gt;one open standard to instrument everything&lt;/strong&gt;, with the freedom to send telemetry data wherever you want.&lt;/p&gt;</description></item></channel></rss>