<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Causely</title>
    <description>The latest articles on DEV Community by Causely (causely).</description>
    <link>https://dev.to/causely</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F8814%2Fbe76ae78-1f52-4c97-92aa-cdfec5be4fdd.png</url>
      <title>DEV Community: Causely</title>
      <link>https://dev.to/causely</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/causely"/>
    <language>en</language>
    <item>
      <title>Is access enough? Auth patterns for Claude Managed Agents</title>
      <dc:creator>Ben Yemini</dc:creator>
      <pubDate>Mon, 17 Aug 2026 19:52:38 +0000</pubDate>
      <link>https://dev.to/causely/is-access-enough-auth-patterns-for-claude-managed-agents-1ldg</link>
      <guid>https://dev.to/causely/is-access-enough-auth-patterns-for-claude-managed-agents-1ldg</guid>
      <description>&lt;p&gt;Originally posted to &lt;a href="https://dev.tourl"&gt;causely.ai&lt;/a&gt; by &lt;a href="https://www.linkedin.com/in/byemini/" rel="noopener noreferrer"&gt;Ben Yemini&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL; DR&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;Background agents run independently and can be triggered by events, making them a good fit for on-call work. Claude Managed Agents are one example, and MCP tunnels give them access to the environment&amp;nbsp;they're&amp;nbsp;making decisions over, reaching it, and authenticating. But access is just the starting point. An agent that can reach and log into every system still&amp;nbsp;isn't&amp;nbsp;automatically one&amp;nbsp;you'd&amp;nbsp;trust to run&amp;nbsp;on-call.&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do background agents fit on-call work?&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;Background agents differ from interactive assistants in one&amp;nbsp;key&amp;nbsp;way: they run on their own schedule, triggered by an event&amp;nbsp;(e.g., a page, an alert) rather&amp;nbsp;than by someone typing a prompt.&amp;nbsp;This&amp;nbsp;difference is what makes them&amp;nbsp;an ideal&amp;nbsp;fit for on-call&amp;nbsp;ops&amp;nbsp;work, where nobody&amp;nbsp;has to be&amp;nbsp;sitting at a keyboard when&amp;nbsp;performance degrades.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Background agents persist. They pick up an event, run for as long as the investigation takes, from seconds to hours,&amp;nbsp;and can be triggered again later on the same thread.&amp;nbsp;&lt;a href="https://www.youtube.com/live/L0BXwymeYvk?t=216s" rel="noopener noreferrer"&gt;Cole&amp;nbsp;Murray,&amp;nbsp;the creator of&amp;nbsp;Open-Inspect,&amp;nbsp;walks&amp;nbsp;through this distinction in detail&lt;/a&gt;, and it's worth watching: the architecture decisions that make sense for a chat assistant don't automatically transfer to something that runs unattended.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Claude Managed Agents&amp;nbsp;provide a similar instantiation:&amp;nbsp;their&amp;nbsp;sessions persist&amp;nbsp;in the&amp;nbsp;cloud, execute over time,&amp;nbsp;and can be triggered by automated events.&amp;nbsp; Anthropic's&amp;nbsp;own walkthrough of managed agents&amp;nbsp;covers the mechanics&amp;nbsp;and shows&amp;nbsp;&lt;a href="https://anthropic.ondemand.goldcast.io/on-demand/f8679328-af86-4d55-9f76-1f32dad49918" rel="noopener noreferrer"&gt;how to build an SRE&amp;nbsp;incident response agent&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;For on-call work, this approach is helpful in two ways. For reactive&amp;nbsp;workflows,&amp;nbsp;it ensures that whoever prompts the agent has the same setup and that the agent has the necessary access to assist with the investigation. More&amp;nbsp;importantly,&amp;nbsp;for proactive&amp;nbsp;workflows,&amp;nbsp;the agent can be triggered by events and start and end the investigation before an on-call engineer gets out of bed.&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Recently,&amp;nbsp;at Code with Claude in London on May 19, 2026, Anthropic shipped two features that&amp;nbsp;improve&amp;nbsp;the performance of these agents when running them against production systems.&amp;nbsp;Self-hosted sandboxes (public beta) and MCP tunnels (research preview). Together, they let a cloud-run agent reach a private Kubernetes cluster or an internal Prometheus instance without opening an inbound port, closing a gap that had been blocking some on-call use cases on security review&amp;nbsp;alone.&amp;nbsp;These&amp;nbsp;welcomed&amp;nbsp;improvements make this approach much more practical.&amp;nbsp;It also surfaces&amp;nbsp;the next key question: once the agent&amp;nbsp;has&amp;nbsp;access,&amp;nbsp;does it have the context it needs to resolve the problem?&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reaching your infrastructure is (mostly) a solved problem&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;A managed agent runs in&amp;nbsp;Anthropic's&amp;nbsp;cloud; your cluster, your metrics, and your logs run in your environment. The agent never touches them directly. It&amp;nbsp;calls MCP servers that do. Your cluster exposes a Kubernetes MCP&amp;nbsp;server,&amp;nbsp;your metrics stack exposes a Prometheus MCP server, and the agent calls&amp;nbsp;both as&amp;nbsp;tools. It never gets a raw&amp;nbsp;kubeconfig&amp;nbsp;or a database connection string.&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The first wall anyone hits&amp;nbsp;is&amp;nbsp;that a cloud agent&amp;nbsp;can't&amp;nbsp;reach&amp;nbsp;localhost&amp;nbsp;or a private API server. For local development or a&amp;nbsp;&lt;code&gt;kind&lt;/code&gt;&amp;nbsp;cluster, a tunnel like&amp;nbsp;cloudflared's&amp;nbsp;quick-tunnel mode gets you unblocked in minutes. This works for&amp;nbsp;a&amp;nbsp;proof&amp;nbsp;of concept, but&amp;nbsp;not for running production traffic. The production answer is&amp;nbsp;&lt;a href="https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/overview" rel="noopener noreferrer"&gt;native MCP tunnels&lt;/a&gt;. A lightweight gateway inside your network opens a single outbound connection;&amp;nbsp;there's&amp;nbsp;no inbound port and no public MCP endpoint for a scanner to find. This is a general property of cloud-run agents, not something specific to Claude. Any agent platform running outside your perimeter&amp;nbsp;has to&amp;nbsp;solve the same reachability problem, and outbound-only tunneling is the shape the industry,&amp;nbsp;including&amp;nbsp;&lt;a href="https://aws.amazon.com/blogs/networking-and-content-delivery/network-connectivity-patterns-for-agents-deployed-on-amazon-bedrock-agentcore-runtime/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://docs.cloud.google.com/architecture/multi-agent-private-networking-patterns" rel="noopener noreferrer"&gt;Google&lt;/a&gt;,&amp;nbsp;has converged on this year.&lt;br&gt;
&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you authenticate an agent to systems it can now reach?
&lt;/h2&gt;

&lt;p&gt;&amp;nbsp;&lt;br&gt;
The Managed Agents MCP connector sends one thing to your server: an&amp;nbsp;&lt;code&gt;Authorization: Bearer&lt;/code&gt;&amp;nbsp;header. Credentials live in a vault matched by the MCP server's URL, not configured on the server entry itself. This&amp;nbsp;means the hard part of auth&amp;nbsp;isn't&amp;nbsp;the agent side,&amp;nbsp;it's&amp;nbsp;getting your existing auth&amp;nbsp;approach&amp;nbsp;to&amp;nbsp;work with&amp;nbsp;that&amp;nbsp;model.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8i6b68ssnyo06xpzb4kd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8i6b68ssnyo06xpzb4kd.png" alt="Three auth patterns for background-agents" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three cases show up in practice, in&amp;nbsp;roughly escalating&amp;nbsp;difficulty:&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No auth.&lt;/strong&gt;&amp;nbsp;A Kubernetes MCP server behind a tunnel with cluster-level RBAC as the only gate. Fine for a&amp;nbsp;&lt;code&gt;kind&lt;/code&gt;&amp;nbsp;cluster or a low-stakes internal tool; not something to run against a production API server without at least a bearer token in front of it.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static bearer token.&lt;/strong&gt;&amp;nbsp;A Grafana service-account token, stored in a vault and matched to the MCP server's URL. This is the common case for read-only observability queries.&amp;nbsp;Prometheus, Loki, and Grafana all support long-lived service-account tokens, and the vault handles rotation.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OAuth client-credentials → JWT.&lt;/strong&gt;&amp;nbsp;The hard case, since most internal APIs&amp;nbsp;weren't&amp;nbsp;built expecting a bearer-only connector.&amp;nbsp;It sends&amp;nbsp;&lt;code&gt;Authorization: Bearer&lt;/code&gt;&amp;nbsp;and nothing else, so the vault has to complete the OAuth exchange up front and hand back a plain bearer token.&amp;nbsp;Sending the client secret as a separate field instead produces a&amp;nbsp;&lt;code&gt;400 unknown field&lt;/code&gt;&amp;nbsp;error, since the&amp;nbsp;connector's&amp;nbsp;schema only expects the one header.&amp;nbsp;For a straightforward approach to&amp;nbsp;handling&amp;nbsp;this see the repo at the end of this post.&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The generalizable rule holds regardless of which of the three cases&amp;nbsp;you're&amp;nbsp;in: the&amp;nbsp;connector's&amp;nbsp;interface is&amp;nbsp;&lt;code&gt;Authorization: Bearer&lt;/code&gt;. Anything more complex belongs in the vault, not in the agent's configuration.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Once&amp;nbsp;that's&amp;nbsp;wired up&amp;nbsp;and authenticated, the reachability problem is&amp;nbsp;addressed, and the real work can begin.&amp;nbsp;&lt;br&gt;
&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  Access&amp;nbsp;isn't&amp;nbsp;understanding&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;An agent with full read access to Kubernetes, Prometheus, and your log pipeline still reasons&amp;nbsp;poorly about the system it is investigating.&amp;nbsp;Even the richest telemetry does not come with a model of what depends on what, or more specifically, what can cause what.&amp;nbsp;Metric series, multiple alerts firing, log lines, and even traces provide the agent with rich data to investigate and reason with, but the access to this data is not structured in a way that makes it effective.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Give an agent&amp;nbsp;&lt;code&gt;kubectl&lt;/code&gt;, a&amp;nbsp;PromQL&amp;nbsp;endpoint, and a log query tool, and it can retrieve almost&amp;nbsp;anything&amp;nbsp;but retrieval&amp;nbsp;isn't&amp;nbsp;diagnosis.&amp;nbsp;This&amp;nbsp;is&amp;nbsp;not&amp;nbsp;a knock on the underlying telemetry.&amp;nbsp;&lt;a href="https://opentelemetry.io/docs/specs/semconv/" rel="noopener noreferrer"&gt;OpenTelemetry's semantic conventions&lt;/a&gt;&amp;nbsp;exist precisely to make spans, metrics, and logs consistent enough to reason&amp;nbsp;over&amp;nbsp;but consistent data&amp;nbsp;isn't&amp;nbsp;the same as a causal model of the system that produced it.&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;We've&amp;nbsp;written before about&amp;nbsp;&lt;a href="https://www.causely.ai/blog/how-causal-reasoning-addresses-the-limitations-of-llms-in-observability" rel="noopener noreferrer"&gt;why LLMs alone hallucinate root causes&lt;/a&gt;&amp;nbsp;for the same underlying reason: pattern-matching over telemetry&amp;nbsp;isn't&amp;nbsp;the same as reasoning over a dependency graph. The distinction between monitoring,&amp;nbsp;knowing something is wrong,&amp;nbsp;and observability,&amp;nbsp;knowing why,&amp;nbsp;makes a related point from a different angle. An agent that can query telemetry has solved the first problem. Solving the second requires encoding dependency and causality structure somewhere: in a semantic layer, a service graph, or an explicit causal model, so the agent has something to reason against, not just something to query.&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&amp;nbsp;&lt;br&gt;
&lt;strong&gt;How do I connect a cloud AI agent to infrastructure it&amp;nbsp;can't&amp;nbsp;reach directly?&lt;/strong&gt;&amp;nbsp;Deploy an MCP server for the system you want the agent to reach, then bridge it with an outbound-only tunnel. For local development or a&amp;nbsp;kind&amp;nbsp;cluster, a quick tunnel like&amp;nbsp;cloudflared&amp;nbsp;works in minutes. For production, use native MCP tunnels: a gateway inside your network opens a single outbound connection, so no inbound port or public MCP endpoint is ever exposed.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does giving an agent more system access make it more reliable?&lt;/strong&gt;&amp;nbsp;Not by itself. Raw access to Kubernetes, Prometheus, and logs lets an agent retrieve data, but that doesn't mean it can diagnose. Without an encoded model of service dependencies and event ordering, an agent&amp;nbsp;can't&amp;nbsp;reliably tell a root cause from a downstream symptom. It can query more, not reason better. Access solves reachability; understanding requires a separate structural layer.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's&amp;nbsp;the difference between an agent reaching a system and an agent understanding it?&lt;/strong&gt;&amp;nbsp;Reaching a system means the agent can call an MCP server and retrieve metrics, logs, or cluster state. Understanding means the agent can tell which of those signals is the&amp;nbsp;cause&amp;nbsp;and which are downstream effects,&amp;nbsp;something that requires a dependency graph or causal model, not just a wider set of tools to query.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I authenticate a managed agent to an internal API that uses OAuth?&lt;/strong&gt;&amp;nbsp;Resolve the OAuth client-credentials flow inside your credential vault, not in the agent's configuration. The Managed Agents MCP connector only ever sends an&amp;nbsp;&lt;code&gt;Authorization: Bearer&lt;/code&gt;&amp;nbsp;header matched to the server's URL.&amp;nbsp;It&amp;nbsp;won't&amp;nbsp;perform a token exchange or accept additional OAuth fields, so the vault has to mint the JWT and return a plain bearer token.&amp;nbsp;See the reference repo below for code examples.&amp;nbsp;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do next&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;Read the&amp;nbsp;&lt;a href="https://github.com/causely-oss/background-agents/tree/main/claude-managed-agents" rel="noopener noreferrer"&gt;three-auth-pattern, kind-runnable reference repo&lt;/a&gt;&amp;nbsp;to see all three cases running end to end&amp;nbsp;with a Claude managed SRE agent accessing&amp;nbsp;a real cluster. The open question this setup raises&amp;nbsp;is&amp;nbsp;whether adding a causal or semantic layer on top of raw telemetry access measurably changes how well an agent investigates an incident.&amp;nbsp;We're&amp;nbsp;running a reproducible, measured comparison on&amp;nbsp;this&amp;nbsp;next. Stay tuned.&amp;nbsp;&amp;nbsp;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>backgroundagents</category>
      <category>ai</category>
      <category>sre</category>
    </item>
    <item>
      <title>Semantics in Observability: A Precise Vocabulary for System Understanding</title>
      <dc:creator>Ben Yemini</dc:creator>
      <pubDate>Mon, 03 Aug 2026 18:32:30 +0000</pubDate>
      <link>https://dev.to/causely/semantics-in-observability-a-precise-vocabulary-for-system-understanding-2fdp</link>
      <guid>https://dev.to/causely/semantics-in-observability-a-precise-vocabulary-for-system-understanding-2fdp</guid>
      <description>&lt;p&gt;Orignially posted to &lt;a href="https://www.causely.ai/blog/semantics-in-observability" rel="noopener noreferrer"&gt;causely.ai&lt;/a&gt; by &lt;a href="https://www.linkedin.com/in/endresara" rel="noopener noreferrer"&gt;Endre Sara&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The word &lt;strong&gt;context&lt;/strong&gt; is overloaded in observability discourse to the point of losing precision. It is used to refer to shared labels, a topology map, temporal proximity, and propagated trace identifiers. Four distinct things, each useful, none of them sufficient.&lt;/p&gt;

&lt;p&gt;This blog defines a precise, layered model of observability semantics intended for engineers and SREs building or operating complex distributed systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gap in Current Observability Tooling
&lt;/h2&gt;

&lt;p&gt;Most observability tooling today implements a shallow semantics of entity and some form of topology, often referred to as the knowledge graph – typically derived from trace data – with partial reach into behavior through threshold-based alerting and anomaly detection. A knowledge graph is a generic term that does not define the semantics of what it captures. It is typically assumed to be a list of services and their topological relationships, but as we point out later, this is not sufficient to answer questions. It is also a dynamic, ever-changing graph; capturing it only once, or once a week, is not a reliable representation for real-time, continuous, automated operation. Deeper semantics are largely absent from tooling and instead exist as undocumented knowledge held by individual engineers.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;This lack of semantics has predictable operational consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alert fatigue: alerting systems fire on symptoms without the ability to identify the root cause, producing storms where a single fault generates dozens of notifications&lt;/li&gt;
&lt;li&gt;Slow incident response: root cause reasoning and impact analysis happen manually, in real time, under pressure, because the causal and dependency knowledge exists only in human memory&lt;/li&gt;
&lt;li&gt;Blast-radius estimation is guesswork: a lack of knowledge of the impact of failure. There is no systematic way to ask what would happen if a given component failed, which dependent services would be affected, which symptoms would surface, and in what order.&lt;/li&gt;
&lt;li&gt;Causal knowledge is reactive, not preventive: no proactive reasoning about causes. Engineers cannot ask what classes of failure could produce a given set of symptoms, or which components in the current system state are most likely to trigger an incident.&lt;/li&gt;
&lt;li&gt;No counterfactual reasoning: there is no way to assert that a specific condition could cause a specific failure, or conversely that a given failure mode cannot produce a set of observed symptoms. Without formal causal and dependency knowledge, both directions of reasoning – “could this cause that?” and “could that have caused this?” – rely entirely on individual experience&lt;/li&gt;
&lt;li&gt;Knowledge loss: engineers who have internalized the causal and constraint knowledge leave, and the organization reverts to slower, less reliable incident response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data to address these problems is largely available in service meshes, infrastructure APIs, configuration management systems, and telemetry pipelines. The gap is not data. It is the absence of explicit semantic models that make that data legible to AI Agents. The sections below define the models.&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Layered Semantic Model for Observability
&lt;/h2&gt;

&lt;p&gt;The following six layers describe the semantic structure required to move from “we see a signal” to “we understand what is happening and why.” Each layer builds on the previous. Tooling that skips layers will exhibit predictable gaps in reasoning capability.&lt;/p&gt;

&lt;p&gt;It is important to note that the semantics model at each layer has two parts, a knowledge base and a dynamic graph. The knowledge base captures the generic knowledge of what may be observed. The knowledge base captures abstract semantic descriptions common across all environments. The dynamic graph instantiates the knowledge base to generate a real-time model of the managed environment at a given point in time. The dynamic graph is the actual observed reality, specific to a given environment at a given point in time, and keeps adapting as the environment changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Entity Model
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;entity model&lt;/strong&gt; defines the named objects in the system and the attributes that describe them. An entity is any discrete thing with identity and an observable state.&lt;/p&gt;

&lt;p&gt;The entity knowledge base captures the types of entities that may be discovered, e.g., a service instance, a host, a Kubernetes pod, a database cluster, a message queue, a CDN edge node, an AI Agent, an MCP server with tools or an LLM model and its provider, and the attributes that may be observed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identity&lt;/strong&gt;: UUID with associated attributes like name, namespace, cluster, region, environment, labels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration&lt;/strong&gt;: resource limits, replica count, connection pool size, JVM flags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime state&lt;/strong&gt;: CPU utilization, memory used, request rate, error rate, queue depth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dynamic entity model instantiates the knowledge base with the discovered entities and serves as an inventory of all entities in the environment at a given point in time. For example, the list of services, hosts, pods, databases, message queues, etc., in the environment.&lt;/p&gt;

&lt;p&gt;Without an entity model, telemetry is a stream of dimensioned numbers. With one, it is a description of a system composed of named, typed, queryable objects. This semantics is a prerequisite for all higher-order reasoning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Topology Model
&lt;/h2&gt;

&lt;p&gt;The topology model encodes the structural relationships between entities: which services call which databases, which pods run on which nodes, which queues are consumed by which workers, etc.&lt;br&gt;
The topology knowledge base captures the relationship that may exist between types of entities, For exaple, a service may be connected to another service, a service may be accessing a database, a service may be layered over a pod.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbqg1m1fp48nwfsd0rkxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbqg1m1fp48nwfsd0rkxi.png" alt="Relationship Types" width="799" height="420"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Relationship Types&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The dynamic topology graph represents the actual discovered relationships between discovered entities. For example, the Coordinator Agent is connected to the Research, Coding, and Ops subagents; the GitHub MCP server, which includes the create pull request tool; and the GPT-4o model, which is layered over the OpenAI model provider (see Figure 1).&lt;/p&gt;

&lt;p&gt;It is important to note that the knowledge base captures design-time assertions, not runtime observations. This distinction is critical. A service dependency map derived from trace data reflects what happened during the observation window. The dynamic topology graph reflects what is. Traces may be incomplete (non-instrumented paths, async operations, batch jobs). The dynamic topology graph enables blast-radius analysis; given that entity foo is degraded, which other entities are structurally dependent on it and therefore at risk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fma08trorwzgly5zibucj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fma08trorwzgly5zibucj.png" alt="Figure 1: Topology — structural relationships between agents, MCP servers, and Model Providers." width="800" height="546"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 1: Topology — structural relationships between agents, MCP servers, and Model Providers.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Behavior Model
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;behavior model&lt;/strong&gt; captures the observable signals of normal and abnormal system behavior. It defines &lt;strong&gt;symptoms&lt;/strong&gt; – semantically meaningful deviations from expected state  – and &lt;strong&gt;events&lt;/strong&gt; – discrete state transitions that represent changes in entity health or configuration.&lt;/p&gt;

&lt;p&gt;A raw metric is not a symptom. The number 95.3 on a CPU utilization gauge is not meaningful without knowing the entity it describes, the threshold at which that utilization constitutes an anomaly, and the operational context in which that threshold applies. A symptom is the semantic interpretation: &lt;em&gt;this entity is exhibiting CPU saturation relative to its configured capacity and expected workload.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The behavior model is what converts monitoring data into an actionable signal. Alerting systems that operate directly on raw metrics without a behavior model produce high false-positive rates because they lack the semantic layer needed to distinguish signal from noise.&lt;/p&gt;

&lt;p&gt;The behavior knowledge base captures the possible observable anomalies an entity may experience. For example, a service may be degraded, experiencing high latency, or a node may be highly utilized, experiencing high CPU utilization.&lt;/p&gt;

&lt;p&gt;The dynamic behavior model represents the environment's actual runtime state based on what is being observed. For example, the Research subagent is degraded and experiencing high latency, or the Postgres MCP is congested and experiencing high query times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 4: Causality Model
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;causality model&lt;/strong&gt; captures the cause-and-effect relationship between potential causes and the symptoms or events they may cause.&lt;br&gt;
The causal knowledge base describes the potential causes, the symptoms they may cause, and how they may propagate. Propagation captures how a cause occurring on one entity may propagate to another related entity. &amp;nbsp;&lt;/p&gt;

&lt;p&gt;The causal knowledge base captures generic knowledge about the types of causes that may occur in an environment and how they will manifest, i.e., the symptoms that may be observed when they occur.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An MCP service may be congested and when it is congested it may cause its tool calls to be slow, manifested as a high tool-call latency symptom, and may propagate and cause degradation of subagents that depend on it.&lt;/li&gt;
&lt;li&gt;A subagent may be degraded and when it is degraded it may cause its responses to be slow, manifested as a slow response time symptom, and may propagate and cause degradation of the coordinator agent that orchestrates it.&lt;/li&gt;
&lt;li&gt;A model provider may be degraded and when it is degraded it may cause its inference requests to be slow, manifested as high inference latency, and may propagate to subagents using its models causing them to be degraded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As the above examples illustrate, the causal knowledge base is completely independent of a given environment. It is independent of how many providers, MCP services, and/or subagents are in the environment, and which models run on which providers, which subagents access which MCPs, or which coordinator orchestrates which subagents.&lt;/p&gt;

&lt;p&gt;The dynamic causal graph represents the actual runtime causality in the environment at a given point in time. It is a function of the dynamic topology graph and represents all potential specific causes that may occur in the environment, along with the specific symptoms they may cause. The figure below illustrates a concrete example: the Postgres MCP may be congested, and the fault may propagate through the execute_sql tool call to the Coding and Ops subagents, and then onward to the Coordinator, with symptom probability decreasing at each hop. Similarly, Anthropic provider degradation may propagate through Claude inference to the Research, Coding, and Ops subagents, and then to the Coordinator.&lt;/p&gt;

&lt;p&gt;In this example, the dynamic causal graph captures that a congested Postgres MCP may cause degradation of the Coding and Ops subagents and the Coordinator. It is important to note that the keyword semantically is “may”. A congested Postgres MCP may degrade downstream entities, but that doesn’t necessarily mean the Postgres MCP is congested – Anthropic provider degradation could produce overlapping symptoms. To conclude, the cause of an observed symptom requires analyzing the state of all potential symptoms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fecwu3z8sxui6krk4flkx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fecwu3z8sxui6krk4flkx.png" alt="Causal graph derived from the agentic topology in Figure 1. Two example fault paths (Postgres MCP congestion, Anthropic provider degradation) propagating through MCP services and subagents into the coordinator." width="799" height="247"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 2: Causal graph derived from the agentic topology in Figure 1. Two example fault paths (Postgres MCP congestion, Anthropic provider degradation) propagating through MCP services and subagents into the coordinator.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Cause (left) propagates rightward through topology edges. Probabilities indicate the likelihood of each symptom given the cause. Multiple symptoms may share a cause; diagnosis evaluates the full set of observed symptoms against this graph.&lt;/p&gt;

&lt;p&gt;The causality model is what makes root cause analysis tractable. Without it, a single infrastructure fault that produces symptoms across dozens of dependent services generates an alert storm with no structural differentiation between cause and effect. With it, symptoms can be suppressed or annotated as consequences once their cause is pinpointed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 5: Attributes Dependency Model
&lt;/h2&gt;

&lt;p&gt;Where the causality model operates at the symptom level, the &lt;strong&gt;attributes dependency model&lt;/strong&gt; operates at the attribute level. As its name suggests, it captures attribute dependencies. The dependent attributes can be of the same entity or of different entities. Dependency knowledge captures that attributes are correlated, along with the directionality and function of the correlation. The function can be defined in the model or learned.&lt;/p&gt;

&lt;p&gt;The attribute knowledge base captures the generic knowledge of which attribute depends on which. Examples of such dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subagent response latency is a function of the tool-call duration of the MCP services it invokes&lt;/li&gt;
&lt;li&gt;Coordinator response latency is a function of the response latencies of the subagents it orchestrates&lt;/li&gt;
&lt;li&gt;Subagent inference latency is a function of the inference latency of the model provider serving its model&lt;/li&gt;
&lt;li&gt;A subagent's token throughput is a function of the rate at which the coordinator dispatches requests to it.&lt;/li&gt;
&lt;li&gt;The end-to-end coordinator latency is a function of both per-call latencies and the number of subagent calls per task. A non-linear relationship, since a coordinator may fan out to multiple subagents in parallel, retry on failure, or recurse on intermediate results.&lt;/li&gt;
&lt;li&gt;Total tokens consumed by a subagent are a function of both the per-call token cost and the number of model-provider inference calls, which scales non-linearly with conversation depth, tool-call retries, and self-reflection loops.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dynamic attribute dependency graph represents the actual run-time dependencies in the environment at a given point in time. It is a function of the dynamic topology model. Given the above static model examples, the dynamic model examples would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the Coding subagent is accessing the Postgres MCP, Coding subagent latency is a function of execute_sql tool-call duration&lt;/li&gt;
&lt;li&gt;If the Coordinator is orchestrating the Coding subagent, Coordinator latency is a function of Coding subagent latency. Note that based on this, Coordinator latency can be computed as a function of execute_sql tool-call duration, even though the Coordinator does not directly access the Postgres MCP.&lt;/li&gt;
&lt;li&gt;If the Research subagent is using Claude served by Anthropic, the Research subagent's inference latency is a function of Anthropic's Claude inference latency.&lt;/li&gt;
&lt;li&gt;For the Ops subagent, its token throughput is a function of the rate of requests the Coordinator dispatches to it.&lt;/li&gt;
&lt;li&gt;If the Coordinator fans out a single user task to the Research, Coding, and Ops subagents in parallel, total Coordinator latency is approximately the max of the three subagent latencies, but if any subagent retries on tool-call failure, that subagent's effective latency multiplies by its retry count, so end-to-end latency grows non-linearly with failure rate.&lt;/li&gt;
&lt;li&gt;If the Coding subagent calls the Postgres MCP once per row in a result set, Coding subagent latency is a function of execute_sql duration multiplied by row count, so a query returning N rows produces N tool calls, and end-to-end latency scales with N rather than staying constant.&lt;/li&gt;
&lt;li&gt;If the Research subagent invokes Claude in a multi-turn reasoning loop with branching factor B and depth D, total Anthropic inference calls scale as B^D – so doubling reasoning depth roughly squares the inference cost, even though the Research subagent's per-task topology entry is unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhv332lnulrh3haibzh4m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhv332lnulrh3haibzh4m.png" alt="Non-linear call-count amplification. Three runtime patterns where total cost diverges from the static topology in Figure 1. (A) Parallel fan-out with retries multiplies the worst-case branch latency. (B) Per-row tool-call loops produce linear-in-N call counts that the topology graph cannot bound. (C) Recursive reasoning produces B^D inference calls, exponential in depth." width="800" height="350"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Figure 3: Non-linear call-count amplification. Three runtime patterns where total cost diverges from the static topology in Figure 1. (A) Parallel fan-out with retries multiplies the worst-case branch latency. (B) Per-row tool-call loops produce linear-in-N call counts that the topology graph cannot bound. (C) Recursive reasoning produces B^D inference calls, exponential in depth.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The attribute dependency graph enables change impact analysis: before modifying a configuration parameter, an operator or automation system can trace the dependency graph to identify which runtime attributes will be affected, on which entities, with what expected magnitude.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 6: Constraint Model
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;constraint model&lt;/strong&gt; defines the desired state. The desired state is one in which goals are achieved while constraints are satisfied. Each entity in an environment may have a desired state, but, more interestingly, the environment as a whole may have one as well.&lt;/p&gt;

&lt;p&gt;A desired environment state is one in which all applications deliver on their goals while running within their operational constraints. Usually, the goals are performance goals of latency and throughput, and service level goals in terms of errors and availability, while the operational constraints are capacity, budget, compliance, and configuration.&lt;/p&gt;

&lt;p&gt;An entity's desired state is the configuration space within which the entity and its attributes operate without triggering symptoms or degradation events. It is the semantic encoding of the system’s operational envelope.&lt;/p&gt;

&lt;p&gt;The constraint model captures both the environment's desired state and the entity's desired state. These can be defined independently, but by using the attribute dependency model, the entity's desired state can be generated/inferred from the environment's desired state, resulting in a very compelling and powerful system.&lt;/p&gt;

&lt;p&gt;As in all other layers, the constraint knowledge base captures generic knowledge about constraints, and the dynamic constraint model represents the runtime constraints at a given point in time based on the discovered topology. Constraints are not just thresholds on metrics. They are relationships between configuration parameters and the runtime conditions required for healthy operation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headroom constraint: Container memory limit &amp;gt;= 1.4 x used heap&lt;/li&gt;
&lt;li&gt;Budget constraint: Application cost &amp;lt; budget&lt;/li&gt;
&lt;li&gt;Latency constraint: Service latency &amp;lt; 100ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the constraint model is explicit, it becomes possible to answer operational questions that today require senior engineering intuition: “What is the minimum safe memory limit for this service at current traffic?” “If we reduce the connection pool by 40%, at what request rate will we begin to see queuing symptoms?” The constraint model is the missing link between observability (what is happening) and operations (what configuration produces health). It is the semantic layer connecting configuration management to runtime behavior.&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  What “Context” Actually Covers and Where It Falls Short
&lt;/h2&gt;

&lt;p&gt;Most observability platforms use the word loosely. Here is what the four common implementations actually encode, and where each one stops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared Labels&lt;/strong&gt;&lt;br&gt;
Common attributes – &lt;em&gt;service, environment, region, version&lt;/em&gt; – are attached to metrics, logs, and traces. This allows tooling to pivot between signal types for a given entity. The relationship is implied by label equality, not by any explicit model of dependency or causation. Two data points sharing &lt;em&gt;service=checkout&lt;/em&gt; are navigable together; they are not necessarily related by anything other than that label. This is a partial implementation of the entity model (layer 1) that lacks declarative topological relationships and behavior.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topology Map&lt;/strong&gt;&lt;br&gt;
A topology map encodes structural relationships between entities, which services call which databases, which pods run on which nodes, and which workloads share a cluster. It is the most semantically substantive form of “context” in common tooling and is typically derived from trace data, service-mesh telemetry, or infrastructure APIs. This is a partial implementation of the topology model (layer 2): it captures that entity X is connected to entity Y, but not what behavior propagates along that edge, why a fault on X causes a symptom on Y, or which of X’s attributes drives which of Y’s. A topology map shows the wiring; it does not encode behavior (layer 3), causality (layer 4), attribute dependency (layer 5), or constraints (layer 6). Two services connected in the topology may be tightly coupled in failure propagation or entirely decoupled. The map alone cannot distinguish them. In practice, this means a topology map supports navigation (“show me what this service talks to”) but not reasoning (“if this service degrades, what symptoms should I expect, on which dependents, and why”). That reasoning requires the higher layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Temporal Proximity&amp;nbsp;&lt;/strong&gt;&lt;br&gt;
Events co-located on a timeline are assumed by operators to be potentially related. The system carries no model of that relationship; pattern recognition is entirely delegated to the human. This is correlation by coincidence, not by structure. It addresses none of the six semantic layers explicitly; it is a UI affordance for human reasoning, not a semantic model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distributed Trace Propagation&lt;/strong&gt;&lt;br&gt;
A trace context header (W3C traceparent, B3, etc.) propagated across service boundaries encodes a genuine causal chain: span B was initiated by span A. This is the most semantically rich form of “context” in common use. It partially implements the topology model (layer 2) for instrumented call paths, and provides raw material for the behavior model (layer 3). However, it is constrained to synchronous, instrumented code paths and does not capture async operations, batch jobs, or infrastructure-level dependencies. It carries no causality, dependency, or constraint models.&lt;/p&gt;

&lt;p&gt;In summary, shared labels, temporal proximity, topology, and trace propagation collectively reach into layers 1 and 2. Layers 4 through 6 – causality, dependency, and constraints – are entirely outside the scope of what “context” addresses. That is the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion&amp;nbsp;
&lt;/h2&gt;

&lt;p&gt;Context – shared labels, topology map, temporal proximity, trace propagation – is a necessary foundation for navigating observability data. It is not sufficient for understanding systems. The jump from “we can see the signals” to “we understand what is happening and why” requires explicit semantic models at six distinct layers: entity, topology, behavior, causality, dependency, and constraint.&lt;/p&gt;

&lt;p&gt;The practical implication for SREs and platform engineers is that runbooks, tribal knowledge, and escalation paths are informal implementations of layers 4 through 6. The question is not whether to encode this knowledge, which already exists, but whether to leave it implicit in human memory or make it explicit in a form that tooling can reason about.&lt;br&gt;
Making semantics explicit is what makes a system legible to an AI agent. An agent reasoning over shared labels, topology, and temporal proximity alone is restricted to the same navigation problem a human faces, pivoting between signals without a model of why they are related. An agent reasoning over layers 4 through 6 can answer the questions that actually drive incident response, capacity planning, and change approval: what is causing this symptom, what is the blast radius of a degraded component, what configuration change would restore the constraint, and what would happen if that change were made. These questions do not require new data; the telemetry, configuration, and trace propagation already carry the raw signal. What they require is a model that the agent can reason against. One that encodes the causal, dependency, and constraint knowledge that today lives only in the engineers who happen to remember.&lt;/p&gt;

&lt;p&gt;Semantics is not an observability feature. It is the foundation that makes observability useful.&lt;/p&gt;

</description>
      <category>semantics</category>
      <category>context</category>
      <category>causality</category>
    </item>
    <item>
      <title>How to Turn Slow Queries into Actionable Reliability Metrics with OpenTelemetry</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Wed, 04 Feb 2026 10:11:00 +0000</pubDate>
      <link>https://dev.to/causely/how-to-turn-slow-queries-into-actionable-reliability-metrics-with-opentelemetry-4blj</link>
      <guid>https://dev.to/causely/how-to-turn-slow-queries-into-actionable-reliability-metrics-with-opentelemetry-4blj</guid>
      <description>&lt;p&gt;Slow SQL queries degrade user experience, cause cascading failures, and turn simple operations into production incidents. The traditional fix? Collect more telemetry. But more telemetry means more things to look at, not necessarily more understanding.&lt;/p&gt;

&lt;p&gt;Instead of treating traces as a data stream we might analyze someday, we should be opinionated about what matters at the moment of decision. As we argued in &lt;a href="https://www.causely.ai/blog/the-signal-in-the-storm?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;em&gt;The Signal in the Storm&lt;/em&gt;&lt;/a&gt;, raw telemetry only becomes useful when we extract meaningful patterns.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll build a repeatable workflow that turns OpenTelemetry database spans into span-derived metrics you can dashboard and alert on—so you can identify what’s slow, what matters most, and what just regressed.&lt;/p&gt;

&lt;p&gt;We’ll make this concrete with slow SQL queries, serving two use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Optimization&lt;/strong&gt; : Which queries yield the most value if made faster, weighted by traffic?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incident response&lt;/strong&gt; : Which queries are behaving abnormally &lt;em&gt;right now&lt;/em&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll build a &lt;a href="https://github.com/causely-oss/slow-query-lab?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;lab&lt;/a&gt; where your app emits &lt;a href="https://opentelemetry.io/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt; traces, and we distill those into actionable metrics, starting with simple slow query detection, then adding traffic-weighted impact, and finally anomaly detection.&lt;/p&gt;

&lt;p&gt;Want to skip the theory? Jump to the Lab. But the context helps you understand what you’re building.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes a Query Slow?
&lt;/h2&gt;

&lt;p&gt;“Slow” isn’t a single problem. It’s a symptom with fundamentally different causes. A 50ms query might be fine for a reporting dashboard but catastrophic for checkout. As &lt;a href="https://www.oreilly.com/library/view/high-performance-mysql/9781449332471/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;em&gt;High Performance MySQL&lt;/em&gt;&lt;/a&gt; emphasizes, understanding why a query is slow determines how to fix it. Here are the most common problems that may cause slow queries:&lt;/p&gt;

&lt;h3&gt;
  
  
  Excessive Work
&lt;/h3&gt;

&lt;p&gt;The database does more than necessary—typically full table scans due to missing or unusable indexes. Without an index on &lt;code&gt;customer_id&lt;/code&gt;, a simple &lt;code&gt;SELECT * FROM orders WHERE customer_id = $1&lt;/code&gt; grows from 20ms at 10K rows to minutes at 10M rows. The query didn’t change; the data volume did. See &lt;a href="https://use-the-index-luke.com/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;em&gt;Use The Index, Luke!&lt;/em&gt;&lt;/a&gt; for the fundamentals.&lt;/p&gt;

&lt;p&gt;Aggregations and joins compound this. Even indexed queries can explode when the planner misjudges cardinality and chooses the wrong join strategy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource Contention
&lt;/h3&gt;

&lt;p&gt;Perfectly optimized queries can be slow when waiting for resources. Lock contention blocks queries until other transactions release rows. Connection pool exhaustion adds latency before the query even starts. A query spending 95% of its time waiting for locks won’t be fixed by query optimization—it needs transaction redesign.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environmental Pressure
&lt;/h3&gt;

&lt;p&gt;CPU saturation, I/O bottlenecks, and memory pressure can slow any query. The same SQL with the same plan performs completely differently under resource contention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plan Regressions
&lt;/h3&gt;

&lt;p&gt;Performance degrades when execution plans change—even with identical queries and data. Parameter-sensitive plans optimize for one set of values but fail for others. Stale statistics after bulk loads cause the planner to choose terrible strategies. The &lt;a href="https://www.postgresql.org/docs/current/performance-tips.html?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;PostgreSQL Performance Tips&lt;/a&gt; documentation covers how to catch these regressions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pathological Patterns
&lt;/h3&gt;

&lt;p&gt;Some slowness doesn’t appear in slow query logs. The N+1 problem executes 100 fast queries (2ms each) sequentially, adding 200ms latency plus network overhead. No individual query is “slow,” but the pattern is catastrophic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The classic workflow: DB-native tooling + manual triage
&lt;/h2&gt;

&lt;p&gt;Databases ship with excellent diagnostic tools: slow query logs, query stores like PostgreSQL’s &lt;a href="https://www.postgresql.org/docs/current/pgstatstatements.html?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;code&gt;pg_stat_statements&lt;/code&gt;&lt;/a&gt;, and plan inspection with &lt;code&gt;EXPLAIN&lt;/code&gt;. These tell you what’s expensive inside the database.&lt;/p&gt;

&lt;p&gt;What they don’t provide is context. Which service triggered the slow query? Is it user-facing or background work? Does it correlate with the latency spike you’re investigating? You’re left with a list of slow queries and no signal about which ones matter most.&lt;/p&gt;

&lt;p&gt;Typically, someone bridges this gap manually: a developer notices a slow endpoint, brings the query to a DBA, and they optimize it together. This works, but that manual linking is exactly what we can automate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing Context to Slow Queries
&lt;/h2&gt;

&lt;p&gt;Database tools tell you what is slow, but not why it matters. When you find a slow query in your logs, you’re missing critical context: Which service triggered it? Is it user-facing or background work? Does it correlate with the latency spike you’re investigating?&lt;/p&gt;

&lt;p&gt;Distributed traces provide this context. Each database span is embedded in a request context—it knows which service, endpoint, and user triggered it.&lt;/p&gt;

&lt;p&gt;Instead of correlating database logs and traces after the fact, we analyze slow queries directly from traces with all the application context built in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Building Blocks
&lt;/h2&gt;

&lt;p&gt;Now that we understand the philosophy and the value of context-rich traces, let’s look at the building blocks we’ll use to implement slow query analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Observability Stack
&lt;/h3&gt;

&lt;p&gt;For our lab, we use the &lt;a href="https://opentelemetry.io/docs/collector/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;OpenTelemetry Collector&lt;/a&gt; paired with &lt;a href="https://github.com/grafana/docker-otel-lgtm?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;docker-otel-lgtm&lt;/a&gt;—a pre-packaged stack from Grafana that bundles Loki, Grafana, Tempo, and Mimir in a single container. This gives us a complete observability environment with minimal setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Application
&lt;/h3&gt;

&lt;p&gt;Our sample application is a simple Go-based “Album API” that serves music album data from PostgreSQL. It’s intentionally designed to produce the kind of intermittent slow queries that are common in production. They services use &lt;a href="https://github.com/XSAM/otelsql?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;otelsql&lt;/a&gt; to instrument database calls, emitting spans with the &lt;a href="https://opentelemetry.io/docs/specs/semconv/database/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;stable OpenTelemetry database semantic conventions&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dashboards
&lt;/h3&gt;

&lt;p&gt;We’ll build three dashboards, each adding a layer of insight:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A simple view of the queries by duration&lt;/li&gt;
&lt;li&gt;Queries weighted by traffic to surface optimization opportunities&lt;/li&gt;
&lt;li&gt;Anomaly detection to identify queries deviating from their normal behavior&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Lab Setup
&lt;/h2&gt;

&lt;p&gt;Let’s put the theory into practice. We’ll clone a &lt;a href="https://github.com/causely-oss/slow-query-lab?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;sample application&lt;/a&gt;, start the observability stack, and explore three progressively more sophisticated approaches to slow query analysis. All you need is &lt;a href="https://www.docker.com/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; installed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clone and Run
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/causely-oss/slow-query-lab
cd slow-query-lab
docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once running, open Grafana at &lt;a href="http://localhost:3001/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;http://localhost:3001&lt;/a&gt;—that’s where we’ll explore our dashboards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Queries by Duration
&lt;/h2&gt;

&lt;p&gt;The first dashboard takes the most direct approach: query Tempo for database spans and aggregate them to find queries that take the longest time. This is what you’d naturally build when you first start exploring traces for slow query analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  What It Shows
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Slow SQL - By Duration&lt;/strong&gt; dashboard queries traces directly using TraceQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ span.db.system != "" } | select(span.db.query.text, span.db.statement)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This finds all spans with database attributes, then uses Grafana transformations to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Group by&lt;/strong&gt; root operation (API endpoint) and SQL statement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aggregate&lt;/strong&gt; duration into mean, max, and count&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sort by&lt;/strong&gt; average duration (slowest first)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is a table showing your slowest queries, which endpoints triggered them, and how often they occur.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17d2ukqw1j0kmt4vz8ox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F17d2ukqw1j0kmt4vz8ox.png" alt="How to Turn Slow Queries into Actionable Reliability Metrics with OpenTelemetry" width="800" height="214"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Slowest queries by root operation&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  What’s Good About This
&lt;/h3&gt;

&lt;p&gt;This approach gives you immediate visibility into queries with full application context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can see exactly which SQL statements are taking the most time&lt;/li&gt;
&lt;li&gt;You know which API endpoints trigger them&lt;/li&gt;
&lt;li&gt;You have the count to understand frequency&lt;/li&gt;
&lt;li&gt;You can click through to individual traces for debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a first improvement over raw database logs because you’re already seeing the application context that makes slow queries actionable.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Limitation
&lt;/h3&gt;

&lt;p&gt;Here’s the problem: sorting by average duration doesn’t tell you which queries matter most.&lt;/p&gt;

&lt;p&gt;Consider two queries:&lt;/p&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;Avg Duration&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Complex report&lt;/td&gt;
&lt;td&gt;2.3s&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;150ms&lt;/td&gt;
&lt;td&gt;10,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;The complex report is “slower” by average duration, so it appears first. But the search query, despite being faster on average, runs 2,000 times more often. Its aggregate impact on your users is far greater.&lt;/p&gt;

&lt;p&gt;This dashboard tells you what’s slow, but not what’s &lt;em&gt;impactful&lt;/em&gt;. For that, we need to consider traffic volume.&lt;/p&gt;
&lt;h2&gt;
  
  
  Traffic-Weighted Impact Analysis
&lt;/h2&gt;

&lt;p&gt;The second dashboard addresses this limitation by introducing an &lt;strong&gt;impact score&lt;/strong&gt; : the product of average duration and call count.&lt;/p&gt;
&lt;h3&gt;
  
  
  What It Shows
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Slow SQL - Traffic Weighted&lt;/strong&gt; dashboard uses the same TraceQL query but adds a calculated field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Impact = Avg Duration × Count
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple formula captures a key insight: a moderately slow query that runs thousands of times has more total impact than a very slow query that runs rarely. The dashboard sorts by impact score, surfacing the queries that matter most to your users.&lt;/p&gt;

&lt;p&gt;The dashboard also adds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service breakdown&lt;/strong&gt; : See which service triggered each query&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency distribution&lt;/strong&gt; : Visualize duration over time, not just averages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Top queries by impact&lt;/strong&gt; : A quick view of where to focus optimization efforts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt2mkr8fmwq1msgf8d7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt2mkr8fmwq1msgf8d7y.png" alt="How to Turn Slow Queries into Actionable Reliability Metrics with OpenTelemetry" width="800" height="212"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Highest impact queries by root operation&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  What’s Good About This
&lt;/h3&gt;

&lt;p&gt;Traffic-weighted impact gives you a much better prioritization signal for optimization work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High-volume, moderately-slow queries surface above rare-but-slow ones&lt;/li&gt;
&lt;li&gt;You can justify optimization work with concrete impact numbers&lt;/li&gt;
&lt;li&gt;The service and endpoint context helps you route issues to the right team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When someone asks “which slow queries should we optimize first?”, this dashboard gives you a defensible answer. It’s exactly what you need for planning performance improvements.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Limitation
&lt;/h3&gt;

&lt;p&gt;But this dashboard is for optimization, not incident response. Even with traffic-weighted impact, it can’t answer a critical question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“What has changed?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suppose your search query has an impact score of 150,000. Is that normal? Is it higher than yesterday? Higher than last week? The dashboard shows you a snapshot of current state, but it has no concept of baseline.&lt;/p&gt;

&lt;p&gt;This matters enormously during incidents. When latency spikes, you don’t just want to know “search queries are slow”—you want to know “search queries are slower than normal”. You need to distinguish between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A query that’s always been slow (known behavior, maybe acceptable)&lt;/li&gt;
&lt;li&gt;A query that just became slow (new problem, needs investigation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a baseline, every slow query looks the same. You’re left manually comparing current values to your memory of what’s “normal,” or digging through historical data to establish context.&lt;/p&gt;

&lt;p&gt;This is the gap that the third dashboard addresses.&lt;/p&gt;
&lt;h2&gt;
  
  
  Symptom Detection with Anomaly Baselines
&lt;/h2&gt;

&lt;p&gt;Because of these limitations, the third dashboard changes our approach: instead of just querying traces, we distill metrics from spans and then apply anomaly detection to identify deviations from normal behavior.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Setup
&lt;/h3&gt;

&lt;p&gt;For this dashboard, we add the &lt;code&gt;spanmetrics&lt;/code&gt; connector to the OpenTelemetry Collector. Here’s the relevant part of the collector configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;connectors:
  spanmetrics:
    dimensions:
      - name: db.system
        default: "unknown"
      - name: db.query.text
      - name: db.statement
      - name: db.name
        default: "unknown"
    exemplars:
      enabled: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [transform, batch]
      exporters: [spanmetrics, otlphttp/lgtm]

    metrics:
      receivers: [spanmetrics]
      processors: [batch]
      exporters: [otlphttp/lgtm]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;spanmetrics&lt;/code&gt; connector examines every database span and generates histogram metrics for query latency, labeled by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;service_name&lt;/code&gt;: Which service made the query&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;db_system&lt;/code&gt;: Database type (postgresql)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;db_query_text&lt;/code&gt; or &lt;code&gt;db_statement&lt;/code&gt;: The SQL query&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;db_name&lt;/code&gt;: Database name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics are stored in Mimir (the Prometheus-compatible backend in docker-otel-lgtm), where we can apply PromQL-based anomaly detection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anomaly Detection with Adaptive Baselines
&lt;/h3&gt;

&lt;p&gt;The sample app includes Prometheus recording rules from Grafana’s &lt;a href="https://github.com/grafana/promql-anomaly-detection?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;PromQL Anomaly Detection&lt;/a&gt; framework. These rules calculate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Baseline&lt;/strong&gt; : A smoothed average of historical values (what’s “normal”)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upper band&lt;/strong&gt; : Baseline + N standard deviations (upper threshold)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lower band&lt;/strong&gt; : Baseline - N standard deviations (lower threshold)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When current values exceed the bands, we have an anomaly—a clear signal that something has changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What It Shows
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Slow SQL - Anomaly Detection&lt;/strong&gt; dashboard displays:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Current latency&lt;/strong&gt; plotted against the adaptive baseline bands&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anomaly indicators&lt;/strong&gt; when latency exceeds normal bounds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-query breakdown&lt;/strong&gt; so you can see which specific queries are anomalous&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key insight is the visual comparison: instead of just showing “p95 latency is 450ms”, it shows “p95 latency is 450ms, which is above the expected range of 200-350ms.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd3ya7iegcnsb9pmqwow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd3ya7iegcnsb9pmqwow.png" alt="How to Turn Slow Queries into Actionable Reliability Metrics with OpenTelemetry" width="800" height="256"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Query latency with anomaly bands&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Is Better
&lt;/h3&gt;

&lt;p&gt;This dashboard answers the question the previous one couldn’t: “What has changed?”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A query that’s always slow (450ms baseline) won’t trigger anomalies when it runs at 450ms&lt;/li&gt;
&lt;li&gt;A query that’s normally fast (50ms baseline) will trigger anomalies if it suddenly runs at 200ms&lt;/li&gt;
&lt;li&gt;You get automatic context for what’s “normal” without maintaining manual thresholds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The anomaly detection acts as a symptom detector. It tells you: “This query is behaving differently than it usually does.” That’s a high-signal insight you can act on immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  From Metrics to Symptoms
&lt;/h3&gt;

&lt;p&gt;Notice what we’ve achieved with this architecture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Raw telemetry&lt;/strong&gt; (traces) flows from the application&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distillation&lt;/strong&gt; (spanmetrics connector) extracts metrics from those traces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anomaly detection&lt;/strong&gt; (Prometheus rules) identifies deviations from baseline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Symptoms&lt;/strong&gt; (anomalous queries) surface for investigation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We went from thousands of trace spans to a handful of anomaly signals that tell you exactly where to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking This to Production
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Metric Cardinality
&lt;/h3&gt;

&lt;p&gt;Raw SQL in metric labels will explode your metrics backend—&lt;code&gt;SELECT * FROM orders WHERE customer_id = 12345&lt;/code&gt; becomes a separate series per customer. Use prepared statements (so instrumentation captures templates, not literals), normalize query text, or use &lt;code&gt;aggregation_cardinality_limit&lt;/code&gt; in the spanmetrics connector.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;SQL may contain sensitive data. The Collector is the ideal place to redact: drop or transform sensitive attributes before shipping downstream. This aligns with distillation: sanitize at the edge, not centrally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anomaly Detection Baseline
&lt;/h3&gt;

&lt;p&gt;Adaptive rules need 24-48 hours of data to establish baselines. Start with wider bands and tighten as confidence grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Remaining Gap: From Symptoms to Root Causes
&lt;/h2&gt;

&lt;p&gt;Even with anomaly detection, you’re still looking at symptoms. In real-world incident scenarios, especially in large environments, slow queries are just one of many symptoms that pop up at once. You’re not only trying to understand the cause of this one; you’re triaging a flood of alerts and correlating many symptoms to find the real root cause.&lt;/p&gt;

&lt;p&gt;When the dashboard shows “search query latency spiked,” you know something changed. But you don’t know &lt;em&gt;why&lt;/em&gt; it changed. The root cause might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A missing index after a schema migration&lt;/li&gt;
&lt;li&gt;Query plan regression due to stale statistics&lt;/li&gt;
&lt;li&gt;Lock contention from a concurrent batch job&lt;/li&gt;
&lt;li&gt;Resource pressure from a noisy neighbor on the database host&lt;/li&gt;
&lt;li&gt;Upstream service degradation causing retry storms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connecting the symptom (“search query is slow”) to the root cause (“index was dropped during last night’s migration”) requires causal reasoning—understanding the relationships between system components and tracing the chain of causation from effect back to cause.&lt;/p&gt;

&lt;p&gt;You can absolutely do this reasoning yourself. Look at deployment timestamps, check for schema changes, investigate resource metrics, correlate with other symptoms. Good engineers do this every day.&lt;/p&gt;

&lt;p&gt;But it’s manual, time-consuming, and doesn’t scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Going Beyond Symptoms with Causely
&lt;/h3&gt;

&lt;p&gt;This is where Causely comes in: Causely extracts slow queries (and other symptoms) as distilled insights out of the box—the same pattern we implemented manually. But it goes further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.causely.ai/getting-started/how-causely-works/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;strong&gt;Causal model&lt;/strong&gt;&lt;/a&gt;: Slow queries are connected into a model of your system’s dependencies. You can see what they &lt;em&gt;impact&lt;/em&gt; (which endpoints, which users) and what &lt;em&gt;causes&lt;/em&gt; them (resource constraints, upstream failures, configuration changes).&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.causely.ai/in-action/root-causes/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;strong&gt;Root cause identification&lt;/strong&gt;&lt;/a&gt;: Instead of showing you a list of symptoms to investigate, Causely traces causation chains to identify the underlying root cause. “Search queries are slow &lt;em&gt;because&lt;/em&gt; the index was dropped.”&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.causely.ai/in-action/ask-causely/?ref=causely-blog.ghost.io#analyzing-slow-sql-queries" rel="noopener noreferrer"&gt;&lt;strong&gt;Actionable recommendations&lt;/strong&gt;&lt;/a&gt;: AskCausely helps you get to “what should we change?”—whether that’s adding an index, reverting a deployment, or addressing the upstream pressure that made the query slow in the first place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern we built in this post—distill, detect anomalies, surface symptoms—is the foundation. Causely is the natural next step: turning symptoms into root causes at scale.&lt;/p&gt;

&lt;p&gt;Want to see how Causely connects your slow queries to their root causes? &lt;a href="https://www.causely.ai/try?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;Try it yourself&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudatbb35lga41agzbhmf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudatbb35lga41agzbhmf.png" alt="How to Turn Slow Queries into Actionable Reliability Metrics with OpenTelemetry" width="800" height="911"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Ask Causely about slow queries&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opentelemetry</category>
      <category>sql</category>
      <category>postgres</category>
    </item>
    <item>
      <title>When Asynchronous Systems Fail Quietly, Reliability Teams Pay the Price</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Wed, 28 Jan 2026 20:19:59 +0000</pubDate>
      <link>https://dev.to/causely/when-asynchronous-systems-fail-quietly-reliability-teams-pay-the-price-2h1c</link>
      <guid>https://dev.to/causely/when-asynchronous-systems-fail-quietly-reliability-teams-pay-the-price-2h1c</guid>
      <description>&lt;p&gt;In our previous post, &lt;a href="https://www.causely.ai/blog/queue-growth-dead-letter-queues-and-why-asynchronous-failures-are-easy-to-misread?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;u&gt;Queue Growth, Dead Letter Queues, and Why Asynchronous Failures Are Easy to Misread&lt;/u&gt;&lt;/a&gt;, we described a failure pattern that plays out repeatedly in modern systems built on asynchronous messaging. &lt;/p&gt;

&lt;p&gt;A queue starts to grow slowly. Nothing looks obviously broken at first. Publish calls are succeeding and consumers are still running, just not quite keeping up. Over time, messages begin to age out, and dead-letter queues start accumulating entries. Downstream services that depend on those messages begin to behave unpredictably. There are partial data, delayed processing and subtle customer-facing issues that are hard to tie back to a single event. By the time the impact is visible in latency or error rates elsewhere in the system, the original cause is buried several layers upstream and hours in the past. &lt;/p&gt;

&lt;p&gt;Teams do not miss these failures because they lack data. They miss them because the signals do not point clearly to the cause. &lt;/p&gt;

&lt;p&gt;Over the past several weeks, we’ve expanded Causely’s asynchronous and messaging queue capabilities to make these failures explicit, explainable, and actionable. This includes:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expanding Causal Model for&lt;a href="https://docs.causely.ai/changelog/v1.0.108/?ref=causely-blog.ghost.io#expanded-messaging-queue-causal-model" rel="noopener noreferrer"&gt; &lt;u&gt;Amazon&lt;/u&gt; &lt;u&gt;SNS&lt;/u&gt; &lt;u&gt;and&lt;/u&gt; &lt;u&gt;SQS and RabbitMQ&lt;/u&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;A new &lt;a href="https://docs.causely.ai/reference/root-causes/applications/?ref=causely-blog.ghost.io#producer-publish-rate-spike" rel="noopener noreferrer"&gt;&lt;u&gt;Producer Publish Rate Spike&lt;/u&gt;&lt;/a&gt; root cause
&lt;/li&gt;
&lt;li&gt;And adding &lt;a href="https://docs.causely.ai/changelog/v1.0.109/?ref=causely-blog.ghost.io#expanded-causal-model-for-asynchronous-communications" rel="noopener noreferrer"&gt;&lt;u&gt;Queue Size Growth and Dead-letter Queue&lt;/u&gt;&lt;/a&gt; as first class symptoms to our model
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Reliability Blind Spot in Messaging-Driven Architectures&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Asynchronous communication is foundational to how modern systems scale. The same advantages systems like Kafka and RabbitMQ provide, decoupling services and absorbing traffic spikes, also introduce new reliability challenges. &lt;/p&gt;

&lt;p&gt;The core issue is not that these systems fail quietly, but that cause and effect are separated. A producer can overload the system without returning errors. A broker can continue accepting traffic while consumers fall behind. By the time downstream symptoms appear, the triggering behavior has often already passed. &lt;/p&gt;

&lt;p&gt;For engineering managers and or those on the frontline of the on-call slack channel, this creates a familiar and frustrating dynamic. Reliability degrades without a clear trigger. Incident response turns into a debate about whether the producer or consumer is responsible. Teams chase anomalies across dashboards while backlogs continue to grow. By the time a decisive action is taken, the customer impact is already real. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Traditional Observability Falls Short&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Metrics, logs, and traces are excellent at answering local questions. They tell you what a service is doing, how long an operation took, or how many messages are currently sitting in a queue. &lt;/p&gt;

&lt;p&gt;What they do not provide is causal understanding across asynchronous boundaries. &lt;/p&gt;

&lt;p&gt;In messaging-driven systems, cause and effect are separated in time and space. A spike in publish rate from one service may not create visible impact until hours later, in a different service, owned by a different team. A slow consumer may be the result of downstream backpressure rather than a defect in the consumer itself. Dead-letter queues tell you that messages failed, but not why the system reached that state. &lt;/p&gt;

&lt;p&gt;Without a causal model of how producers, exchanges, queues, and consumers interact, teams are forced to infer failures indirectly. That inference is slow, fragile, and heavily dependent on tribal knowledge. Under pressure, it leads to overcorrection, unnecessary rollbacks, and missed root causes. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Expanding the Causal Model for Messaging Systems&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To close this gap, we have significantly expanded Causely’s causal model for asynchronous messaging systems. &lt;/p&gt;

&lt;p&gt;Rather than treating queues as opaque buffers, Causely now models messaging infrastructure the way it actually operates in production. Producers, exchanges, queues, and consumers are represented as distinct entities with explicit relationships and data flows. This applies across common technologies, including Amazon SQS, Amazon SNS, and RabbitMQ, whether used in simple queue mode or exchange-based pub/sub patterns. &lt;/p&gt;

&lt;p&gt;By modeling the topology directly, Causely can reason about how work enters the system, how it is routed, where it accumulates, and how pressure propagates across services. This makes it possible to explain failures that previously required intuition and guesswork. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7idzjqnyjqzk0d62avnv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7idzjqnyjqzk0d62avnv.png" alt="When Asynchronous Systems Fail Quietly, Reliability Teams Pay the Price" width="800" height="488"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Causely Dataflow Map makes it easy for engineers to understand how data moves between services and exchanges and queues that make up Amazon SQS and SNS and RabbitMQ&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Making Queue Growth and Dead-Letter Failures First-Class Signals&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;We have also expanded the causal model to treat queue size growth and dead-letter queue activity as first-class symptoms, not secondary indicators. &lt;/p&gt;

&lt;p&gt;This changes how asynchronous failures are diagnosed. Instead of surfacing queue metrics as passive signals, Causely reasons about them causally, linking backlog growth and dead-letter events directly to the producers, consumers, and operations involved. &lt;/p&gt;

&lt;p&gt;As a result, queue-related failures are no longer inferred indirectly from downstream latency or error spikes. The failure mode is explicit, explainable, and traceable to the point where intervention is most effective.  &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A New Root Cause: Producer Publish Rate Spike&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most common and least understood asynchronous failure modes is a sudden change in publish behavior. Causely now includes a dedicated root cause for this pattern: Producer Publish Rate Spike. &lt;/p&gt;

&lt;p&gt;This occurs when a service, HTTP path, or RPC method begins publishing messages at a significantly higher rate than normal. The increase may be triggered by a code change, a configuration update, or an unexpected shift in traffic patterns. Downstream queues absorb the initial surge, but consumers cannot keep up indefinitely. Queue depth grows, message age increases, and backpressure begins to affect the rest of the system. &lt;/p&gt;

&lt;p&gt;What makes this failure particularly dangerous is that the producer often looks healthy. Publish requests succeed, error rates remain low, and nothing appears obviously wrong at the source. Without causal reasoning, teams frequently blame consumers or infrastructure capacity, missing the true trigger entirely. &lt;/p&gt;

&lt;p&gt;Causely now detects this condition explicitly. It ties unexpected increases in publish rate to queue growth, consumer pressure, and downstream service degradation, making the failure both visible and explainable. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjh5yrkwhbcbc0gn2ab3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjh5yrkwhbcbc0gn2ab3.png" alt="When Asynchronous Systems Fail Quietly, Reliability Teams Pay the Price" width="800" height="382"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Understanding the cause of increased queue depths , causing performance degradation&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What This Changes for Reliability Teams&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For teams responsible for revenue-critical services, these capabilities change how asynchronous failures are handled in practice. &lt;/p&gt;

&lt;p&gt;Instead of reacting after queues are saturated and customers are impacted, teams can see which producer initiated the failure, how pressure propagated through the messaging system, and where intervention will have the greatest effect. Slow consumers, misconfigured routing, and unexpected publish spikes are distinguished clearly rather than conflated into a single “queue issue.” &lt;/p&gt;

&lt;p&gt;This shortens incident response, reduces unnecessary mitigation, and eliminates the finger-pointing that often arises when failures span multiple teams. More importantly, it enables a proactive reliability posture in systems that are constantly changing. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Asynchronous Reliability Without Guesswork&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Asynchronous architectures are essential for scale, but they demand a different approach to reliability than synchronous request paths. &lt;/p&gt;

&lt;p&gt;With its expanded messaging and asynchronous causal model, Causely provides deterministic, explainable reasoning over how data flows through your system. Teams do not need to stitch together dashboards to reconstruct timelines after the fact. They do not need to trust black-box AI summaries that cannot explain their conclusions. They no longer have to exhaustively eliminate possibilities to arrive at a root cause. &lt;/p&gt;

&lt;p&gt;Instead, they get clear answers to the questions that matter most: what is breaking, why it is breaking, and where to act first to protect reliability and revenue.&lt;/p&gt;

</description>
      <category>causely</category>
      <category>async</category>
      <category>sre</category>
    </item>
    <item>
      <title>Alerts Aren’t the Investigation</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Thu, 22 Jan 2026 16:59:39 +0000</pubDate>
      <link>https://dev.to/causely/alerts-arent-the-investigation-161j</link>
      <guid>https://dev.to/causely/alerts-arent-the-investigation-161j</guid>
      <description>&lt;p&gt;PagerDuty fires: CheckoutAPI burn rate (2m/1h). Grafana shows p99 going from ~120ms to ~900ms. Retries doubled. DB CPU is flat, but checkout pods are throttling and a downstream dependency’s error budget is evaporating. Ten minutes in, you’ve collected artifacts, not understanding.&lt;/p&gt;

&lt;p&gt;If you’ve been on call, you’ve seen this movie.&lt;/p&gt;

&lt;p&gt;This is also why plenty of “AI-powered observability” rollouts still don’t change the lived experience of on-call. Leadership expects response times to improve. On-call gets richer dashboards, smarter summaries, and more plausible explanations. To be fair, those do help with faster lookup and briefing in the room, but the social reality stays the same: alerts get silenced in PagerDuty, rules get tagged as “flappy,” and old pages keep firing long after anyone can justify what they were meant to protect. The problem isn’t effort. It’s that the page still doesn’t reliably collapse into shared understanding. Call it the Page-to-Understanding Gap: the time and coordination cost of turning a threshold into a system story.&lt;/p&gt;

&lt;p&gt;Alerts are supposed to start an investigation. Too often, they start translation: &lt;em&gt;what is the system doing right now?&lt;/em&gt; That translation slows containment, splinters context, and stretches customer impact. &lt;/p&gt;

&lt;p&gt;That decoding work is what incident response depends on, yet it’s rarely made explicit. It’s why MTTR gains often plateau even after teams invest heavily in monitoring and dashboards. &lt;/p&gt;

&lt;h2&gt;
  
  
  Alerts are a paging interface, not a language of explanation
&lt;/h2&gt;

&lt;p&gt;Alerting is optimized for one job: interrupt a human at the right moment. &lt;/p&gt;

&lt;p&gt;So alerts are built from what’s easiest to express at scale: thresholds, proxy signals, and rules that “usually work.” They encode operational history, not system truth. &lt;/p&gt;

&lt;p&gt;That’s not a failure of alerting. It’s what alerting is for, but it also makes alerts a shaky foundation for understanding. They’re a simplified label over messy reality. When alerts aren’t grounded in clear definitions of “healthy” behavior, the signal loses meaning and teams stop trusting it. &lt;/p&gt;

&lt;h2&gt;
  
  
  One alert name can mean multiple different realities
&lt;/h2&gt;

&lt;p&gt;Take a familiar page: “latency high,” or the modern equivalent: an SLO burn rate page. &lt;/p&gt;

&lt;p&gt;Burn rate fires on checkout. You assume checkout is slow, start in the service dashboard, see p99 up, then notice retries doubled. Meanwhile, Slack is already split: “DB” vs. “checkout.” Fifteen minutes later you realize a downstream dependency is brownouting and checkout is just drowning in retries. The giveaway is usually the shape: one hop shows rising timeouts and retry storms while upstream looks "healthy" until it saturates. The alert didn’t lie—it just didn’t tell you what you needed first. &lt;/p&gt;

&lt;p&gt;The page looks identical. The mechanism isn’t. &lt;/p&gt;

&lt;p&gt;So teams build muscle memory around “what usually causes this,” and it works—until the system changes just enough that it stops working. Scale and change are exactly what modern organizations optimize for, so the failure mode is guaranteed. When that happens, the alert doesn’t just wake you up. It points you in the wrong direction. &lt;/p&gt;

&lt;h2&gt;
  
  
  Many alerts can describe the same underlying behavior
&lt;/h2&gt;

&lt;p&gt;The reverse problem happens just as often. A single degradation creates a cascade of pages across services: latency, errors, saturation, queueing, burn rate alarms. Each is technically “true,” but treating them as separate problems creates thrash. &lt;/p&gt;

&lt;p&gt;People split into parallel investigations, duplicate context gathering, and argue about which page is “the real one.” Context fragments across Slack threads and war rooms, ownership ping‑pongs, and escalations get noisy. By the time you agree which page is “primary,” you’ve already created a coordination incident. The outcome isn’t just wasted engineer time—it’s that nobody has one shared narrative everyone can repeat while impact is unfolding. The incident becomes less about understanding and more about sorting competing signals. This is how alert fatigue turns into incident fatigue. &lt;/p&gt;

&lt;h2&gt;
  
  
  The silent gap: important behavior you don’t alert on
&lt;/h2&gt;

&lt;p&gt;The costly ones are the slow degradations that ship impact before they page. &lt;/p&gt;

&lt;p&gt;A dependency gets a little slower. Retries creep up. One critical route starts timing out for a slice of customers. Averages look fine. Thresholds don’t trip. You don’t notice until the page fires, or until customers do. &lt;/p&gt;

&lt;p&gt;It’s not that teams don’t care. It’s that these behaviors don’t fit neatly into alert rules: risk builds up, dependencies decay, partial impact hides in aggregates, and propagation only makes sense once you’ve traced it end to end. &lt;/p&gt;

&lt;p&gt;Most alerts only get defined after you’ve understood the behavior in the middle of an incident. The post-mortem produces a new rule and a brief feeling of closure. Then traffic shifts, dependencies evolve, and the next incident arrives with a different shape. You’re never done. &lt;/p&gt;

&lt;p&gt;So teams find these late, after impact is already underway, when time is most expensive. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why teams don’t switch investigation entry points
&lt;/h2&gt;

&lt;p&gt;When teams adopt a new investigation system, they often ask a simple question: “Does it match our alerts?” &lt;/p&gt;

&lt;p&gt;What they’re really asking is: “Can I trust this in the first 90 seconds?” Because in the first minute, the primary goal isn’t elegance, it’s not making it worse.&lt;/p&gt;

&lt;p&gt;A system that generates more hypotheses doesn’t help if it can’t connect the page to what the system is doing in a way the on-call trusts. &lt;/p&gt;

&lt;p&gt;If the system describes an incident in a different language than the alert model engineers rely on, mismatches get interpreted as duplication, contradiction, or risk. The result is predictable: people consult it late, after they’ve already committed to a direction. &lt;/p&gt;

&lt;p&gt;Even correct insights arrive too late to change behavior. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why this problem is getting worse
&lt;/h2&gt;

&lt;p&gt;Systems are becoming more dynamic: more dependencies, faster deploys, and more integration points. Deploy frequency keeps climbing—and AI-assisted coding is only accelerating it—so the number of failure paths keeps growing. Meanwhile, alert fatigue is already high, and teams are hesitant to change workflows mid-incident. &lt;/p&gt;

&lt;p&gt;Better tooling can speed up lookup and correlation, but it can’t compensate for an alerting model that no longer maps cleanly to real system behavior. &lt;/p&gt;

&lt;p&gt;So the interpretation workload keeps rising. Every page demands more interpretation, more cross-checking, more manual stitching of symptoms into a coherent story. &lt;/p&gt;

&lt;h2&gt;
  
  
  What’s actually broken
&lt;/h2&gt;

&lt;p&gt;Most organizations are operating with two different languages: the language of paging and the language of understanding. The persistent MTTR plateau is the Page-to-Understanding Gap between them.&lt;/p&gt;

&lt;p&gt;Incidents start with the first, but the work happens in the second. &lt;/p&gt;

&lt;h2&gt;
  
  
  A better way to think about alerts
&lt;/h2&gt;

&lt;p&gt;Alerts are not the investigation. They’re a notification that something is going sideways. &lt;/p&gt;

&lt;p&gt;The goal is not to tune thresholds until the noise feels tolerable. It’s to shorten the time from page to shared understanding: what behavior is emerging, what changed, what’s being impacted—and whether it matters to the business. &lt;/p&gt;

&lt;p&gt;Treating that translation as unwritten know‑how is not a workflow quirk. It’s a structural weakness. If your incident response starts with decoding alerts, you’re spending your best engineers on interpretation instead of containment.&lt;/p&gt;

</description>
      <category>alerts</category>
      <category>causely</category>
      <category>investigation</category>
    </item>
    <item>
      <title>Queue Growth, Dead-Letter Queues, and Why Asynchronous Failures Are Easy to Misread</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Tue, 20 Jan 2026 19:18:45 +0000</pubDate>
      <link>https://dev.to/causely/queue-growth-dead-letter-queues-and-why-asynchronous-failures-are-easy-to-misread-ng2</link>
      <guid>https://dev.to/causely/queue-growth-dead-letter-queues-and-why-asynchronous-failures-are-easy-to-misread-ng2</guid>
      <description>&lt;p&gt;Asynchronous pipelines sit at the core of most modern systems. Message brokers accept traffic, consumers process it in the background, and downstream services depend on the results.&lt;/p&gt;

&lt;p&gt;When these systems fail, the failure rarely shows up where it starts.&lt;/p&gt;

&lt;p&gt;Teams often notice stale data, degraded behavior, or latency spikes elsewhere in the system. By the time those symptoms appear, the underlying problem has usually been present for some time.&lt;/p&gt;

&lt;p&gt;In many real-world failures, two signals appear earlier: &lt;strong&gt;queue growth&lt;/strong&gt; and &lt;strong&gt;dead-letter queues&lt;/strong&gt;. They are widely monitored, but they are still widely misunderstood.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The common misunderstanding&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Queues are often treated as infrastructure components rather than behavioral signals. When a queue grows, it is attributed to load. When messages land in a DLQ, it is treated as a retry policy doing its job. Investigation tends to focus downstream, where symptoms are visible.&lt;/p&gt;

&lt;p&gt;This framing obscures where asynchronous systems actually break. In many failures, message brokers continue to accept traffic normally. Producers succeed. Nothing looks obviously down. The problem is that consumers are no longer able to keep up reliably or consistently. That distinction matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Queue growth is not just volume&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Queue growth occurs when messages arrive faster than they can be processed successfully over time. This does not require a traffic spike. It can result from: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consumers slowing due to code changes or resource pressure &lt;/li&gt;
&lt;li&gt;Dependencies becoming latent or unreliable &lt;/li&gt;
&lt;li&gt;Retry rates increasing &lt;/li&gt;
&lt;li&gt;Backpressure failing to engage &lt;/li&gt;
&lt;li&gt;Partition skew concentrating work unevenly &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In these cases, the broker behaves correctly. Messages are accepted. The queue grows quietly. What is accumulating is &lt;strong&gt;lag&lt;/strong&gt;. A sustained backlog means work is no longer flowing through the system at the intended rate, even if no explicit failures are visible yet.  &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why this matters before anything looks broken&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Asynchronous systems are designed to absorb instability. Queues buffer mismatches. Retries smooth over failures. Backlogs delay visible impact. This is useful, but it also postpones feedback. As queues grow: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processing time increases &lt;/li&gt;
&lt;li&gt;Derived state falls behind &lt;/li&gt;
&lt;li&gt;Downstream services operate on increasingly stale or incomplete data &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The transition from “degraded” to “broken” often appears sudden because the system has been accumulating lag for some time before any external threshold is crossed. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Dead-letter queues signal a different failure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Dead-letter queues exist to capture messages that cannot be processed successfully. Messages land there after repeated failures, timeouts, or deterministic errors. DLQs prevent infinite retries and protect the main pipeline. What they represent is not transient instability, but &lt;strong&gt;persistent processing failure under current system behavior&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;A non-empty DLQ means some class of messages cannot be handled as the system is currently operating. That incompatibility can come from: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Broken contracts between producers and consumers &lt;/li&gt;
&lt;li&gt;Partial or skewed deployments &lt;/li&gt;
&lt;li&gt;Schema drift &lt;/li&gt;
&lt;li&gt;Unhandled edge cases &lt;/li&gt;
&lt;li&gt;Dependencies that fail consistently rather than intermittently &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DLQs often grow alongside backlogs, but they can also appear independently. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why these problems are so common&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In real systems, producers and consumers evolve independently. Load shifts. Dependencies degrade. Retry behavior changes system dynamics in non-obvious ways. It is common for: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brokers to continue accepting traffic &lt;/li&gt;
&lt;li&gt;Queues to grow steadily &lt;/li&gt;
&lt;li&gt;Consumers to fail intermittently or slow down &lt;/li&gt;
&lt;li&gt;Processing failures to accumulate quietly &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Operationally, queues and DLQs sit between services. They rarely have clear ownership. They are easy to monitor superficially and hard to reason about in context. As a result, many teams only notice these issues once downstream behavior degrades.  &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Queue growth and DLQs are related, but distinct&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Queue growth and DLQs are often discussed together, but they answer different questions. &lt;/p&gt;

&lt;p&gt;Queue growth asks: "Are messages flowing through the system fast enough?"&lt;/p&gt;

&lt;p&gt;DLQs ask:  "Are some messages failing to be processed at all?"&lt;/p&gt;

&lt;p&gt;In many incidents, sustained queue growth precedes DLQs. Consumers slow down, retries increase, and retry limits are eventually exceeded. In others, DLQs appear immediately due to deterministic processing failures, even while queue depth looks healthy. Treating one as a proxy for the other creates blind spots. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The deeper diagnostic challenge&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most teams diagnose asynchronous failures indirectly. They look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency spikes &lt;/li&gt;
&lt;li&gt;Error rates &lt;/li&gt;
&lt;li&gt;Timeouts &lt;/li&gt;
&lt;li&gt;User-visible symptoms &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those signals matter, but they are downstream effects. Earlier and more precise signals exist inside the message pipeline itself: where messages are accepted, where they slow down, and where they fail to be processed reliably. When those signals are ignored or misinterpreted, teams spend time chasing symptoms rather than isolating where the workflow is actually breaking.  &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A better way to think about queues&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Queues are not just buffers. Queue growth is not harmless backlog. Dead-letter queues are not operational exhaust. They are indicators of whether asynchronous workflows are functioning as intended or quietly degrading under real conditions. &lt;/p&gt;

&lt;p&gt;The goal is not to watch queue depth, instead, it’s to continuously understand flow: where work accumulates, why it accumulates, and which downstream interactions it impacts. &lt;/p&gt;

&lt;p&gt;Understanding them is not an optimization. It is foundational to operating reliable, event-driven systems.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>microservices</category>
      <category>performance</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Slight Reliability EP 113: AI Use-cases for SRE with Shmuel Kliger</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Mon, 12 Jan 2026 19:31:00 +0000</pubDate>
      <link>https://dev.to/causely/slight-reliability-ep-113-ai-use-cases-for-sre-with-shmuel-kliger-38ge</link>
      <guid>https://dev.to/causely/slight-reliability-ep-113-ai-use-cases-for-sre-with-shmuel-kliger-38ge</guid>
      <description>&lt;p&gt;From the day we invented computers we've been struggling to keep applications running and delivering services to the business. Is this latest wave of AI helping or hurting us?  &lt;/p&gt;

&lt;p&gt;This week I'm joined by Causely founder Shmuel Kliger to dive into...  &lt;/p&gt;

&lt;p&gt;🌊 The three waves of AI hype over the decades (the history of AI)&lt;br&gt;&lt;br&gt;
☠️ The dangers of over-promising and under-delivering what AI can do&lt;br&gt;&lt;br&gt;
🧠 What is causal reasoning?&lt;br&gt;&lt;br&gt;
😱 Is AI replacing SREs?&lt;br&gt;&lt;br&gt;
🔮 AI as a way to allow humans to solve higher level problems&lt;/p&gt;

&lt;p&gt;Find the full conversation on YouTube: &lt;a href="https://www.youtube.com/watch?v=e1L9YE7igz4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=e1L9YE7igz4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>causality</category>
      <category>devopssre</category>
      <category>podcast</category>
    </item>
    <item>
      <title>Causely Expands Datadog Integration to Deliver Causal Intelligence Across Hybrid Environments</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Mon, 22 Dec 2025 14:43:25 +0000</pubDate>
      <link>https://dev.to/causely/causely-expands-datadog-integration-to-deliver-causal-intelligence-across-hybrid-environments-1mn8</link>
      <guid>https://dev.to/causely/causely-expands-datadog-integration-to-deliver-causal-intelligence-across-hybrid-environments-1mn8</guid>
      <description>&lt;p&gt;Causely is expanding its &lt;a href="https://www.datadoghq.com/?ref=dev.to"&gt;Datadog&lt;/a&gt; integration to address a problem every senior engineering team eventually runs into: observability data keeps growing, but confidence during incidents does not. Even with Datadog APM, infrastructure metrics, and monitors deployed everywhere, engineers are still forced to interpret symptoms and argue about which change or dependency actually caused an outage. The issue is not missing telemetry. It is the lack of a system-level understanding of cause and effect. &lt;/p&gt;

&lt;p&gt;This limitation becomes especially visible in modern, hybrid architectures. Services span Kubernetes clusters, standalone EC2 instances, ECS tasks, and legacy infrastructure, all connected through real production traffic. Datadog can surface signals across these environments, but understanding how failures propagate across those boundaries remains a manual, error-prone exercise. The result is slower recovery, repeated incidents, and reduced confidence in change. &lt;/p&gt;

&lt;p&gt;With this &lt;a href="https://docs.causely.ai/telemetry-sources/datadog/?ref=dev.to"&gt;expanded Datadog integration&lt;/a&gt;, Causely gives teams a unified, causal model of their entire application across Kubernetes and non-Kubernetes environments. This model that explains &lt;em&gt;why&lt;/em&gt; services are impacted, not just &lt;em&gt;where&lt;/em&gt; symptoms appear. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;From Observability Signals to System Understanding&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Many teams already rely on Datadog APM, infrastructure metrics, and monitors as the backbone of their observability stack. With Causely’s expanded support, those same Datadog signals can now be used to build a complete and accurate causal model of the system without changing existing instrumentation. &lt;/p&gt;

&lt;p&gt;Causely supports Datadog APM dual shipping, which allows trace data to be sent directly from the Datadog collector into Causely’s mediator. Teams continue using Datadog exactly as they do today, while Causely consumes the same traces for causal reasoning. This approach avoids additional agents, avoids data duplication, and does not introduce new egress costs. &lt;/p&gt;

&lt;p&gt;Just as importantly, Causely now supports services running outside Kubernetes and keeps causality intact across the hybrid boundary. By tagging Datadog APM traces with host identity metadata, Causely can stitch together services running on EC2 with those running inside Kubernetes clusters. What previously broke at environment boundaries becomes a single, end-to-end behavioral model of how the application actually runs in production. &lt;/p&gt;

&lt;p&gt;Datadog monitors can also be ingested directly into Causely and treated as symptoms rather than conclusions. Instead of reacting to alerts in isolation, Causely uses them as signals that inform its understanding of what is happening in the system and why. That’s how you get faster convergence, fewer false leads, and higher confidence in the fix. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Real-World Hybrid Application Scenario&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Consider a typical production application. Customer-facing APIs and frontend services run in a Kubernetes cluster. Background workers, billing services, or legacy processing jobs run on standalone EC2 instances. The application depends on shared infrastructure such as Postgres, Redis, and external APIs. Datadog is already deployed across all of it. &lt;/p&gt;

&lt;p&gt;Under normal conditions, everything appears healthy. Then, during a traffic spike, latency starts creeping up in one of the Kubernetes services. Shortly after, Datadog monitors begin firing for elevated error rates in downstream components. Engineers open dashboards, inspect traces, and try to correlate timelines across environments. The symptoms are visible, but the cause is not obvious. &lt;/p&gt;

&lt;p&gt;This is where Causely changes the workflow. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flel7ctz3v4lt5c090wpj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flel7ctz3v4lt5c090wpj.png" alt="Causely Expands Datadog Integration to Deliver Causal Intelligence Across Hybrid Environments" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
_Causely leverages Datadog APM dual shipping as input to build its own model of service dependencies, infrastructure, and data flows. _&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8sqhz4c7t7hk4tmglwoo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8sqhz4c7t7hk4tmglwoo.png" alt="Causely Expands Datadog Integration to Deliver Causal Intelligence Across Hybrid Environments" width="800" height="784"&gt;&lt;/a&gt;&lt;br&gt;
_Causely leverages Datadog APM dual shipping as input to build its own model of service dependencies, infrastructure, and data flows. _&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbbv0gu4csgbftjdpvmr1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbbv0gu4csgbftjdpvmr1.png" alt="Causely Expands Datadog Integration to Deliver Causal Intelligence Across Hybrid Environments" width="800" height="485"&gt;&lt;/a&gt;&lt;br&gt;
_Causely leverages Datadog APM dual shipping as input to build its own model of service dependencies, infrastructure, and data flows. _&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Automatically Pinpointing the True Cause&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Using Datadog traces, infrastructure metadata, and monitor events, Causely continuously reconstructs end-to-end request paths and dependencies across Kubernetes and EC2. That continuity holds across environment boundaries, so you don’t have to manually stitch together “what talks to what” in the middle of an incident.  Instead of reacting to individual alerts, Causely continuously builds and maintains a behavioral model of the entire system. This model captures how services, infrastructure, and data flows interact, and how specific failure modes produce observable symptoms. &lt;/p&gt;

&lt;p&gt;Datadog APM traces provide the raw evidence of system behavior, including service interactions, request paths, and downstream dependencies. Datadog monitors are ingested and mapped as symptoms within Causely’s knowledge base. Together, these signals allow Causely to maintain an up-to-date causal model that explicitly links observed symptoms to the conditions and changes that produced them. &lt;/p&gt;

&lt;p&gt;Because this causal model is updated continuously, Causely can explain not just what is failing, but what changed first, how the impact propagated, and why specific services or endpoints are affected. The result is a precise, system-level explanation of performance degradation that teams can act on immediately. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzegws0ssmfcnybt5s41z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzegws0ssmfcnybt5s41z.png" alt="Causely Expands Datadog Integration to Deliver Causal Intelligence Across Hybrid Environments" width="800" height="256"&gt;&lt;/a&gt;&lt;br&gt;
_Using the system-level understanding, Causely applies its knowledge base of known failure patterns to infer the exact root cause driving service degradation. _&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;From Incident Response to Reliability Assurance&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This expanded Datadog integration is not just about faster root cause analysis during incidents. By continuously modeling system behavior, Causely enables teams to validate reliability before changes reach production, monitor how reliability evolves over time, and detect drift caused by infrastructure or configuration changes. &lt;/p&gt;

&lt;p&gt;Modern systems are hybrid by default, and reliability problems do not respect environment boundaries. To operate confidently at scale, teams need more than visibility. They need to understand how their systems behave and why failures occur. &lt;/p&gt;

&lt;p&gt;With expanded Datadog support across Kubernetes and EC2, Causely helps teams move from alert-driven firefighting to causal reliability engineering. The result is fewer war rooms, faster resolution, and the confidence to ship changes without fear. &lt;/p&gt;

&lt;p&gt;To learn more about using Causely with Datadog, &lt;a href="https://docs.causely.ai/telemetry-sources/datadog/?ref=dev.to"&gt;explore the integration guide&lt;/a&gt; or &lt;a href="https://www.causely.ai/try?ref=dev.to"&gt;reach out to see a unified service graph in action&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>causely</category>
      <category>datadog</category>
      <category>integration</category>
    </item>
    <item>
      <title>Thank You, FluxCD: How it helps us, and how you can use it too!</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Tue, 16 Dec 2025 17:47:11 +0000</pubDate>
      <link>https://dev.to/causely/thank-you-fluxcd-how-it-helps-us-and-how-you-can-use-it-too-1o81</link>
      <guid>https://dev.to/causely/thank-you-fluxcd-how-it-helps-us-and-how-you-can-use-it-too-1o81</guid>
      <description>&lt;p&gt;The second post in our “thank you” series, just in time for the end of the year.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.causely.ai/blog/thank-you-grafana-beyla-how-to?ref=dev.to"&gt;In the first one, we said thanks to Grafana for donating Beyla&lt;/a&gt; and making it easier for teams to get to usable telemetry quickly. This time we want to zoom out to something that quietly runs under the hood at Causely every day: GitOps with &lt;a href="https://fluxcd.io/?ref=dev.to"&gt;FluxCD&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Causely is a member of the &lt;a href="https://www.cncf.io/?ref=dev.to"&gt;Cloud Native Computing Foundation (CNCF)&lt;/a&gt;. That’s not just a logo on the website for us: our entire product and our own operations lean heavily on CNCF projects. We build on &lt;a href="https://opentelemetry.io/?ref=dev.to"&gt;OpenTelemetry&lt;/a&gt;, we run on &lt;a href="https://kubernetes.io/?ref=dev.to"&gt;Kubernetes&lt;/a&gt;, and we &lt;a href="https://www.causely.ai/blog/eating-our-own-dog-food-causelys-journey-with-opentelemetry-causal-ai?ref=dev.to"&gt;dogfood our own reliability engine&lt;/a&gt; against that stack.&lt;/p&gt;

&lt;p&gt;Another key piece in that puzzle is FluxCD. It is what takes “the desired state in git” and makes it true in our clusters, repeatedly. It’s the heartbeat behind our weekly releases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Flux Helps
&lt;/h2&gt;

&lt;p&gt;If you’re operating modern Kubernetes environments, you’ve probably felt this tension. On one hand, you want velocity: teams push changes constantly, services multiply, and configurations evolve all the time. On the other hand, every manual kubectl apply is a potential one-off change that no one can fully reconstruct later. Over time, clusters drift away from whatever was last written down as “how things should be,” and you are left relying on muscle memory and shell history.&lt;/p&gt;

&lt;p&gt;Flux solves exactly that problem by turning git into the control surface and reacting to changes within seconds of a merge.&lt;/p&gt;

&lt;p&gt;For us, that has very practical consequences.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Releases are commits, not hand-crafted ceremonies.&lt;/li&gt;
&lt;li&gt;A new Causely version is rolled out by changing a tag or a value in git; Flux notices the change within seconds, reconciles the cluster, and either converges to the new state or loudly tells us why it couldn’t.&lt;/li&gt;
&lt;li&gt;Environments stay in sync because the same manifests back our test clusters, staging, and production. The differences between them are intentional and visible in overlays, not hidden in one-off fixes on a live production cluster.&lt;/li&gt;
&lt;li&gt;And drift becomes a signal, not a mystery: when the cluster does not match git, Flux shows it, which turns the familiar “what changed?” question into a quick investigation rather than a full-blown incident archaeology.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The net effect is that we can move quickly without giving up control. Our reliability engine depends on a stable substrate; Flux helps us keep it that way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices We’ve Learned Using Flux
&lt;/h2&gt;

&lt;p&gt;We didn’t get there on day one. It took a set of habits to turn FluxCD from a cool project into a core platform primitive.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Treat manifests like product code&lt;/li&gt;
&lt;li&gt;Keep Kustomize overlays boring&lt;/li&gt;
&lt;li&gt;Watch Flux like any other production controller&lt;/li&gt;
&lt;li&gt;Make promotion a path, not an event&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Treat manifests like product code
&lt;/h3&gt;

&lt;p&gt;All of our Kubernetes manifests live in git. Not most of them, not “the important ones” – all of them. That sounds obvious, but it changes behavior in subtle ways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reviews happen before things break, because a change to a HelmRelease or a Kustomize overlay goes through the same review process as a feature change.&lt;/li&gt;
&lt;li&gt;The commit history becomes an operational log: when we see a strange spike in errors, we can line it up against recent git changes, including configuration tweaks that would otherwise live only in someone’s bash history.&lt;/li&gt;
&lt;li&gt;Our issue tracker also stays connected to reality, because we reference issue numbers in commit messages, so the question “why did we change this setting?” always has a direct link back to the discussion that justified it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the early days, we still made the occasional manual change in production, usually in the name of speed. Those changes always came back to haunt us as confusing states that no one could fully explain. Once we committed to git as the only source of truth and forced ourselves to route every change through it, the platform became much more predictable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Kustomize overlays boring
&lt;/h3&gt;

&lt;p&gt;We use &lt;a href="https://kustomize.io/?ref=dev.to"&gt;Kustomize&lt;/a&gt; to manage environment-specific differences across test clusters, staging, production, and chaos environments. The rule we eventually settled on is simple: overlays describe differences, not alternative universes.&lt;/p&gt;

&lt;p&gt;In practice, that means we maintain a clean base with shared resources such as namespaces, common &lt;a href="https://fluxcd.io/flux/components/helm/helmreleases/?ref=dev.to"&gt;HelmReleases&lt;/a&gt;, and shared configuration. On top of that base, we keep the environment overlays as thin as possible. They patch what truly needs to change, such as cluster names, resource limits, or a particular feature flag, rather than redefining whole stacks.&lt;/p&gt;

&lt;p&gt;Whenever we tried to be clever with external references or overlays that diverged heavily from one another, troubleshooting became harder. Keeping overlays compact and predictable means we can scan a diff and understand at a glance what will change in a given cluster. Before committing, we render Kustomize configs locally as a quick sanity check that catches typos and misaligned paths before Flux has to complain about them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Watch Flux like any other production controller
&lt;/h3&gt;

&lt;p&gt;GitOps is not “set and forget.” Flux is a control loop running in production and, when it is unhappy, your platform will slowly drift.&lt;/p&gt;

&lt;p&gt;We treat Flux like a critical controller. We watch reconciliation health and consider a stuck HelmRelease or Kustomization as important as any failing deployment. When Flux cannot talk to git, or when an apply keeps failing, that is something we alert on rather than something we notice days later in a dashboard. And when “nothing seems to be changing” in a cluster despite recent commits, Flux logs are one of the first places we look.&lt;/p&gt;

&lt;p&gt;This mindset becomes even more important when GitOps extends beyond just core applications and starts to manage your observability stack, gateways, and even Causely itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make promotion a path, not an event
&lt;/h3&gt;

&lt;p&gt;Flux really shines when you treat deployments as a series of git-based promotions instead of isolated production pushes. A typical Causely release starts with a change landing in a test environment: we use clusters like test1 and test2 for this. We verify that the change behaves as expected there, including how it interacts with telemetry and Causely’s own reasoning about incidents. Once we are happy, we promote the same change to staging by updating the relevant overlay or values. Only after staging behaves as expected do we roll the change into production.&lt;/p&gt;

&lt;p&gt;Alongside this path, we maintain dedicated chaos clusters, chaos1 and chaos2, where we deliberately break things to see how the system responds. Because everything flows through git, we can rehearse failure modes without fear of leaving behind strange manual fixes that only exist on one cluster. Keeping cluster-specific configuration isolated and well documented is what allows us to run realistic experiments in those chaos clusters without letting that complexity bleed into production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Flux On Your Own
&lt;/h2&gt;

&lt;p&gt;To really understand Flux, it helps to feel git driving your cluster. The smallest useful experiment is a git repository, a local kubernetes cluster, and Flux bootstrapped from that repository. The nice part is that flux bootstrap already does most of the heavy lifting: it creates the repository, installs the controllers, and wires everything together for you.&lt;/p&gt;

&lt;p&gt;You can run the following guide on your laptop with &lt;a href="https://kind.sigs.k8s.io/?ref=dev.to"&gt;kind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Start by installing the Flux CLI. The easiest way is via the official install script; if you prefer Homebrew, apt, or other package managers, the Flux documentation lists those options as well in the &lt;a href="https://fluxcd.io/flux/installation/?ref=dev.to"&gt;Flux installation guide&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -s https://fluxcd.io/install.sh | sudo bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, export your GitHub credentials so Flux can authenticate and create the repository for you. If you are logged in with the GitHub CLI (&lt;code&gt;gh auth login&lt;/code&gt;), you can derive both the user name and token directly from it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export GITHUB_USER="$(gh api user --jq '.login')"
export GITHUB_TOKEN="$(gh auth token)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a local Kubernetes cluster and verify that Flux can run there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind create cluster --name flux-playground
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When your cluster is ready, bootstrap Flux into it. This command will create a repository called &lt;code&gt;flux-playground-gitops&lt;/code&gt; under your GitHub account, install Flux into the &lt;code&gt;flux-system&lt;/code&gt; namespace, and configure it to track the &lt;code&gt;./clusters/flux-playground&lt;/code&gt; path in that repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=flux-playground-gitops \
  --branch=main \
  --path=./clusters/flux-playground \
  --personal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clone the newly created repository to your machine and change into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh repo clone flux-playground-gitops
cd flux-playground-gitops
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are now ready to define the &lt;a href="https://opentelemetry.io/docs/demo/?ref=dev.to"&gt;OpenTelemetry demo&lt;/a&gt; as a git-managed workload by adding a manifest for the demo under &lt;code&gt;clusters/flux-playground&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;gt; clusters/flux-playground/oteldemo.yaml &amp;lt;&amp;lt;'EOF'
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: open-telemetry
  namespace: flux-system
spec:
  interval: 1m
  url: https://open-telemetry.github.io/opentelemetry-helm-charts---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: otel-demo
  namespace: flux-system
spec:
  interval: 1m
  chart:
    spec:
      chart: opentelemetry-demo
      sourceRef:
        kind: HelmRepository
        name: open-telemetry
        namespace: flux-system
  targetNamespace: otel-demo
  install:
    createNamespace: true
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point your git repository fully describes both Flux itself and the OpenTelemetry demo that Flux will deploy.&lt;/p&gt;

&lt;p&gt;Commit and push these changes so Flux can reconcile the new state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "Add OpenTelemetry demo via Flux"
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within seconds of the push, Flux will see the new revision, apply the changes, and start rolling out the OpenTelemetry demo. You can watch the pods come up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;watch kubectl get pods -n otel-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a few minutes you will see the OpenTelemetry demo microservices starting in the otel-demo namespace.&lt;/p&gt;

&lt;p&gt;You now have a real application being managed by Flux from git: the desired state lives in a repository, Flux reconciles it into the cluster within seconds of your merge, and you never had to use kubectl apply for the actual deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flux + Causely: GitOps All the Way Down
&lt;/h2&gt;

&lt;p&gt;If you followed the small lab above, you already have a local cluster, Flux installed, and the OpenTelemetry demo running under GitOps control. From there, adding &lt;a href="https://www.causely.ai/?ref=dev.to"&gt;Causely&lt;/a&gt; is just one more git-driven change. &lt;/p&gt;

&lt;p&gt;Conceptually, the flow is simple. You obtain a Causely access token, store it as a Kubernetes Secret, and add the Causely FluxCD manifests to the same git repository that Flux already manages. Git drives the rollout, Flux reconciles it into the cluster, the OpenTelemetry demo generates realistic behavior, and Causely explains what is going on. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.causely.ai/installation/flux/?ref=dev.to"&gt;Our documentation&lt;/a&gt; has a full FluxCD installation guide with more background and variations. The example below is meant to be something you can copy and adapt directly from your existing &lt;code&gt;flux-playground-gitops&lt;/code&gt; setup. &lt;/p&gt;

&lt;p&gt;First, retrieve your Causely &lt;a href="https://portal.causely.app/?ref=dev.to"&gt;access token from Causely&lt;/a&gt; and keep it handy. Then, create a namespace for Causely and a kubernetes secret with your token. The Causely FluxCD manifests expect a secret named &lt;code&gt;causely-secrets&lt;/code&gt; and use Flux's native post-build substitution to inject &lt;code&gt;CAUSELY_TOKEN&lt;/code&gt; into the &lt;code&gt;HelmRelease&lt;/code&gt;, so the token never has to be committed to git:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create namespace causely 
kubectl create secret generic causely-secrets \ 
  --from-literal=CAUSELY_TOKEN=your-actual-gateway-token-here \ 
  -n causely 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, from inside your GitOps repository, clone the public &lt;a href="https://github.com/causely-oss/causely-deploy?ref=dev.to"&gt;causely-deploy repository&lt;/a&gt; and copy the FluxCD manifests into your own cluster configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd flux-playground-gitops 
git clone https://github.com/causely-oss/causely-deploy.git  
mkdir -p clusters/flux-playground/causely 
cp causely-deploy/kubernetes/fluxcd/causely/*.yaml clusters/flux-playground/causely/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, your git repository now contains everything Flux needs to deploy Causely, and you can commit and push these changes so Flux can reconcile the new state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add clusters/flux-playground 
git commit -m "Add Causely via Flux" 
git push origin main 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the push, Flux notices the change, applies the new manifests, and starts deploying Causely into your cluster. You can watch it the same way you watched the OpenTelemetry demo roll out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flux get kustomizations -A 
kubectl get pods -n causely
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the Causely pods are healthy, you can return to the Causely portal, where the cluster you just configured will appear. Over time, topology fills in and, as issues arise, you will see root cause views associated with the services in your demo. &lt;/p&gt;

&lt;p&gt;At that point, you have a complete loop on a single laptop: Git drives change, Flux applies it, the OpenTelemetry demo generates behavior, and Causely explains what happens when things go wrong. If you want more variations, production-grade knobs, or to run this across multiple clusters, &lt;a href="https://docs.causely.ai/installation/flux/?ref=dev.to"&gt;the FluxCD installation guide&lt;/a&gt; in our docs walks through additional options in detail. &lt;/p&gt;

&lt;h2&gt;
  
  
  Closing: Thank You, Flux
&lt;/h2&gt;

&lt;p&gt;FluxCD is a great example of the kind of infrastructure we love in the CNCF ecosystem. It nudges teams toward good habits, turns the question “how did this get here?” into something with a clear, auditable answer, and helps keep complex Kubernetes estates boring and predictable.&lt;/p&gt;

&lt;p&gt;As a CNCF member building on OpenTelemetry, Kubernetes, and the wider cloud-native stack, we are genuinely grateful for projects like Flux that quietly raise the floor for everyone.&lt;/p&gt;

&lt;p&gt;So: thank you to the Flux maintainers and community for building and maintaining an engine that lets us practice what we preach about control, desired state, and autonomous reliability. If you are running kubernetes and still relying on manual deploys or one-off scripts, Flux is worth a serious look.  &lt;/p&gt;

&lt;p&gt;And if you want to see what happens when you combine GitOps with causal reasoning, we are always happy to show you how Causely fits into that picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.causely.ai/try?ref=dev.to"&gt;Book a demo today -&amp;gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>fluxcd</category>
      <category>opentelemetry</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Causely Named a Gartner Cool Vendor in AI for IT Operations 2025</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Tue, 09 Dec 2025 20:25:00 +0000</pubDate>
      <link>https://dev.to/causely/causely-named-a-gartner-cool-vendor-in-ai-for-it-operations-2025-18g8</link>
      <guid>https://dev.to/causely/causely-named-a-gartner-cool-vendor-in-ai-for-it-operations-2025-18g8</guid>
      <description>&lt;p&gt;We are excited to share that Gartner has named Causely a &lt;a href="https://www.gartner.com/en/documents/7233330?ref=dev.to"&gt;&lt;u&gt;Cool Vendor for AI in IT Operations for 2025&lt;/u&gt;&lt;/a&gt;. For us, this recognition reflects what we’re seeing across engineering and operations teams everywhere. Systems are changing faster than traditional tools can keep up, and teams need a more reliable way to understand how their applications behave as they evolve. &lt;/p&gt;

&lt;p&gt;At the pace modern cloud-native systems move, reacting after symptoms appear is not enough. Teams need a reliability operating system that works continuously alongside their applications, maintains an up-to-date understanding of how everything fits together, and provides the context required for safe automation and proactive reliability. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why this recognition matters&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Modern cloud-native applications evolve constantly. Every deploy, configuration change, traffic surge, and infrastructure adjustment can reshape system behavior. The pace is so fast that even the best teams struggle to reason about what is happening and why. &lt;/p&gt;

&lt;p&gt;Traditional observability dashboards can show what happened after symptoms appear, and AI copilots can help speed up triage, but reacting after the fact isn’t good enough for business-critical applications. &lt;/p&gt;

&lt;p&gt;Teams need something that runs continuously alongside their systems, understands how everything fits together, and helps them see how changes will affect performance before they land in production. That’s the foundation for proactive reliability, not just faster incident response. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What Gartner recognized about&lt;/strong&gt;   &lt;strong&gt;Causely&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Gartner recognized Causely for taking a fundamentally different approach to reliability in modern systems. Instead of reacting to symptoms after they spread, Causely maintains a &lt;a href="https://www.causely.ai/blog/causal-reasoning-the-missing-piece-to-service-reliability?ref=dev.to"&gt;&lt;u&gt;live causality graph&lt;/u&gt;&lt;/a&gt; that reflects how services, dependencies, and performance constraints relate to one another as the environment evolves. By continuously analyzing telemetry, Causely identifies the underlying driver behind emerging changes in golden signals, even when failures cascade across multiple services, including the code change, configuration update, or operational event that first introduced risk. &lt;/p&gt;

&lt;p&gt;This continuous causal inference is what enables proactive reliability. Causely provides clear direction on where to focus and what action is most likely to reduce performance risk, long before issues escalate. The same causal model supports both pre-production and production, helping teams understand how behavior will shift during testing, rollout, and real-world load. &lt;/p&gt;

&lt;p&gt;Causely runs locally as a lightweight, containerized system and &lt;a href="https://www.causely.ai/blog/demystifying-automatic-instrumentation?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;u&gt;processes telemetry without exporting raw data&lt;/u&gt;&lt;/a&gt;. This eliminates the need for central pipelines, avoids sampling or data volume constraints, and gives teams high-fidelity insight that integrates directly into their engineering workflows through APIs, webhooks, and an MCP server. This structured context supports both human decisions and safe automation. &lt;/p&gt;

&lt;p&gt;For us, this recognition validates the direction we have been building toward. The future of reliability is proactive, predictive, and grounded in causal understanding. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Who&lt;/strong&gt;   &lt;strong&gt;should care?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Causely is designed for teams responsible for building and operating modern distributed systems. It gives engineering and operations organizations a clearer understanding of how system behavior changes over time and how those changes affect reliability. Whether preparing a release, managing growth, or diagnosing unexpected behavior, teams need deeper clarity to make confident decisions. Continuous causal inference provides that clarity. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Looking ahead&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We’re grateful to Gartner for this recognition and excited about what it represents. Reliability is entering a new chapter. Systems are more dynamic, &lt;a href="https://www.linkedin.com/pulse/when-ai-overwhelms-your-architecture-machine-load-new-shergilashvili-zhw5f/?ref=causely-blog.ghost.io" rel="noopener noreferrer"&gt;&lt;u&gt;AI workloads are growing&lt;/u&gt;&lt;/a&gt;, and teams need deeper clarity to keep everything running smoothly. &lt;/p&gt;

&lt;p&gt;Causely’s mission is to provide that reliability. Continuous causal inference helps teams prevent issues before they escalate, support high-velocity engineering without sacrificing reliability, and give both humans and automation the context they need to act safely. &lt;/p&gt;

&lt;p&gt;We’re excited for what’s ahead and proud to help shape the future of reliable, intelligent, and resilient systems. &lt;/p&gt;




&lt;p&gt;Want to learn what this could look like for your organization? &lt;a href="https://www.causely.ai/try?ref=dev.to"&gt;&lt;u&gt;Get started with Causely today.&lt;/u&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Gartner subscribers can &lt;a href="https://www.gartner.com/en/documents/7233330?ref=dev.to"&gt;&lt;u&gt;view the full report&lt;/u&gt;&lt;/a&gt; for more information.&lt;/p&gt;

</description>
      <category>causely</category>
      <category>ai</category>
      <category>gartner</category>
    </item>
    <item>
      <title>Announcing Reliability Delta: Clear, Objective Insight into Whether Your Release Made Your System Better or Worse</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Thu, 04 Dec 2025 21:23:59 +0000</pubDate>
      <link>https://dev.to/causely/announcing-reliability-delta-clear-objective-insight-into-whether-your-release-made-your-system-e</link>
      <guid>https://dev.to/causely/announcing-reliability-delta-clear-objective-insight-into-whether-your-release-made-your-system-e</guid>
      <description>&lt;p&gt;Your team has been grinding for days, tuning a critical service to improve performance without lighting your cloud bill on fire. It’s the kind of systemic change you can’t hand off to an AI coding agent. After countless reviews, experiments, and late nights, the update is finally in production. &lt;/p&gt;

&lt;p&gt;You take a breath. Maybe even consider sleeping. &lt;/p&gt;

&lt;p&gt;Then Slack lights up: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Did it work?” — CTO&lt;/strong&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You stare at dashboards. Nothing’s red. But you still don’t actually know: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did reliability improve, or quietly regress? &lt;/li&gt;
&lt;li&gt;Did the change shift bottlenecks or introduce new stress points? &lt;/li&gt;
&lt;li&gt;Are you now closer to the edge under peak load? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a 50 to 100+ microservice environment with dense service-to-service dependencies, even small regressions can cascade silently. And slowing down isn’t an option. Leadership needs faster delivery and fewer incidents. &lt;/p&gt;

&lt;p&gt;This is exactly why we built Reliability Delta. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Reliability Delta: A Deterministic Answer to “Did This Change Make Things Better or Worse?”&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Reliability Delta turns subjective guesswork (like manual diffing of dashboards, correlation hunts, “nobody is complaining” anecdotes) into clear, evidence-based reliability signals. &lt;/p&gt;

&lt;p&gt;It’s powered by Causely’s continuously updated understanding of your environment: &lt;/p&gt;

&lt;h3&gt;
  
  
  Causality Mapping
&lt;/h3&gt;

&lt;p&gt;Causely builds a Bayesian network that models how issues propagate across services, enabling true cause-and-effect visibility. &lt;/p&gt;

&lt;h3&gt;
  
  
  Attribute Dependency Graph
&lt;/h3&gt;

&lt;p&gt;A DAG of functional dependencies generated from live topology and Causely’s attribute models, highlighting how attributes influence one another. &lt;/p&gt;

&lt;p&gt;These models allow Causely to compare two snapshots—two releases, two load tests, or two moments in time—and determine whether system behavior: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improved &lt;/li&gt;
&lt;li&gt;Regressed &lt;/li&gt;
&lt;li&gt;Or shifted in ways you need to investigate &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result: deterministic signals engineers can trust.  &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Use Cases for&lt;/strong&gt;   &lt;strong&gt;Reliability Delta&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;1.&lt;/em&gt; &lt;em&gt;Validate&lt;/em&gt; &lt;em&gt;Every Release Instantly&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Know immediately whether your change introduced risk. &lt;/p&gt;

&lt;p&gt;Feature flags and canaries help, but they don’t guarantee safety. What matters is whether the system is behaving normally. &lt;/p&gt;

&lt;p&gt;Reliability Delta automatically surfaces: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Behavior changes isolated to a specific flag, tenant, or traffic segment &lt;/li&gt;
&lt;li&gt;Downstream effects in pipelines, async jobs, and data flows &lt;/li&gt;
&lt;li&gt;Subtle regressions that don’t trip alerts but violate known patterns of normal &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn’t “no alerts fired = good.” &lt;/p&gt;

&lt;p&gt;This is evidence-based release confidence.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;2. Understand Load Test Results Beyond Pass/Fail&lt;/em&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“With&lt;/em&gt; &lt;em&gt;Causely’s&lt;/em&gt; &lt;em&gt;Reliability Delta, we can quantify how each release behaves under identical load. It surfaces changes in bottlenecks, stress patterns, and causal relationships that traditional load tests miss. At our scale, having that level of confidence before shipping is critical.”&lt;/em&gt; - &lt;strong&gt;Cade Moore, Performance Engineering Lead at Hard Rock Digital&lt;/strong&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Did this release push you closer to the breaking point? &lt;/p&gt;

&lt;p&gt;A load test passing doesn’t mean you’re safe. &lt;/p&gt;

&lt;p&gt;Reliability Delta shows: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How bottlenecks shifted compared to last time &lt;/li&gt;
&lt;li&gt;Whether the same load now produces more stress &lt;/li&gt;
&lt;li&gt;Early signs of fragility or shrinking performance margins &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It answers the question load tests never answer: &lt;/p&gt;

&lt;p&gt;“Are we drifting toward failure or away from it?” &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;3. Detect Reliability Drift Over Time&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Systems naturally drift through config changes, dependency updates, scaling events, and organic load shifts. &lt;/p&gt;

&lt;p&gt;By capturing snapshots periodically, you can: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spot slow-building risk &lt;/li&gt;
&lt;li&gt;Track reliability trends &lt;/li&gt;
&lt;li&gt;Validate that ongoing changes are improving SLO posture, not eroding it &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This moves teams from reactive firefighting to proactive reliability assurance. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;4.&lt;/em&gt; &lt;em&gt;Validate&lt;/em&gt; &lt;em&gt;Experiments with Confidence&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Know immediately whether your experiment improved or degraded system behavior. &lt;/p&gt;

&lt;p&gt;Teams frequently adjust timeouts, concurrency, sampling, queue behavior, or other system parameters, but these changes rarely trigger alerts, and standard dashboards make it hard to see their true impact. &lt;/p&gt;

&lt;p&gt;Reliability Delta lets you validate experiments with clear before-and-after evidence by automatically highlighting: &lt;/p&gt;

&lt;p&gt;• Shifts in bottlenecks or stress patterns across services &lt;/p&gt;

&lt;p&gt;• Degradations hidden behind “passing” performance metrics &lt;/p&gt;

&lt;p&gt;• Unexpected side effects in downstream dependencies &lt;/p&gt;

&lt;p&gt;• Whether the experiment made the system more resilient or more fragile &lt;/p&gt;

&lt;p&gt;This isn’t trial-and-error tuning. It is evidence-based experiment validation. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why Reliability Delta Matters for Modern Engineering Teams&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you’re accountable for revenue-critical systems—measured by 99.9%+ SLOs, delivery pace, and incident reduction—you need more than observability dashboards. You need a deterministic framework for evaluating how change affects system behavior.  &lt;/p&gt;

&lt;p&gt;Reliability Delta gives you: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Objective, repeatable comparisons between versions &lt;/li&gt;
&lt;li&gt;Root-cause-aware analysis using causal models &lt;/li&gt;
&lt;li&gt;Clear guardrails leadership can trust &lt;/li&gt;
&lt;li&gt;Confidence to ship fast without risking SLOs or customer experience &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It transforms subjective judgment into trusted, actionable reliability signals—so every release, load test, and system change is safer, faster, and more predictable.  &lt;/p&gt;

&lt;h2&gt;
  
  
  *&lt;em&gt;Ship Faster with Confidence *&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Reliability isn’t something you can eyeball anymore. With Reliability Delta, engineering leaders get the missing layer between observability and automation: clear causal evidence of how changes affect system behavior. It ensures your team can move fast, protect SLOs, and deliver with the confidence that every release is safer than the last. &lt;/p&gt;

&lt;p&gt;To learn more, see our docs: &lt;a href="https://docs.causely.ai/in-action/reliability-delta/?ref=dev.to"&gt;&lt;u&gt;https://docs.causely.ai/in-action/reliability-delta/&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sre</category>
      <category>causely</category>
      <category>devops</category>
    </item>
    <item>
      <title>eAfterWork EP 9: What Every Leader Needs to Know with Severin Neumann</title>
      <dc:creator>Severin Neumann</dc:creator>
      <pubDate>Wed, 03 Dec 2025 11:36:00 +0000</pubDate>
      <link>https://dev.to/causely/eafterwork-ep-9-what-every-leader-needs-to-know-with-severin-neumann-80n</link>
      <guid>https://dev.to/causely/eafterwork-ep-9-what-every-leader-needs-to-know-with-severin-neumann-80n</guid>
      <description>&lt;p&gt;In this episode of eAfterWork, we’re going straight to the source: Severin, OpenTelemetry maintainer, member of the OpenTelemetry Governance Committee, and one of the people who writes and maintains the official OpenTelemetry documentation.  &lt;/p&gt;

&lt;p&gt;He’ll help us understand why OpenTelemetry matters for both technical and non-technical leaders, how it’s shaping the future of observability, and what you really need to know to make the right decisions.&lt;/p&gt;

&lt;p&gt;Watch the full conversation on YouTube: &lt;a href="https://www.youtube.com/watch?v=LkaytYEAJnQ" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=LkaytYEAJnQ&lt;/a&gt;&lt;/p&gt;

</description>
      <category>podcast</category>
    </item>
  </channel>
</rss>
