惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
Microsoft Security Blog
Microsoft Security Blog
NISL@THU
NISL@THU
T
Threatpost
T
The Exploit Database - CXSecurity.com
T
Threat Research - Cisco Blogs
S
Securelist
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
S
Secure Thoughts
MyScale Blog
MyScale Blog
O
OpenAI News
P
Palo Alto Networks Blog
美团技术团队
C
Cyber Attacks, Cyber Crime and Cyber Security
TaoSecurity Blog
TaoSecurity Blog
量子位
L
Lohrmann on Cybersecurity
G
GRAHAM CLULEY
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
Know Your Adversary
Know Your Adversary
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Simon Willison's Weblog
Simon Willison's Weblog
宝玉的分享
宝玉的分享
PCI Perspectives
PCI Perspectives
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tenable Blog
I
InfoQ
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Microsoft Azure Blog
Microsoft Azure Blog
Recent Announcements
Recent Announcements
S
Security @ Cisco Blogs
S
Schneier on Security
B
Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Cloudflare Blog
AWS News Blog
AWS News Blog
IT之家
IT之家
V
Vulnerabilities – Threatpost
The Hacker News
The Hacker News
H
Heimdal Security Blog
I
Intezer
A
Arctic Wolf
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
H
Help Net Security
W
WeLiveSecurity

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
A Cluster Stall Looks Healthy on Every Host. The Cause Is in the Pattern Across Hosts.
Ingero Team · 2026-05-06 · via DEV Community

Cluster-level GPU tracing diagram: eight ranks across two hosts (node A, node B) running ncclAllReduce, with rank 5 entering the barrier 290ms late and the other seven ranks blocked-in-ncclAllReduce while reading 95-99% utilization, fan-in into a single Ingero Echo DuckDB store on the right

Eight ranks on two hosts. Every per-host metric reads healthy. Rank 5 enters the barrier 290ms late. The cause lives in a cross-rank query, not in any single host’s trace.

Watch the demo (90 seconds): Echo starts on :4317, two echo-stress invocations push 2,000 events combined (node-a100 + node-h100), then DuckDB verifies they all landed and the causal-chain markers survived the wire.

asciinema cast: Ingero Echo cluster fan-in (90 seconds; click to play on asciinema.org)

TL;DR

Eight ranks on two hosts run an all-reduce. Token throughput drops 4x. Every per-host nvidia-smi reads 95-99% utilization. Every per-host eBPF trace looks clean. The cause is rank 5 on node B taking 380ms on a step that the other seven ranks finish in 90ms. The other seven ranks spend 290ms blocked inside ncclAllReduce, which counts as a running kernel and reports as healthy on every per-host metric. The diagnosis lives in a cross-rank query, not in any single host’s trace. We shipped Ingero Echo (a cluster-wide AI-investigation tool that auto-collects OTLP from every node and exposes it as MCP-over-DuckDB) to make those queries answerable for AI agents directly. This post walks through the proof: 2,000 events from two nodes, fan-in into one DuckDB, queries that surface the straggler.

What per-host tracing cannot see

A typical 8-GPU all-reduce on H100s runs at ~80GB/s ring bandwidth. The synchronization barrier is ncclAllReduce. Every rank enters at roughly the same wall-clock; the rank that finishes last sets the wall time for all eight. When one rank is slow, the other seven do not idle visibly. They sit inside ncclAllReduce, which is itself a CUDA kernel. nvidia-smi sees a kernel running. DCGM’s SM_ACTIVE ticks. Per-host eBPF sees cudaLaunchKernel -> ncclAllReduce -> cudaStreamSynchronize complete normally. The local trace is clean.

What each rank does NOT see:

  • That the seven other ranks are also blocked inside the same ncclAllReduce for the same window.
  • That one specific rank entered the barrier 290ms later than the others.
  • That this same rank-5 pattern repeats every 14 steps, hinting at a memory-fragmentation cycle on the slow host.

These are facts about the cluster, not facts about any host. A monitoring stack that ships per-host samples to a centralized dashboard can render them as time series, but a time-series view does not answer “which rank’s call stack caused the 290ms wait the other ranks observed?” That is a relational query across host boundaries.

The cluster-level question

The question that matters during a stall is:

For each step where end-to-end throughput dropped, which rank’s ncclAllReduce started later than its peers, and what was that rank doing in the previous 500ms?

To answer it, you need:

  • Every rank’s ncclAllReduce enter/exit events, timestamped with a clock that is consistent across hosts.
  • Every rank’s CUDA call stack and off-CPU events for the 500ms before each ncclAllReduce enter.
  • A causal chain identifier that links a single training step’s events across all ranks.
  • A single store you can SQL.

Ingero’s per-host agent already produces those events. The agent attaches uprobes to libcudart.so and libnccl.so, captures kernel-scheduler events with eBPF, and emits OTLP. The missing piece in v0.12.4 was the cluster-level destination: a place where every host’s stream could fan in, where the events keep their resource attributes (cluster ID, node ID, rank, nranks), and where SQL can join across ranks. v0.12.5 ships that piece.

Echo, in one paragraph

Ingero Echo is a cluster-wide AI-investigation tool for GPU observability. It auto-collects OTLP/gRPC streams from every Fleet collector in the cluster into embedded DuckDB (one writer, single-statement read-only SQL), then exposes that data through a Model Context Protocol server with four tools: fleet.cluster.event_history, fleet.cluster.find_outlier_nodes, fleet.cluster.run_analysis (SQL-only, gated by a lexical guard), and fleet.cluster.get_cost. AI agents (Claude, Cursor, ollmcp, any MCP client) drive cross-rank investigations through this MCP-over-DuckDB surface without ever touching the database directly. Echo ships as a single-binary StatefulSet behind a ClusterIP service. The event-store path holds a flock(2) so a rolling-update force-detach does not corrupt the WAL. The receiver enforces bearer-token auth on the OTLP listener. The image is 87MB. One Echo per cluster.

The fan-in correctness proof

Before shipping Echo as a single source of truth for cluster-level queries, we wanted a hard answer to one question:

When N agents push concurrently from N hosts, do all events land, do causal-chain identifiers survive, and can a SQL query distinguish the straggler from the healthy ranks?

The proof is cmd/ingero-echo/integration_test.go plus a hardware run on Lambda Cloud. Eight concurrent producers, 250 events each, OTLP/gRPC into a DuckDB-backed Echo. Mixed across two cluster IDs. Causal-chain markers injected every 25th event. Stragglers (synthetic low-health-score events) injected every 100th. Total: 2,000 events.

The test asserts:

  1. All events land: SELECT COUNT(*) FROM events == 2000.
  2. Per-rank counts are correct: each of the 8 producer node IDs has exactly 250 events.
  3. Causal chains preserved across the wire: the 80 distinct causal_chain_id markers we inserted at the producer come back from the store. None lost. None merged.
  4. Stragglers surface in a cross-cluster query: SELECT node_id, COUNT(*) FROM events WHERE value_double < 0.4 GROUP BY node_id returns the 18 events we injected and only those.
  5. Burst write does not lose events under contention: a separate test runs 5,000 events at ~1k EPS through WriteEvents from 8 goroutines simultaneously, all serialized via Echo’s writer mutex. Zero loss; throughput floor met.

The integration test (TestEchoFanIn_AllEventsLand) runs in under 21 seconds on a CI runner. The hardware run on the populated DB is reproducible from the artifacts attached to this post.

The hardware run

We provisioned an A100 (40GB SXM4) on Lambda us-east-1 and an H100 (80GB SXM5) on Lambda us-south-3 to play the role of two GPU nodes. Echo ran on the A100. A simple OTLP/gRPC stress client (cmd/echo-stress/) pushed 1,000 events from each node into Echo. Cross-region OTLP from H100 to A100 was blocked by Lambda’s default firewall, so the H100 stream was simulated from the A100 host with --node-id=node-h100. Echo’s fan-in path treats both streams identically; the test exercises the same RPC handler, the same writer mutex, and the same DuckDB schema. The DB attached to this post (echo-fanin-demo.db, 1.0 MiB) is the result.

The exact commands are in commands.md next to this post. The runbook starts Echo with a bearer token, runs two echo-stress invocations with different node IDs, and validates with three DuckDB queries.

The queries that matter

These are the SQL queries that produced the assertions above. All four run against the attached DB.

Per-node event count.

SELECT cluster_id, node_id, COUNT(*) AS events
FROM events
GROUP BY cluster_id, node_id
ORDER BY node_id;

Enter fullscreen mode Exit fullscreen mode

demo-cluster | node-a100 | 1000
demo-cluster | node-h100 | 1000

Enter fullscreen mode Exit fullscreen mode

Causal chains preserved.

SELECT COUNT(DISTINCT json_extract_string(attrs_json, '$.causal_chain_id')) AS chains
FROM events
WHERE attrs_json LIKE '%causal_chain_id%';

Enter fullscreen mode Exit fullscreen mode

80

Enter fullscreen mode Exit fullscreen mode

Stragglers per node.

SELECT node_id, COUNT(*) AS straggler_events
FROM events
WHERE value_double < 0.40
GROUP BY node_id;

Enter fullscreen mode Exit fullscreen mode

node-a100 | 9
node-h100 | 9

Enter fullscreen mode Exit fullscreen mode

Median and p95 health by node.

SELECT node_id,
       quantile_cont(value_double, 0.5)  AS median_health,
       quantile_cont(value_double, 0.95) AS p95_health
FROM events
GROUP BY node_id;

Enter fullscreen mode Exit fullscreen mode

The same shape of query is what an agent calls through the MCP run_analysis tool. The lexical SQL gate (sqlguard) rejects any query that touches the filesystem (read_csv, read_parquet, the READ_* family, the SNIFF_* family, bare-quoted FROM table sources, the httpfs/s3/gcs schemes) and any query that introspects DuckDB’s own catalog (duckdb_settings, duckdb_tables, the duckdb_* family). The guard runs once at the MCP boundary and once again inside the store, so the gate cannot drift between layers.

What this changes for AI agents

The MCP server is the part that matters for agents. An agent investigating “throughput dropped at 14:32 UTC, every rank reports healthy, why” can now ask Echo directly:

fleet.cluster.find_outlier_nodes(window="14:30-14:35", metric="ingero.health.score", threshold=0.4)

Enter fullscreen mode Exit fullscreen mode

and receive back the ranked node list. It can then ask:

fleet.cluster.event_history(cluster_id="...", node_id="<outlier>", window="14:30-14:35", limit=1000)

Enter fullscreen mode Exit fullscreen mode

to pull the call stack. It can finally call:

fleet.cluster.run_analysis(sql="SELECT ... causal_chain_id ... GROUP BY node_id ...")

Enter fullscreen mode Exit fullscreen mode

to pivot the data into the shape that answers the question. The agent never sees the populated DB directly. It sees four tools, each returning JSON-shaped responses bounded by the lexical guard.

This is the gap that per-host MCP servers cannot close. A per-host MCP server can answer “what did the agent do on this host?” but it cannot answer “what was the cluster doing when the agent observed the spike?” Cross-rank causal questions need a cross-rank AI-investigation surface. Echo is that surface.

Try it locally

Two paths, depending on whether you want to run the demo end-to-end or just inspect the recorded output.

Reproduce the fan-in scenario from scratch. The integration test in cmd/ingero-echo/integration_test.go spins up Echo backed by a fresh DuckDB in a per-test temp directory, fans in 8 concurrent agents pushing 250 events each (2,000 events total), and asserts that all events landed, the planted outlier surfaces in the MCP query, and causal-chain events are preserved with all attributes. Each invocation produces its own DB.

git clone https://github.com/ingero-io/ingero-fleet.git
cd ingero-fleet/cmd/ingero-echo
go test -run TestEchoFanIn_AllEventsLand ./...

Enter fullscreen mode Exit fullscreen mode

The test takes under 10 seconds on a developer laptop. Requirement: a Go toolchain plus DuckDB’s CGO build dependencies (libstdc++).

To inspect the populated DB after the test runs, set ECHO_BLOG_ARTIFACT=1 in the environment and the test will copy the final DB to /tmp/echo-fanin-demo.db. Then:

ECHO_BLOG_ARTIFACT=1 go test -run TestEchoFanIn_AllEventsLand ./...
duckdb /tmp/echo-fanin-demo.db

Enter fullscreen mode Exit fullscreen mode

Run any of the queries from “The queries that matter” section above against this freshly captured DB; the schema is identical, only the random event IDs differ.

Inspect the published demo DB without running anything. The same DB referenced earlier in this post is published in the public Fleet repo. 2,000 events, 2 clusters, 80 causal chains preserved across the wire, 18 stragglers detected end-to-end.

curl -fsSL -o echo-fanin-demo.db \
  https://github.com/ingero-io/ingero-fleet/raw/main/investigations/echo-fanin-demo.db

duckdb echo-fanin-demo.db

Enter fullscreen mode Exit fullscreen mode

Open it and run the same queries from “The queries that matter” section above. The Echo schema is documented in cmd/ingero-echo/store/schema.go: one row per OTLP data point, dedicated columns for cluster_id / node_id / metric_name / rank / nranks / value_double / value_int, and an attrs VARCHAR holding the rest as JSON. Two indexes target the most-used filters ((cluster_id, timestamp_ns) and (node_id, timestamp_ns)).

The two paths are independent: the test reproduction does not read the published DB, and the published DB does not require the test to be run. Both demonstrate the same Echo store schema, so a query that works on one works on the other.

For the hardware-shaped run (two real hosts, OTLP over the wire), the runbook in commands.md next to this post’s draft is the script. Total wall time is under five minutes; total cost on Lambda was about $0.50 for the A100 alone.

Across hosts, not on hosts

A per-host trace can be perfectly correct and still useless. The pattern across hosts is what carries the cause. Eight ranks blocked inside ncclAllReduce looks identical to eight ranks running healthy work; the only thing that distinguishes the two is whether one rank entered late. That fact lives in a join, not in a single host’s events.

Echo’s job is to be the AI-investigation surface where the join can run, with the same OTLP semantic conventions on the wire, the same DuckDB schema underneath, and the same MCP shape that agents are already learning to use. The fan-in correctness proof is the gate before the rest of the work depends on the store. With v0.12.5 it is shipped, tested, and reproducible.


Ingero – open-source eBPF agent for GPU debugging. One binary, zero deps, <2% overhead. Apache 2.0 + GPL-2.0. *GitHub ⭐** · Open an issue if you are running distributed training or inference and seeing throughput drop while every rank reads healthy.

Investigation DB: investigations/echo-fanin-demo.db*

Related reading