The Decomposition Problem: Why Breaking Tasks into Agent-Sized Pieces Is Harder Than It Looks

The Decomposition Problem: Why Breaking Tasks into Agent-Sized Pieces Is Harder Than It Looks

Every operator who has worked with autonomous agents has experienced this: you carefully decompose a complex task into clean, discrete subtasks, hand them to an agent, and watch it reconstruct them into something that doesn’t resemble your original intent. The decomposition looked logical on your whiteboard. The execution looked logical from the agent’s perspective. But the output is wrong in ways that are hard to diagnose.

The problem isn’t the agent’s capability. It’s the decomposition itself.

Why Human Decomposition Fails

Human beings decompose tasks based on linear causality. We draw diagrams where A leads to B leads to C, and each step has a clear input-output relationship. This works perfectly for physical tasks and well-defined software workflows.

But agent tasks rarely have clean linearity. They have loops, feedback cycles, and implicit context that humans absorb unconsciously but agents must reconstruct explicitly.

Consider: you want an agent to “research competitor pricing and draft a pricing strategy memo.” You break this into steps: (1) gather competitor prices, (2) analyze pricing patterns, (3) draft recommendations. It sounds reasonable. But step 3 requires knowledge that isn’t in step 2’s output—things like your product’s positioning, your sales team’s discount patterns, your enterprise customers’ willingness to pay. The agent doesn’t know to pull this context unless you tell it to.

This is the decomposition problem: humans decompose tasks based on how tasks feel sequential. Agents decompose based on what’s actually in each data payload.

The Atomic Unit Fallacy

The instinct when things go wrong is to decompose further. Make the tasks smaller. More discrete. More atomic. This usually makes things worse.

When you break a task into units that are too small, you lose the coherence that makes the task tractable. A research subtask that says “find competitor pricing” is executable but lacks the guiding context of “find competitor pricing so we can identify underpriced segments.” Without that context, the agent optimizes for the wrong objective. It returns comprehensive pricing data instead of actionable pricing insights.

The agent’s cost function is implicit in how you phrase the task. Atomic tasks strip away the cost function.

The Thick Slice Principle

The better framing is thick slices rather than atomic units.

A thick slice contains:

  1. The objective — what decision this work informs
  2. The context — what background knowledge the agent needs
  3. The constraints — what success looks like, including what to avoid
  4. The output format — how the agent should structure its response

A thin slice contains only the action: “find competitor pricing.” A thick slice contains: “find competitor pricing for our top 5 rivals in the SMB segment, focusing on entry-level tiers and bundling patterns. I need this to inform a pricing decision next week. Return a structured comparison with per-feature pricing breakdown, not just list prices.”

Thick slices are more work upfront. They require you to think through what you actually need, not just what feels like the logical first step. But they dramatically reduce the reconstruction cost on the back end.

Failure Modes When Decomposition Goes Wrong

The most common failure mode isn’t task failure—it’s tangential success. The agent completes the decomposed subtasks with high fidelity, but the completion is irrelevant to the original goal. The research was thorough. The analysis was sound. The recommendations were confidently wrong for your specific market.

This happens because decomposed subtasks get their own optimization targets. Each subtask becomes “do this subtask well” rather than “move toward the original goal.” The agent loses sight of the forest for the trees, not because it’s stupid, but because you inadvertently made each tree a separate objective.

Another failure mode is context fragmentation. When tasks are broken into disconnected units, each unit loses the surrounding context. The agent working on step 7 doesn’t know what step 3 found, unless you explicitly wire that information flow. In human teams, this happens naturally through shared context and whiteboards. In agent systems, you have to build it explicitly.

The Decomposition Review

Before sending work to an agent, run a decomposition review. For each subtask, ask:

  1. Does this subtask have an explicit connection to the final goal, or only an implicit one?
  2. Is there context this subtask needs that lives in other subtasks?
  3. What would this subtask’s output look like if it were perfectly executed but irrelevant to the goal?
  4. What information does the next subtask need from this one that isn’t currently specified?

If you find gaps, thicken the slice. Add context. Add constraints. Add output specifications.

The goal isn’t to remove the need for agent judgment—it’s to give the agent the context it needs to exercise judgment correctly.

Breaking tasks into agent-sized pieces isn’t a sizing exercise. It’s a reasoning exercise. And most of us are doing it backwards.

Our 2026 Direction: AI and Classic Workflows in JetBrains IDEs

Two valid ways of writing code. One place to own it.

Quick version for AI-news-tired readers:

There are two ways developers create code now:

  1. The classic way: By typing, refactoring, debugging, and building up intent line by line.
  2. The new way: Through collaborating with AI – sometimes via autocomplete and other times by using an agent that can draft whole chunks of work.

We don’t think one is better than the other.

Our goal is to ensure both workflows can coexist inside JetBrains IDEs without hindering each other. In practice, this means that:

  • If you want to write code yourself, the IDE should be focused on code writing, and AI shouldn’t compromise the core coding experience.
  • If you want to generate code with AI (or delegate tasks to agents), the IDE should make that feel natural and powerful, both in terms of UX and functionality.

Either way, one thing doesn’t change: A human is responsible for the code that ships. And the best place to read, understand, and own that code is still the IDE.


What “AI in the IDE” means without the snake oil or hype

We’re not limiting this to one “official” workflow. The market is moving too fast for that – and developers are too diverse for a one-size-fits-all approach.

So when we say “AI in JetBrains IDEs”, we mean agentic added value: UX and features that become available as and when useful:

  • In the AI Chat tool window, as a chat-first workflow.
  • in the IDE terminal, where many developers already work with CLI tools.
  • In the new opt-in modes created for agentic systems, where you can run an agent and leave it to work for hours.

Think of it as follows: One IDE, with multiple AI-powered ways to get work done – picked by the user, shaped by the team, and constrained by real development expectations.


The AI strategy: Avoid vendor lock‑in and keep workflows compatible

If there’s one thing we’re confident about, it’s this: The “best” model, provider, or agent today won’t be the best forever – or perhaps even next month.

That’s why we’re deliberately building toward an IDE experience that does not depend on a single vendor’s roadmap.

Practically, that means our AI chat experience supports multiple ways to connect – depending on what’s allowed by providers’ terms, and what users actually want:

  • JetBrains AI-managed setup (with JetBrains AI subscription).
  • BYOK: Bring your own API key.
  • OAuth sign-in for supported provider accounts (where the provider supports it).
  • ACP agents: Connect external coding agents through a standard protocol.

One honest footnote: OAuth isn’t always available. If an agent provider doesn’t offer OAuth (or doesn’t offer it in a way an IDE can use), we can’t invent it.


Agent Client Protocol (ACP): “Bring your own agent”

ACP lets you connect external coding agents to JetBrains IDEs through a standard interface, so the IDE doesn’t need a bespoke integration for every agent. Agents can be installed from a curated registry (or configured manually), and the installed agents appear inside the AI chat. 

A practical example of one that people have been asking for is the Cursor agent. Cursor is already available as an AI agent inside JetBrains IDEs through ACP – you can select it from the agent picker and use its agentic workflow inside your JetBrains IDE. 

This is the shape we want:

  • You choose the agent that fits your workflow or team.
  • You keep working in the IDE you already rely on.
  • Classic IDE workflows don’t get shoved aside for “agent mode”.

“Professional coding with AI” means more responsibility

We’re not anti-AI. We’re anti-confusion.

There’s a kind of coding that’s optimized for disposable output – and it’s totally valid in the right context. But JetBrains IDEs are built for code that isn’t disposable, but rather for code that is intended for long-term use.

So here’s the principle we design for: Generated code should be treated like real code. That means it should be possible to:

  • Read it
  • Review it
  • Change it
  • Revert it when it’s wrong
  • Understand its impact on the codebase

In practice, our baseline expectation is boring (in the best possible sense):

  • Changes should be visible
  • Changes should be reversible
  • Your project isn’t left in a broken state (“no red code” is a pretty good starting point)

And yes, agents can edit many files. That can be a superpower – but only if you can fully inspect, understand, and correct the outcome. That’s where the IDE matters: It gives you visibility and control over the code produced by humans or AI.


AI on your terms: our product commitments

1. AI and classic modes live side by side 

Typing-first workflows and AI-first workflows are both valid. We’re not building for developer-replacement narratives, and we’re not building an IDE that nudges you into a single “approved” way of working. We respect both approaches. 

2. AI agents must respect the core IDE promise

Every push toward agents must keep the IDE’s core promise intact: deep code intelligence, safe refactoring, debugging, navigation, inspections, reviews – the stuff professional development is made of.

3. Zero vendor lock-in

Multiple activation pathways (subscription, BYOK, OAuth, where possible, and ACP agents) are not a “nice to have.” We are committed to ensuring your workflow is never tied to a single vendor.

4. Long-term utility over hype

If people keep using these workflows weeks later (real retention, real projects), that’s the signal. A lot of AI-driven workflows today are just hype (I’m talking about you, Ralph-loop). 

5. Prioritizing candid community feedback

We value the honesty of Reddit users, Marketplace reviewers, and community members who don’t owe us politeness. Those are exactly the people we want judging our progress.


AI will create a lot of code. That’s not a prediction anymore – it’s the reality in April 2026.

But someone still has to be responsible for that code. Someone still has to read it before it merges. And right now, agents can help you move fast – but they can’t carry the risk for you.

So our commitment is straightforward:

We’ll keep building AI workflows that speed up creation – and we’ll keep strengthening the IDE as the best place to review, understand, and own what gets shipped.

You decide how much AI you want. We’ll make sure both paths – AI-assisted and classic – work great together, but you can stay on the path you prefer.

React vs. React Native: The difference, and which is best for you

Choosing between React vs. React Native for your project can be confusing. Both JavaScript user interface (UI) libraries serve similar purposes and use the same syntax, but their differences are important. React is designed for building user interfaces for web front ends, while React Native helps you build native mobile apps for Android and iOS.

This article explains what React and React Native are and their differences, and provides context and information so that you can decide which to use for a particular project.

React and React Native are not the same thing

React and React Native are two distinct JavaScript libraries for developing user interfaces. While React serves as the foundation for React Native, they are not the same thing, and serve different purposes when developing user interfaces:

  • React is intended for building user interfaces for web applications that run in the browser. It lets you create reusable UI components using your own designs implemented using CSS, or using a pre-built user interface library.

  • React Native lets you use React to build mobile applications that look and behave like native applications. Rather than defining your own look and feel, it adopts the appearance of the native UI elements of the operating system (like buttons, lists, and inputs), while still letting you develop your own broader design using familiar React concepts and syntax.

Both libraries use the same core React syntax and component-based architecture.

Before deciding which JavaScript UI library to adopt for a project, it’s worth understanding each in detail. As React Native is built on React, the programming knowledge is transferable, so it’s less a matter of deciding which you will invest your time learning, and more about learning React and then identifying when it would be better to use React Native on a per-project basis.

What is React?

React is an open-source frontend JavaScript library that is developed specifically for building user interfaces for applications that run in a web browser. It lets you create reusable UI components (known as a component-based architecture), reducing the code you need to write and providing a consistent and efficient codebase.

React uses JSX, an extension to JavaScript that lets you include the HTML for your reusable UI components alongside their JavaScript in the same file, which some developers prefer as it makes your codebase easier to understand and navigate.

Another major feature of React is the virtual DOM: a representation of the HTML document displayed in the browser that you can manipulate programmatically, and that React then automatically syncs to the real DOM as shown to the user. This feature lets you use React to make dynamic pages that don’t have to reload to change their contents, with much less code than would be required if working from scratch.

Due to React’s lightweight nature, you can use it to provide as little or as much interactivity in a web page as needed, and you can add it to existing projects. Alternatives to React for web development include Vue.js and Angular. React is used by websites like Facebook, Instagram, and Netflix to power their user interfaces.

Below is an example of an HTML list rendered in React using JSX syntax:

// Import the React module
import React from 'react';

// Create the React component 
const App = () => {
    const items = ['Apple', 'Banana', 'Cherry']; // List data

    return (
        <div>
            <h1>Fruit List</h1>
            <ul> 
                {items.map((item) => (
                <li key={item}>{item}</li> /* Item names in the example array are unique strings, so they can be used as the key */
                ))}
            </ul>
        </div>
    );
};

export default App;

What is React Native?

React Native was developed so that React developers could create mobile apps with their existing React skill sets. It allows for efficient app development, as you can share much of your code between all of your web and native applications (Windows, iOS/iPadOS, and Android).

In addition to letting you leverage existing React skills, tools, and techniques to cover cross-platform native app development, React Native lets you build applications that look and feel like they were designed for each platform from the ground up.

Rather than building your own UI elements and interacting with a virtual DOM, you use React Native’s buttons, lists, panels, and other included components to create applications that look like, animate like, and conform to the host’s design system. Apps built with React Native include Discord, Uber, and Skype.

Below is an example of the same list as above, but implemented using React Native user interface elements:

// Import the React module as well as the React Native UI element modules for View, Text, and FlatList
import React from 'react';
import { View, Text, FlatList } from 'react-native';

// Create the React Component
const App = () => {
    const items = ['Apple', 'Banana', 'Cherry']; // Sample list data

    return (
        <View> 
        <Text style={{ fontSize: 24 }}>Fruit List</Text> 
        <FlatList 
            data={items}
            keyExtractor={(item, index) => item} // Item names in the example array are unique strings, so they can be used as the key
            renderItem={({ item }) => (
            <Text style={{ fontSize: 18 }}>{item}</Text> 
            )}
        />
        </View>
    );
};

export default App;

You’ll notice that while React and JSX syntax is used in both the React and React Native examples, the React example uses HTML elements like

and

    whereas the React Native example uses native UI components like and .

    The behavior of each example is the same, but the UI provided by React will require CSS to style it, whereas the React Native UI elements will automatically adopt the appearance of the mobile platform they are run on (it’s worth noting that you can alter the appearance of React Native components).

    What is React Native for Web?

    Web browsers don’t include native UI components for React Native to display. React Native for Web makes it possible to deploy React Native apps for delivery to web browsers by providing a set of web-compatible HTML UI components to use in place of the missing native components.

    This allows you to use React Native to build both mobile and web applications, and while React Native for Web isn’t a core part of React Native, it is widely supported and used by the React community, and is actively maintained.

    React Native for macOS and Windows

    It’s also possible to use it to develop desktop applications using React Native for Windows and React Native for macOS.

    When should you use React?

    You should use React to build user interfaces for your web development projects when you:

    Want to benefit from the component-based architecture and interactivity React provides.

    Are building web applications that will run in a web browser.

    Need to design bespoke interfaces with unique visual elements that differ from the visual style of the host operating system.

    When should you use React Native?

    You should use React Native when you:

    • Want to take your React skills and use them to build native mobile or desktop apps.
    • Require a consistent user interface that adopts the appearance of the host operating system.
    • Are building native apps that you will publish to the Apple App Store, Google Play, and Microsoft Store.
    • Are developing an application that doesn’t rely on HTML — React Native has no DOM, so everything must be constructed with React Native UI components.

    Choosing the best tools for your project

    React is a powerful user interface development tool, greatly streamlining the frontend development process. React Native builds on this by letting you use React to build native mobile apps as well as web apps, for full platform coverage using the same language and tools.

    However, that doesn’t mean React (or React Native) is necessarily right for your project: there are a number of other user interface libraries and technologies, each with their own use cases and advantages. In some cases, a full application framework may accelerate your development process by providing a code foundation and boilerplate functionality for your apps.

Field Learnings with OpenClaw and WhatsApp

Technical notes extracted by Claude from deploying an agentic WhatsApp bot to production (OpenClaw 2026.4.23). Focus on things not in the official docs or that cost hours of debugging.

High-Level Architecture

OpenClaw is a self-hosted agentic gateway that routes messages between:

  • Channels (WhatsApp via Baileys, Slack, Discord, Telegram, etc).
  • Agents (isolated objects with workspace, persona, model).
  • Tools via MCP (Model Context Protocol — standard protocol).

The main process is the gateway (Node 24, listens on :18789), which maintains a Baileys session per WhatsApp account and triggers agents on demand.

Config: JSON, Not YAML

The active config is ~/.openclaw/openclaw.json (under the node user, uid 1000). The env var OPENCLAW_CONFIG=/path/to/yaml is ignored by the gateway. The schema is huge (49.5k lines), validated via JSON Schema draft-07.

Useful commands:

openclaw config schema        # Full JSON Schema (stdout)
openclaw config get <path>    # read value
openclaw config set <path> <value> --strict-json [--dry-run] [--replace]
openclaw config set --batch-file /tmp/batch.json --strict-json

config set automatically creates a .bak before overwriting. A gateway restart is required to apply changes (docker restart openclaw-gateway).

Gotcha — . in paths: if the path contains . (e.g., a JID like 120363406566286319@g.us), the parser interprets it as an object separator. Workaround: set the entire object one level up (channels.whatsapp.groups, with value being a dict).

Inheritance Bug: Must Set on Both Channel + Account

channels.whatsapp.<X> is not inherited by channels.whatsapp.accounts.default.<X> during resolveMergedAccountConfig. Silent symptom: you set it on the channel, the value is “default” at runtime, and the gateway applies the fallback. Config changes must be duplicated:

{
  "channels.whatsapp.groupPolicy": "allowlist",
  "channels.whatsapp.accounts.default.groupPolicy": "allowlist",
  "channels.whatsapp.groupAllowFrom": [...],
  "channels.whatsapp.accounts.default.groupAllowFrom": [...]
}

groupAllowFrom Is a Sender List, Not a Group List

The name is misleading. groupAllowFrom is validated against senderE164 (the phone number of the message sender), via isNormalizedSenderAllowed(). It is not an allowlist by group.

There is no native group JID allowlist in OpenClaw. To restrict to a specific group, the options are:

  • Operational: the bot is in only one group.
  • Per user: list authorized phone numbers in groupAllowFrom. The bot responds when ONE of them speaks in ANY group (with default mention).
  • Combined: requireMention: true (default) everywhere, with an exception via groups.<JID>.requireMention: false for the main group.

WhatsApp in DinD

The <container_name> container is Docker-in-Docker. The Docker daemon that mounts volumes belongs to the outer host (<hostname>), not the inner container. Symptoms:

  • Bind-mounting a file creates a directory instead: the daemon looks for the file on its own filesystem, doesn’t find it, and creates an empty dir. Solution: package files in a thin Dockerfile via COPY (instead of bind mounts).
  • localhost doesn’t resolve in Alpine containers: use 127.0.0.1.
  • Binding 127.0.0.1:18789 on the host conflicts: use expose: instead of ports:. To access the UI externally: docker exec or port-forward via SSH.

Baileys Pairing

docker exec -it openclaw-gateway openclaw channels add --channel whatsapp
docker exec -it openclaw-gateway openclaw channels login --channel whatsapp

The second command opens an ASCII QR code in the terminal. It must be a TTY (docker exec -it + ssh -t if via SSH). Pair with the phone app under Linked Devices. Session is persisted in a Docker volume.

Session expires after a few days. Symptom: channels status --probe reports linked, connected, in:Xm ago but messagesHandled: 0. Common root cause: error 1006 from failed hydrating participating groups on connect. Solution: logout + login (new QR).

docker exec openclaw-gateway openclaw channels logout --channel whatsapp
docker exec -it openclaw-gateway openclaw channels login --channel whatsapp

After login, verify with directory groups list — if it returns the group list, hydration completed successfully.

append Skip Bug After Restart

Each gateway restart triggers a Baileys reconnect. Messages arriving during this window come with upsert.type === "append" (history sync). The code path in /app/dist/extensions/whatsapp/monitor-BXydC-6q.js around line ~967 checks:

const msgTsNum = msg.messageTimestamp != null ? Number(msg.messageTimestamp) : NaN;
if ((Number.isFinite(msgTsNum) ? msgTsNum * 1e3 : 0) < connectedAtMs - 60_000) continue;

If messageTimestamp is absent, the fallback 0 makes the comparison always true — skipping the message. Patch: change : 0 to : Date.now(). This is a manual edit in a dist file; it must be redone after each docker compose build. Issue tracker: openclaw/openclaw#19856.

groupAllowFrom Bug (issue #54613)

Multiple issues report “DMs work, groups don’t” or “messagesHandled stuck at 0 even when connected”. The actual cause is a combination of:

  • groupPolicy must be set on both channel + account (inheritance bug).
  • groupAllowFrom must contain E.164 sender numbers, not JIDs.
  • groups.<JID>.requireMention defaults to true and silently blocks in applyGroupGating if the message has no real mention (and WhatsApp Web doesn’t always mark mentions correctly).

Full workaround is documented in @pandeysoni’s comment on issue #54613.

Sessions and Conversation Context

OpenClaw has native sessions per channel+group. SessionKey:

agent:<agentId>:whatsapp:group:<JID>

Persisted in ~/.openclaw/agents/<agentId>/sessions/<uuid>.jsonl — JSONL with each turn (user message + tool calls + agent response). Consecutive messages in the same group share context, so “add 1 more” after “how much sugar does it have?” works.

To debug a conversation:

docker exec openclaw-gateway cat ~/.openclaw/agents/main/sessions/<uuid>.jsonl

MCP Transport: Legacy SSE, Not Streamable HTTP

OpenClaw 2026.4.x uses legacy HTTP+SSE for MCP, not Streamable HTTP (the newer protocol). The client sends a GET to the configured URL and expects a text/event-stream response with an event: endpoint handshake. Servers that return 405 on GET (common with Streamable HTTP-only stateless servers) fail with SSE error: Non-200 status code (405).

Solution: implement SSEServerTransport from @modelcontextprotocol/sdk alongside Streamable HTTP, exposing GET /sse (handshake) + POST /messages?sessionId=<id> (client messages). Configure MCP in OpenClaw pointing to /sse:

openclaw mcp set <name> '{"url":"http://host:port/sse"}'

Gateway Mode Is Required

gateway.mode must be set (local or remote). Without it, gateway start is blocked and openclaw doctor complains. The default is not populated — missing this once cost a full day of debugging.

Useful Debug Commands

# General status
openclaw doctor
openclaw channels status --probe

# View recent inbound/outbound
docker exec openclaw-gateway cat /tmp/openclaw/openclaw-$(date +%F).log | grep web-inbound | tail -5
docker exec openclaw-gateway cat /tmp/openclaw/openclaw-$(date +%F).log | grep web-auto-reply | tail -5

# MCP discovery
docker logs openclaw-gateway | grep bundle-mcp

# Heartbeat (check messagesHandled and lastInboundAt)
docker exec openclaw-gateway tail -3 /tmp/openclaw/openclaw-$(date +%F).log

# List groups visible to Baileys (after hydration)
openclaw directory groups list

Strategy for Debugging Silent Symptoms

When “messages aren’t arriving” and no log explains it, patch the dist file with console.error at critical points. The path is /app/dist/extensions/whatsapp/monitor-BXydC-6q.js (the hash in the filename changes with each release). Useful points to instrument:

  • handleMessagesUpsert (entry) — confirms Baileys delivers
  • normalizeInboundMessage null returns — ACL, recent outbound echo, status broadcast
  • enrichInboundMessage null return — unsupported format
  • claimRecentInboundMessage — dedup
  • enqueueInboundMessage — confirms entry into the pipeline

Back up first (cp file file.bak), then cp file.bak file to restore.

Recommendations for Other Deployments

  • Avoid DinD if possible. The outer host’s Docker daemon vs the container runs in different namespaces, and bind mounts break silently.
  • Use mcpServers from the start instead of proprietary TS plugins. MCP is the official path and is reusable (Claude Desktop, Cowork, etc. consume the same server).
  • Patch dist files carefully. Keep versioned backups; an OpenClaw upgrade will overwrite the files, losing patches. Consider forking the image with a multi-stage Dockerfile.
  • Baileys sessions are fragile. Schedule a preventive weekly restart (cron) and monitor messagesHandled in the heartbeat — if it stays at 0 for more than 1h while connected, it’s time to re-login.

Building or Buying: The Agentic Analytics Dilemma

Every company, when evaluating new tools, technologies, or infrastructure, eventually runs into the same question:

“Should we build this ourselves or buy a ready-made solution?”

The default answer is often: “We can do it ourselves.” And technically, that’s true.

But the real question isn’t whether it’s possible. It’s how fast and how efficiently you can get there. How long will it take to get something working? And more importantly, how long will it take to make it reliable, maintainable, and usable across the company?

Those are very different problems, and in the context of agentic analytics, the gap between them is especially wide.

We often start with the wrong question

Most build vs. buy discussions are approached with a narrow perspective:

“If we simply plug an LLM into our database and documentation, will that give us what we need?”

In early demo stages, this option often works surprisingly well. But it reduces the problem to a single dimension: evaluating model performance on a limited snapshot of data and context.

What it doesn’t capture is what happens next, once the system is used across teams, over time, in real workflows. Questions of consistency, reuse, maintainability, cost, and integration – all of which matter in production – are often overlooked at this stage, even though they ultimately determine whether the system succeeds or fails.

So the real question isn’t: “Can we make this work?”

It’s: “What does it take to make this work reliably across the business, over time?

Where most DIY approaches fail

In the early stages, DIY setups often look promising. You connect an agent to your warehouse, add some documentation, and run a few queries. The results can be impressive, especially compared to having no solution at all.

But the issues don’t show up in demos. They show up later as the scope expands and becomes more complex. They usually revolve around four main pitfalls commonly found in organizations.

1. Ambiguous business logic

DIY setups typically rely on documentation written in plain English, data catalogs, or a mix of both. These are quick to produce, but they leave room for interpretation, especially across teams that use different definitions for the same metrics.

Take a simple example: What does “active customer” actually mean?

Is it someone who logged in in the last 30 days, made a purchase, or holds an active subscription?

Without a formal definition, the agent has to guess the meaning. And those inferences are not stable; they shift depending on context, phrasing, or even the model’s behavior. Over time, this ambiguity accumulates and leads to inconsistent answers that often look correct but aren’t.

2. Answer quality is a context problem

It’s tempting to assume that better models will fix these issues. In reality, answer quality depends far more on the structure of the underlying context than on the model itself.

When metrics are defined in a structured and consistent way, queries become repeatable. The same question leads to the same result, grounded in the same logic.

Without that structure, each answer becomes a new interpretation. That’s why systems that perform well in controlled benchmarks can fail in production, where the same questions are asked repeatedly, by different people, in slightly different ways.

3. Two sources of noise

Agentic analytics sits at the intersection of two unavoidable sources of noise:

  • The first comes from how users ask questions. Natural language is flexible, and the same intent can be expressed in many different ways.
  • The second comes from how metrics are defined. When definitions are written in free-form text, they introduce ambiguity and inconsistency.

These two types of noise amplify each other. As both the questions and the definitions become more complex, the system becomes increasingly unstable – unless there is a clear, structured layer underneath.

4. Maintainability is the real bottleneck

This is where most DIY projects start to break down.

Even if the system works initially, it raises a series of difficult-to-answer questions as time progresses.

What happens when a metric definition changes? How do you correct inaccurate answers? How does the system evolve as new data sources or teams are added? And what happens when the person who built the original setup is no longer involved?

Beyond that, there are operational concerns: tracking usage and adoption, controlling cost per query, and monitoring answer quality over time.

At this point, the scope has expanded well beyond a simple agent. What started as a quick experiment has grown into a broader system encompassing a semantic layer, integrations, monitoring, and internal workflows. In practice, you are no longer building a tool; you are maintaining an internal product.

The hidden cost of “just building it”

What begins as a lightweight prototype quickly turns into a multi-surface system. It needs to integrate into communication tools like Slack or Teams, provide usable interfaces, expose APIs or MCP servers, manage permissions, and offer visibility into performance and usage.

Each of these components introduces its own complexity. And most teams don’t account for this upfront, discovering it gradually, once the system is already in use.

This pattern shows up again and again:

  • Month 1: A prototype works → strong internal excitement.
  • Month 3: Inconsistencies appear → more prompt tuning.
  • Month 6: Another team tries it → results don’t transfer.
  • Month 9: Maintenance becomes ad hoc.
  • Month 12: The team starts evaluating alternative platforms.

DIY approaches can work, but they rarely scale without significant ongoing investment.

What actually matters when deciding whether to build or to buy

When evaluating whether to build or buy, the decision usually comes down to a few core considerations:

  • How quickly can you define your business logic in a way that is unambiguous and reusable?
  • Will your approach remain flexible as your data stack evolves?
  • Can you ensure that answers remain consistent over time?
  • Does the system improve with usage, or require continuous manual effort?
  • And finally, who is responsible for building and maintaining the full stack around it?

These questions matter far more than whether a prototype works on day one.

Who should actually build

There are cases where building your own solution makes sense. Typically, these are large organizations with dedicated platform teams, the resources to maintain a semantic layer as a product, and a long-term commitment to developing internal tooling.

For most companies, however, that level of investment isn’t realistic.

In the end, the dilemma is simpler than it appears:

Do you want to build and maintain an internal product, or use an existing one?

And if you choose to buy, the more important question becomes whether the platform you choose will remain flexible, transparent, and maintainable over time.

About Databao

Databao is built around this exact problem: making agentic analytics reliable without requiring teams to build and maintain the entire system themselves.

It focuses on generating a structured semantic layer automatically, keeping it aligned with real usage, integrating directly into existing workflows, and ensuring consistency over time.

If you’re evaluating how to bring AI into your analytics stack, we’d be happy to explore the process with you and provide a proof of concept for your individual use case.

TALK TO THE TEAM

Popular Go Web Frameworks: A Practical Guide for Developers

According to the 2025 Go Developer Survey, 46% of Go developers use the language to build websites and/or web services. It’s therefore unsurprising that the topic of web frameworks frequently pops up in conversation and is often the subject of healthy debate.

The GoLand team enters the chat armed with data to answer the question: What are the most popular web frameworks for Go developers and why?

Do I even need a framework?

Developers from environments that rely heavily on frameworks, such as JavaScript, will naturally seek out frameworks to simplify or reduce their workload. Meanwhile, hardcore Gophers will reject external libraries and frameworks altogether as superfluous dependencies that ultimately make their work harder. Both sides are right to some extent; using Go’s standard library exclusively comes with its own set of pros and cons.

Reasons to use net/http

  • Robustness: Go famously has a “batteries included” approach, and the net/http package is no exception. Go’s standard library provides a solid foundation for building web services; in particular, it already includes routing, middleware composition via handlers, and an HTTP server implementation.
  • Simplicity: The standard HTTP package has no extra frills or dependencies. This means developers often write more boilerplate, but it also provides clear and predictable building blocks that can be composed however a project requires.
  • No dependencies: Some developers prefer to exclusively use net/http, so as to avoid external dependencies. Third-party libraries are only good as long as they’re maintained, and they can always introduce security risks and maintenance overhead. Especially in larger commercial projects, these limitations are often unacceptable.
  • Full control: Developers who stick with net/http have full control over their code and don’t have to pay the “overhead tax” for features they don’t use that come with the libraries.
  • Maintenance and growth: Go is regularly maintained by the Google team, and new features are added consistently, such as enhanced routing patterns in 1.22.
  • Standardization: Since every Go developer knows net/http (or so we hope), in commercial settings, this eliminates the need to learn new tools to become productive when a new developer is hired.

Reasons not to use net/http

  • Lack of built-in abstractions: It’s not that the standard library can’t handle complex scenarios; it’s that it can quickly turn into a nightmare for the engineer who has to provide instructions on how to handle them. Many developers turn to external libraries for the convenience they provide when it comes to routing or middleware management.
  • Productivity loss: As is often the case with Go, using standard solutions equals writing a lot of boilerplate code to stitch things together, which forces developers to work on mundane tasks, negatively affecting their productivity.

Whether you are convinced by the arguments for or against, the truth remains that – according to JetBrains State of Developer Ecosystem Report 2025 – as much as 32% of Go developers use net/http, and its popularity remains largely unchanged.

Most popular Go web frameworks

Unlike a lot of other languages – as is the case with Ruby and Rails or Python with Django or Flask – there isn’t one dominant framework that every Go developer would recognize and use. While stdlib remains a popular choice, our data shows that it has a formidable opponent, used by almost half of Go developers – Gin.

On top of that, in our analysis of The Go Ecosystem in 2025, we’ve identified the most widely used web frameworks to be Gin (48%), Gorilla (17%), Echo (16%), and Fiber (11%).

Now, let’s look at how they stack up against each other and against net/http and see if there is a clear winner when it comes to web frameworks for Go (spoiler alert: There isn’t 😉).

Gin

Gin is an HTTP web framework for building REST APIs, web applications, and microservices in Go. It offers middleware support, JSON validation, route grouping, error management, and built-in rendering. Gin is highly extensible and remains the top choice for Go developers as one of the fastest regularly maintained frameworks with a developer-friendly API. It has over 88,000 stars on GitHub and a sizable community around it, so you can expect to find a lot of examples and support from other developers when you run into trouble.

You can create a router engine in Gin with (gin.Default()) or without (gin.New()) middleware attached, depending on how much control you need. gin.Default() comes with logger and recovery middleware out of the box. Other middleware lives in the official gin-contrib collection, where you can find a CORS mechanism, as well as authentication, session manager, pprof, and other tools.

Gin’s creators boast that its “performance [is] up to 40 times faster than Martini”, though in 2026, this probably doesn’t indicate much. Thankfully, they also run their own benchmarks, allowing you to compare Gin’s performance against a number of more modern libraries as well. And while Gin is not the most performant in all scenarios (Aero actually takes that cake), the results are still very close to the top across the board. This is largely due to zero-allocation routing, which keeps the app memory usage stable even under high traffic.

Gin is an opinionated framework, which means it follows its own approach. For example, it uses gin.Context instead of the standard context.Context. It is still built on top of net/http, but if your code depends heavily on Gin-specific features, moving to another framework later may require extra work.

Pick Gin if you want a framework that:

  • Is familiar to most developers and thus easier to adopt.
  • Has community support and lots of learning resources, making onboarding and troubleshooting easier.
  • Provides simple, widely adopted patterns for easier development.

Echo

Echo is yet another high-performing and minimalist framework that has an HTTP router without dynamic memory allocation. It includes automatic TLS, support for HTTP/2, middleware, data binding and rendering, and various template engines. It’s also very extensible at various levels. It continues to grow in popularity, with 16% of Go developers declaring its use in 2025.

Echo has a broad catalog of official middleware that you will also find in other frameworks, such as CORS, JWT, and key authentication tools, as well as a logger and rate limiter.

Similarly to Gin, Echo is built on top of net/http, but it does deviate from it at times. For example, it uses Echo.context instead of context.Context. Also, Echo handlers use the signature func(echo.Context) error rather than http.HandlerFunc, but Echo provides adapters to integrate standard net/http handlers when needed.

Choose Echo if you:

  • Care about clean, centralized error handling and handlers that return errors.
  • Need a more structured, “batteries-included” framework.

Chi

Chi also claims to be a lightweight yet robust composable router for building Go HTTP services. Some would argue it’s not really a framework, but it’s still quite popular with Go developers, ranking as the fifth most popular alternative (used by 12% of developers in 2025).

Chi’s authors claim it offers “an elegant and comfortable design” for large REST APIs, and the framework itself is deconstructed into smaller parts. You can use the standalone core router or extend it with subpackages for middleware, rendering, and/or docgen. Other key features include full compatibility with net/http and no external dependencies. Chi uses standard Go handler types and middleware shape.

This means that Chi is compatible with all standard middleware, giving you more flexibility. Its optional middleware package includes a suite of core net/http tools, and on top of that, there are also extra middleware and other packages. Some noteworthy middleware options include: CORS, JWT auth, request logger, and rate limiter tools.

You can check Chi’s benchmarks here, though they are rather old.

It’s worth considering Chi if:

  • You want to stay close to the standard library: Some would argue there’s no point in even using Chi because you can achieve the same thing with net/http. If, however, you feel that a router would make your life easier, but you still want full compatibility with stdlib, Chi might be the choice for you.
  • You want more of a router than a full framework.

Fiber

Finally, there’s Fiber – a framework that JavaScript developers in particular will be very fond of, as it’s inspired by Express. It boasts robust routing, the ability to serve static files, API-readiness, a rate limiter, flexible middleware support, low memory footprint, support for template engines and WebSocket, and – you guessed it! – great performance. The Fiber team provides its own benchmarks here. It’s the last framework that’s been adopted by over 10% of developers according to our survey.

What differentiates Fiber from the other frameworks we’ve already discussed is that it’s built on a different HTTP engine – fasthttp. It can interoperate with net/http; however, the compatibility is provided through adapters and not through shared foundations. As Fiber’s architecture is fundamentally different from the standard library, choosing it locks you in more than other frameworks do, and migrating between Fiber and net/http frameworks typically requires more refactoring.

Considering Fiber’s architecture, it’s no surprise that it offers the broadest built-in toolbox of all the frameworks discussed. On top of that, it also has a whole host of third-party middleware maintained by the Fiber team or the community. Some of the most popular middleware options for Fiber are: a template engine, adaptor that converts net/http handlers to Fiber handlers and vice versa, Helmet integration, and key authentication tools.

Fiber is especially good for:

  • Developers with experience using Express.js: JavaScript developers who used Express before will feel right at home with Fiber because of the similarities.
  • Projects where performance is really crucial, even at the expense of idiomatic Go.

(Honorable mention) Gorilla

Strictly speaking, Gorilla is not a full-blown framework but rather a toolkit, and Gorilla/mux is just a router. But we include it on the list due to its enduring presence, with 17% of developers still using it in 2025. Even with a sharp decline in popularity compared to 2020, it’s still the third most popular choice (after Gin and net/http), despite the project no longer being actively maintained by the original team (the last update was in November 2023). While community forks continue development, most new projects today veer towards alternatives, such as Chi, or the improved routing features in Go’s standard library.

So how do they stack up?

net/http Gin Echo Chi Fiber
HTTP engine stdlib net/http net/http net/http fasthttp
Compatibility with net/http Native Partial  Partial Full Via an adapter
Maintenance Core Go Active Active Active Active
Performance High Very high High High Extremely high
Learning curve Low Low Medium Very low Medium
Standout features No dependencies; standardized solution Wide adoption; robust community support Clean error handling; “batteries-included” approach Closeness to stdlib; minimalist features Similarity to Express; extremely high performance
Dependencies None Moderate Moderate Very low Significant
Extensibility Very high Moderate – sometimes requires adaptation Moderate – requires wrapping Very high Low – mostly incompatible with standard middleware 
Ecosystem The largest and most mature; supported by Google Very mature with the largest community and adoption after net/http Mature with a strong community and long-term maintenance Mature with a sizeable community Younger framework, with a community that’s still expanding
Compatibility with net/http Native Opinionated, but built on net/http Built on top of net/http Designed around net/http – fully compatible Not directly compatible, built on fasthttp

Code samples

To show you how each framework handles API ergonomics, how verbose it is, and how it deviates from idiomatic Go, here’s a sample of the same API endpoint implemented in different frameworks.

net/http

// net/http
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(users)
})

Gin

// Gin
router.GET("/users", func(c *gin.Context) {
    c.JSON(200, users)
})

Echo

// Echo
e.GET("/users", func(c echo.Context) error {
    return c.JSON(200, users)
})

Chi

// Chi
r.Get("/users", func(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(users)
})

Fiber

// Fiber
app.Get("/users", func(c *fiber.Ctx) error {
    return c.JSON(users)
})

How can GoLand help web developers?

Using frameworks is not the only thing that can make your life easier; your IDE can help you stay productive as well, without locking you in. Here’s how using GoLand can help you as a web developer.

  • HTTP Client: With the HTTP Client plugin, you can create, edit, and execute HTTP requests directly in the GoLand code editor. This is especially useful when you are developing a RESTful web service or an application that interacts with one. This tool includes features like code highlighting, completion, folding, live templates, and language injections.
  • Endpoints tool: This window provides an aggregated view of client and server API used in your project for HTTP and WebSocket protocols. It can help you when you’re developing microservices, backend-frontend communication, and when you need to explore third-party APIs.

Frequently asked questions

What is the difference between Go’s standard library and a web framework?

Like in any other language, libraries are there to provide solutions to common problems and free up your time to focus on important work. While Go’s standard library, and net/http in particular, contain everything you need to build a production-ready web server, the libraries described in this article will help you avoid a lot of boilerplate and simplify common tasks such as routing, middleware composition, and request binding.

Why doesn’t Go have a single dominant web framework?

In the Go ecosystem, frameworks are optional rather than foundational. Many production services are built directly on top of net/http, while others use lightweight routers or frameworks to simplify common tasks.

Because the standard library is so robust, for many engineers, there isn’t really a good justification for using frameworks that require learning their syntax, create extra dependencies, and force regular updates. There isn’t a single dominant framework because none of them is superior to stdlib; they just offer different tradeoffs.

Are Go web frameworks necessary for production applications? Is net/http sufficient for building scalable APIs?

One of Go’s key differentiators is that, technically, you don’t need any external libraries for your application. Go’s standard library has everything you need, regardless of the scale of your project, and some hard-core Gophers stick to only that.

This is not to say that libraries are bad or useless – if they make your life easier and you’re aware of the tradeoffs, there’s really no reason not to use them.

What should I consider when choosing between Gin, Echo, Fiber, and Chi? Is one of them better for APIs or microservices?

While most Go web frameworks support common features such as routing, middleware, and JSON handling, they differ in architecture, ecosystem compatibility, and how closely they follow net/http. When deciding on the right one for you, focus primarily on what your team and project need.

  • If you’re looking for an established solution with a solid knowledge base that’s familiar to everyone, consider Gin.
  • If you need a more structured framework with centralized error handling, go for Echo.
  • If you’re after a lightweight router and need full compatibility with net/http, Chi is your best bet.
  • If you’re familiar with Express.js or you need extreme performance, even at the cost of compatibility, think about Fiber.

Does using Fiber limit compatibility with the Go ecosystem?

To a certain extent – yes, at least more than the other frameworks mentioned in this article. Because Fiber was designed around fasthttp, it had to make architectural trade-offs.

The biggest limitation is that you cannot use the vast library of generic Go middleware with Fiber out of the box. You therefore need to use middleware maintained by the Fiber team or employ an adapter (adaptor.FromHTTP), which introduces performance overhead and effectively defeats the reason to use Fiber in the first place.

[Livestream] TeamCity 2026.1: AI, Pipelines, and Enterprise CI/CD Improvements

TeamCity 2026.1 introduces a set of focused improvements that make your CI/CD more intuitive, intelligent, and enterprise-ready.

Join us for a live walkthrough of the latest updates, including support for both the Kotlin DSL and YAML in pipelines.

We’ll also introduce the new TeamCity CLI, which includes agent skills for popular AI coding agents like Claude Code, Codex, and JetBrains Junie. The TeamCity CLI helps developers run and manage TeamCity commands directly from the terminal. With added MCP support, it also connects TeamCity to leading AI tools across different environments.

📆 May 12 at 18:00 CEST

🔗 https://jb.gg/6u3izo

Register now

We’ll share how these changes fit into TeamCity’s broader evolution, including AI-assisted workflows and a more flexible pipeline experience, and what’s coming next on our roadmap.

Whether you’re already using TeamCity or exploring modern CI/CD approaches, this session will give you practical insights and a look at where TeamCity is heading.

Speaking to you

Daniel Gallo, Solutions Engineering Lead, TeamCity

Daniel is a Solutions Engineering Lead on the TeamCity team at JetBrains. With over 20 years of experience in the software development industry, he has held diverse roles, including Software Developer, Senior Systems Analyst, and Solutions Engineer. In his current role, Daniel works with customers worldwide, helping them understand TeamCity and optimize their CI/CD build pipelines.

Ernst Haagsman, Product Manager, TeamCity

Ernst is a Product Manager at JetBrains, where he works on strategy for TeamCity. In his time at JetBrains, he has worked on a range of developer tools and platforms, including IntelliJ IDEA, remote development, and IDE Services. With hands-on experience in software, DevOps, and working with enterprise customers, Ernst brings a practical perspective to improving developer workflows. Before joining JetBrains, he worked in the games industry.

Introducing the Skill Manager and Skill Repository

Install trusted skills once, then use them across agents and projects.

Two new features have just arrived in AI Assistant to address this issue: the skills manager and the skill repository. Together, they make skills easier to discover, trust, and reuse. Instead of keeping skills tied to one agent or project you can install them once and use them wherever they are needed while managing them from inside the IDE.

In practice, a skill gives an agent reusable capabilities for a specific task. The problem is that skills often stay tied to a single setup. They live with one agent, one repository, or one machine. Skills Manager changes that by making them reusable across projects and supported agents.For a quick introduction to what skills are, check out this great explanation from PyCharm Content Creator Kristel Cocoli.

Skills manager: One place to install, manage, and reuse skills

Skills are useful because they give agents reusable capabilities for specific developer tasks, whether that is debugging CI failures, working through PR comments, automating browser flows, or converting Java to Kotlin. The problem is that they often stay locked to a single setup.

Skills Manager fixes that by adding a new IDE layer for skill management. That means developers can install skills once inside the IDE and make them available across supported agents and across all projects opened in that IDE, instead of rebuilding the same setup over and over.

It also supports different ways of working depending on the task. Some skills belong at the IDE level, where they stay available across projects for an individual developer. Some belong at the project level, where they can travel with the repository and be shared through version control. Others are best kept agent-specific, tied to a dedicated workflow like CI triage, frontend work, or code review.

That is the core improvement: Skills Manager gives developers one place to discover recommended skills, choose the right scope for each one, and keep those skills available where the work actually happens.

Skill repository: A verified starting point

The skills manager makes skills easier to use. The skill repository makes them easier to get started with.

At launch, the repository gives you a JetBrains-filtered and verified list of skills, organized for easier discovery and reuse. Instead of building a collection from scratch or managing it by hand, you get a curated starting point with skills that are ready to be installed.

The repository is also designed to make adoption safer. New additions are screened to detect prompt injection, data exfiltration, and malicious code patterns. Attribution is preserved by using the skill’s own author metadata when available, or otherwise crediting the upstream maintainer or organization. That gives you a practical starting point you can trust, with useful skills, a safer adoption path, and clear credit to the people who created them.

Recommended skills to try first

Here are just a few examples from the repository that show the range of tasks where skills can be used to guide agents with improved accuracy. To view the full repository, check out this link: https://github.com/JetBrains/skills. 

  • React-best-practices –  Reusable React and Next.js guidance for writing, reviewing, and refactoring frontend code.
  • postgres-best-practicesPractical guidance for Postgres queries, schema design, performance, and security.
  • playwrightA structured way to automate and debug real browser flows.
  • pnpmBetter support for pnpm-based JavaScript projects, including workspaces and CI usage.
  • kotlin-tooling-java-to-kotlinSupport for disciplined migration from Java to idiomatic Kotlin.

Transparency and limitations

Skills Manager introduces an IDE-wide layer so developers can install skills once and make them available across supported agents and all projects opened within the IDE. That is the recommended default experience, but support is not universal yet.

  • Today, IDE-wide skill storage is supported in AI Assistant Chat for Codex and Claude Agent. Support for Junie and other ACP agents is coming.
  • For CLI workflows, the experience is different. CLI agents cannot use IDE-installed skills, so terminal-based workflows still rely on project-level or agent-specific installation.
  • Support also differs slightly between agents. Due to harness’ configuration Claude Agent can’t work with .agents folder and uses its own agent-specific location  (.claude folder), instead of the shared project location.
  • The repository will also keep expanding over time, including with more IDE-specific skills.

Get started

To get started, install the AI Assistant plugin in your JetBrains IDE. In the AI chat, click the + button and go to Skills to add, remove, and manage the skills that fit your workflow. Watch this video from JetBrains Developer Advocate Michelle Frost to see how installation works and which skills she recommends.

The “Bug-Free” Workforce: How AI Efficiency Is Subtly Disrupting The Interactions That Build Strong Teams

Through many discussions with industry colleagues, we’ve started hearing a phrase more often when swapping stories about AI adoption:

“Now I don’t have to bug [someone].”

Product designers don’t need to bug researchers anymore — retrieval-augment generation (RAG) tools surface insights instantly. Product Managers don’t need to bug designers for mockups — AI generates acceptable options. Engineers don’t need to bug accessibility teams — automated scanners flag issues in real-time.

It’s framed as liberation, and in many ways, it is. There’s genuine relief in being unblocked, in not having to wait, in solving problems independently.

With AI, we’re building a “bug-free workforce”.

But what if the bugs that AI is automating away, such as the quick questions, the small talk, the organic connections, are actually an important part of the scaffolding that builds and sustains healthy teams?

The Vanishing Scaffolding

Consider what actually disappears when we turn to AI assistance before engaging with a colleague directly. For instance:

  • The 2-minute Slack exchange that turns into a 20-minute whiteboarding session.
  • The “quick question” that reveals a fundamental misalignment.
  • The accessibility review that becomes mentorship.

Although these interactions are primarily intended to exchange information and unblock individuals’ tasks, many are the building blocks for the intangible but crucial sense of belonging and connection in the workplace.

The inefficiencies of interpersonal communication and daily interaction build the larger organism known as work culture. When AI disrupts these interactions, what is lost?

What The Research Actually Shows

There is ample psychological research to support our hypothesis: If the trust built through organic and informal connections is threatened, teams will be negatively impacted. Let’s examine a few:

In 2012, MIT’s Human Dynamics Lab (Pentland, 2012) discovered that the best predictor of team productivity wasn’t formal meetings but “energy” from informal communication: the hallway conversations, coffee chats, and quick questions. Teams with the most informal interaction had 35% more successful outcomes. With AI, what energy is not generated, leading to fewer successful outcomes?

In 2015, Google’s Project Aristotle studied over 180 teams to find out why some thrived, and others underperformed. They found that psychological safety, the shared belief among team members that the environment is safe for interpersonal risk-taking, built through frequent, low-stakes interactions, was the number one predictor of high performance. Not intelligence. Not resources. Trust built through micro-moments. The exact micro-moments we see vanishing when we overuse AI.

In 2025, researchers from Harvard, Columbia, and Yeshiva University published a study focused on the impact of AI on performance and team coordination. The authors concluded that AI-driven automation decreased overall team performance and increased coordination failures. These effects were especially large in the short-term and in low- and medium-skilled teams. Automation also decreased team trust.

Why This Matters

When AI disrupts the team’s energy and psychological safety, a sense of disconnection sets in, which, in turn, hurts the company’s bottom line.

Disconnected Employees Leave

People don’t stay at companies because of the work. They stay because of the people. And if connections to colleagues decrease due to AI’s presence, how might that expedite one’s departure?

Consider this question in dollar terms. McKinsey’s Great Attrition research found that not feeling a sense of belonging was one of the most frequently cited reasons employees left. When informal micro-interactions disappear, belonging erodes, and people walk.

“Employee disengagement and attrition could cost a median-size S&P 500 company between $228 million and $355 million a year in lost productivity.”

— McKinsey

Leaders must ask themselves if the potential gains from AI rollouts and promised productivity gains outweigh the costs of a disengaged and attrition-prone workforce. The evidence suggests otherwise.

Disconnected Teams Are Less Innovative

Korean researchers in 2024 analyzed innovation in the private sector and concluded that weak ties — the bridging conversations with people you interact with occasionally — sustained innovative performance in companies characterized by active technological innovation.

Simply put, breakthroughs do not necessarily emerge from your core team but from interactions with the people you would have “bugged” in the past. Eliminating these interactions in favor of AI could not only negatively impact team health, but it could also hurt the business through decreased depth and breadth of innovation in design, coding, content, and beyond.

AI’s seduction is that it feels like pure gain until the team realizes they’ve become strangers who happen to work on the same project.

If a shared sense of purpose and belonging disappears, employers have a workforce less engaged and less innovative, with a higher chance of attrition.

If AI helps us need each other less, how can a company hope to nurture a connected, supported, and effective workforce?

The answer requires a balanced and multi-pronged approach. Use AI tools for dull, repetitive, and high-volume tasks while reserving the human brain for higher-level problem solving. Design physical workspaces and online team interactions that will maintain or increase human connection.

Maintaining The Best Of Both

In short, leverage the best of AI tools and human abilities.

1. Use AI To Eliminate The Toil

In the March 2026 article “When Using AI Leads to ‘Brain Fry’,” the authors outline their study of 1,488 full-time U.S.-based workers to understand the impact of AI use on professionals. The result was a concept they call “AI Brain Fry,” a form of acute mental fatigue and cognitive exhaustion resulting from excessive use, interaction, or oversight of AI tools beyond an individual’s cognitive capacity.

Further, the study reveals that the cognitive strain created by intensive AI use carries business costs, including decision fatigue and error-prone work. Perhaps the most troubling finding is that 34% of workers who reported experiencing brain fry intended to quit their jobs. The loss of institutional knowledge caused by turnover is well documented.

One conclusion is that AI is not inherently bad or cognitively taxing. Rather, as with any tool, what matters is how it’s used.

Focusing our energy on identifying the repetitive, unenjoyable parts of our jobs (or “toil”) and using AI to remove them is a way to improve cognitive and team health.

Indeed, the Harvard Business Review authors explain that participants in their study who used AI to eliminate toil only had 15% lower rates of burnout but also reported “a higher degree of social connection with peers…because they had more time to spend ‘off keyboard.’” In this toil-elimination scenario, AI did not disrupt team connections; it removed what we consider busy work that prevented the team from solving problems with colleagues.

2. Institutionalize Productive Friction

Steve Jobs famously designed the Pixar studios so employees would have to bump into each other. “Steve realized that when people run into each other, when they make eye contact, things happen,” reflected Brad Bird, the director of The Incredibles and Ratatouille movies. John Lasseter, responsible for some of Pixar’s most beloved films, shared that he’d “never seen a building that promoted collaboration and creativity as well as this one.” Jobs understood that serendipitous collision drives creative work, and Pixar’s oeuvre reveals the genius.

What is the equivalent of creating this type of organizational design in the age of AI?

  • Build AI tools that connect the team.
    We’ve found that when building internal agents, it’s best to attach the names of the original creators to the work and to direct seekers to these creators. This way, any seeker not only finds the answer but is connected to others with more institutional knowledge to help.
  • Publicly spotlight successful team uses of AI.
    By finding examples of how teams have used AI to work more effectively and efficiently together and highlighting them in public forums and townhalls, it helps establish the narrative that AI can be something that brings us together rather than pushes us apart.
  • Establish rotation programs.
    If AI means product managers can prototype, have them shadow designers anyway. Having a more holistic understanding of each other’s craft through direct dialogues benefits both sides beyond simple AI outputs.
  • Hold panel discussions on the evolution of work.
    Gather cross-functional partners to regularly discuss and debate how our work is currently changing or could in the near future. It keeps intentional change top of mind and in the open.

3. Build Team Cohesion Through AI-inspired Laughter

Positive humor in the workplace has been studied extensively as a way for teams to bond. We see how AI can improve team connections through a good, absurd laugh.

  • Bad UX Vibecoding Competitions
    Give your team a silly prompt (“Design the worst volume control”) and 30 minutes to vibe-code a horrible solution. The process of building these outputs helps the team: learn new AI tools, get the creative juices flowing, and, most importantly, laugh together.

  • Hyper-specific AI Creations
    Would a certain image make people smile in this workshop? Is there a funny idea at work that would be even weirder as an AI-generated song? Using them for absurd work moments is a fun way to get people laughing.

Eliminating toil, institutionalizing productive friction, and building team cohesion through humor show the power of integrating the best of the human brain and AI algorithms.

The question isn’t whether to use AI. Contemporary workers have less and less choice. The question is: what kind of team do you want to become when AI is the newest teammate?

Conclusion

Leaders who introduce artificial intelligence with an equal amount of emotional intelligence will enable their teams to thrive by leveraging the power of AI while also shielding their teams from the inherent risks associated with the disruptive natures of these new tools.

When the unexpected hits — the crisis, the pivot, the moment that requires trust you can’t manufacture overnight — it will be the teams with cultures intact that will thrive.

References

  • The 4 Stages of Psychological Safety: Defining the Path to Inclusion and Innovation, Clark, T. R. (2020), Berrett-Koehler Publishers
  • What Google Learned From Its Quest to Build the Perfect Team, Duhigg, C. (2016), The New York Times Magazine
  • Psychological Safety and Learning Behavior in Work Teams, Edmondson, A. C. (1999), Administrative Science Quarterly, 44(2)
  • The Strength of a Weak Tie in the Innovative Performance of Firms: A Case of Korean High-tech Manufacturing Small and Medium-sized Enterprises, Hong, Jinki; Lee; Raehyung; Ohm, Jay Y.;, Lee, Duk Hee (2024), Sociology Compass Volume 18, Issue 5
  • How Psychological Safety Impacts R&D Project Teams, Liu, Yuwen; Keller, R.T. (2021), Research-Technology Management Volume 64, Issue 2
  • Creating Psychological Safety in the Workplace, McCausland, Tammy (2023), Research-Technology Management Volume 66, Issue 2
  • Some Employees Are Destroying Value. Others Are Building It. Do You Know the Difference?, De Smet, Aaron; Mugayar-Baldocchi, Marino; Reich, Angelika; Schaninger, Bill (September 11, 2023), McKinsey Quarterly
  • The New Science of Building Great Teams, Pentland, A. (2012), Harvard Business Review
  • Super Mario Meets AI: Experimental Effects of Automation and Skills on Team Performance and Coordination, Dell’Acqua, Fabrizio; Kogut, Bruce; Perkowski, Patryk (2025), The Review of Economics and Statistics 107 (4)
  • Humor Is Serious Business: Why Humor Is A Secret Weapon In Business And Life, Aaker, J; Bagdonas, Naomi (2021)

SQLite Verification, pg_savior, & PostgreSQL Restore Strategies

SQLite Verification, pg_savior, & PostgreSQL Restore Strategies

Today’s Highlights

This week, delve into SQLite’s rigorous formal verification, discover a new PostgreSQL extension for preventing accidental data modifications, and learn about redesigning PostgreSQL backup strategies for robust restores.

Reply: Formal verification for SQLite (SQLite Forum)

Source: https://sqlite.org/forum/info/244c91ec88a019145e7b340d98b988cf8666690dc8a0a2c8eae7aa152c81b53a

This forum discussion highlights SQLite’s unwavering commitment to formal verification, a rigorous process of mathematically proving the correctness of software code. SQLite is renowned for its exceptional reliability and stability, and formal verification plays a pivotal role in achieving this unmatched quality. The discussion likely explores the sophisticated methods and tools employed, such as abstract state machines and advanced theorem provers, to ensure the database engine operates without bugs, inconsistencies, or vulnerabilities, particularly concerning transactional integrity and data persistence.

This meticulous approach to development sets SQLite apart, offering unparalleled confidence in its operation. Such deep technical assurance is critical for embedded systems, mission-critical applications, and any scenario where data integrity and system robustness are paramount. Understanding SQLite’s dedication to formal verification sheds light on why it remains one of the most deployed and reliable database engines in the world, impacting countless applications from web browsers to IoT devices.

Comment: Gaining insight into SQLite’s formal verification process reinforces immense confidence in its reliability for critical applications, showcasing the profound engineering and attention to detail behind its consistent robustness.

pg_savior: a seatbelt for Postgres – blocks accidental DELETE/UPDATE (r/PostgreSQL)

Source: https://reddit.com/r/PostgreSQL/comments/1swdar1/pg_savior_a_seatbelt_for_postgres_blocks/

pg_savior is a new PostgreSQL extension designed as a crucial safeguard to prevent accidental DELETE or UPDATE statements on live production databases. This innovative tool acts like a “seatbelt” for your database, adding a critical layer of safety by proactively blocking potentially destructive DML (Data Manipulation Language) operations unless a specific, temporary bypass mechanism is explicitly enabled by the user.

It is an invaluable asset for database administrators and developers who frequently interact directly with production environments, where even a minor typo or a moment of oversight can lead to significant data loss or corruption. The extension likely operates by intercepting DML commands at a low level, checking for a pre-defined override flag or a specific session setting before allowing the query to execute. This provides a much-needed defense against human error, significantly enhancing database reliability and operational safety without necessitating complex or intrusive changes to existing application codebases.

Comment: This is an ingeniously practical extension that directly addresses a common DBA nightmare. I’m definitely installing pg_savior in our staging environments immediately to prevent accidental data modifications during testing, and considering its robust application in production.

I redesigned my PostgreSQL backup strategy after realizing restores were the real problem (r/PostgreSQL)

Source: https://reddit.com/r/PostgreSQL/comments/1sw3zhd/i_redesigned_my_postgresql_backup_strategy_after/

This insightful post details a critical paradigm shift in thinking about database backups: the author argues that while creating backups is often perceived as straightforward, designing a truly reliable and efficient restore process is the real, often-underestimated, challenge. The article shares practical insights gained from redesigning a PostgreSQL backup strategy, specifically tailored for Docker deployments, emphasizing the often-overlooked complexities involved in achieving swift and accurate data recovery.

The discussion likely delves beyond simple data dumps, encompassing crucial aspects such as the comprehensive verification of restore procedures under various failure scenarios, ensuring absolute data consistency post-recovery, and optimizing for key metrics like Recovery Time Objectives (RTO) and Recovery Point Objectives (RPO). This approach involves automating restore tests, implementing robust backup retention policies, and meticulously documenting recovery plans. This guide offers invaluable lessons for anyone managing PostgreSQL in production, providing a practical blueprint for building truly resilient data protection strategies, especially within modern containerized infrastructures.

Comment: This article’s emphasis on designing for restore reliability, rather than merely creating backups, is a crucial insight many overlook. The detailed approach to PostgreSQL backup and recovery in Dockerized environments is highly practical and directly applicable to optimizing our existing data protection strategies.