skills/ipc-communication-patterns/SKILL.md
Comprehensive reference for inter-process communication mechanisms -- every way processes can talk on a computer. Covers sockets (TCP, UDP, Unix domain), WebSockets, SSE, pipes (named/anonymous), shared memory (mmap, shm_open), message queues, signals, D-Bus, XPC (macOS), gRPC, REST, stdin/stdout, file-based coordination, and clipboard. Performance benchmarks, platform availability, and code examples for each. Special focus on which IPC works best for AI agent coordination. Activate on: "IPC", "inter-process communication", "process communication", "how do I talk between processes", "Unix socket vs TCP", "shared memory", "named pipe", "WebSocket vs SSE", "gRPC vs REST", "agent coordination IPC", "XPC service", "message passing", "stdout pipe", "D-Bus", "mmap". NOT for: distributed systems design (use distributed-systems), network protocol design (use networking), message queue infrastructure like Kafka (use data-pipeline-engineer).
npx skillsauth add curiositech/windags-skills ipc-communication-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Every way processes can communicate on a computer. This skill provides decision trees for selecting IPC mechanisms, failure diagnostics, and implementation patterns for AI agent coordination.
Are processes related (parent-child)?
├── YES
│ ├── Need bidirectional?
│ │ ├── YES → Unix Domain Socket (same machine) | TCP (may cross machines)
│ │ └── NO → Anonymous Pipe (stdin/stdout)
│ └── Simple one-way → Anonymous Pipe
│
└── NO (unrelated processes)
├── Same machine only?
│ ├── YES
│ │ ├── High throughput (>1GB/s) → Shared Memory + coordination
│ │ ├── Low latency (<10us) → Unix Domain Socket
│ │ ├── Typed RPC needed → gRPC over Unix Socket
│ │ └── Simple messages → Named Pipe | Unix Domain Socket
│ │
│ └── NO (cross-machine capable)
│ ├── Web-compatible → WebSocket | SSE | REST
│ ├── Streaming data → gRPC streaming | WebSocket
│ ├── Request-reply → REST/HTTP | gRPC unary
│ └── Fire-and-forget → UDP
│
└── Browser client involved?
├── Server → Client only → SSE
├── Bidirectional → WebSocket
└── Request-reply → REST/HTTP
If latency requirement:
├── <1us → Shared Memory (lock-free ring buffer)
├── <10us → Unix Domain Socket | Shared Memory (with locks)
├── <100us → TCP loopback | gRPC
└── <1ms → REST/HTTP acceptable
If throughput requirement:
├── >10GB/s → Shared Memory only option
├── >5GB/s → Unix Domain Socket
├── >1GB/s → TCP | gRPC
└── <1GB/s → Any mechanism works
Agent Communication Pattern → Recommended IPC
Parent spawns child agents:
├── Simple task execution → stdin/stdout pipe
├── Progress reporting needed → Unix Domain Socket
└── Web UI monitoring → stdin/stdout + SSE to browser
Orchestrator + independent agents:
├── Same machine → Unix Domain Socket
├── May scale across machines → gRPC | WebSocket
└── Simple coordination → Named Pipe
Long-running agent services:
├── macOS → XPC Service
├── Linux desktop → D-Bus
└── Cross-platform → Unix Domain Socket | TCP
Detection: Process hangs when writing to stdin while child's stdout buffer is full
Symptoms: write() blocks indefinitely, process unresponsive, strace shows blocking on pipe write
Root cause: Both stdin and stdout buffers full (~64KB Linux, ~16KB macOS), neither process can proceed
Fix: Use async I/O to drain stdout while writing stdin, or separate threads for read/write operations
# Detect: strace shows blocked write to pipe
strace -p <pid> | grep -E 'write.*PIPE|read.*PIPE'
Detection: EACCES error on connect(), "Permission denied" in logs
Symptoms: Client process cannot connect to Unix domain socket, socket file exists with wrong permissions
Root cause: Socket file permissions too restrictive, or client running as different user
Fix: Set socket permissions to 0666 for multi-user access, or 0600 + proper ownership
# Fix socket permissions
chmod 666 /tmp/agent.sock
# Or set ownership
chown user:group /tmp/agent.sock
Detection: ECONNREFUSED errors, agents unable to reach orchestrator
Symptoms: Multiple agents fail simultaneously, orchestrator shows no incoming connections
Root cause: Orchestrator crashed/restarted, firewall blocking port, or port already in use
Fix: Implement exponential backoff retry, health checks, and port conflict detection
// Detect port conflicts
const server = net.createServer();
server.on('error', (err: NodeJS.ErrnoException) => {
if (err.code === 'EADDRINUSE') {
console.error(`Port ${port} already in use`);
}
});
Detection: Garbage data reads, segfaults, inconsistent state between processes Symptoms: Data races, torn reads/writes, process crashes with SIGSEGV Root cause: Missing synchronization, incorrect memory barriers, or buffer overruns Fix: Add proper atomics for flags, use futex/semaphore for critical sections
// Fix: Use atomic operations
atomic_store(&shared->flag, 1); // Not: shared->flag = 1;
Detection: SIGTERM not handled cleanly, processes leave stale state Symptoms: Lock files not cleaned up, connections not closed, zombie processes Root cause: Signal handler interrupted critical section, or handler not async-signal-safe Fix: Use self-pipe trick or signalfd (Linux) for safe signal handling
// Fix: Only set flag in signal handler, do cleanup in main loop
volatile sig_atomic_t shutdown_requested = 0;
void sigterm_handler(int sig) { shutdown_requested = 1; }
Scenario: Orchestrator manages 5 agent processes, each running different AI models. Need bidirectional communication for task assignment and progress reporting.
Decision process:
Implementation walkthrough:
// 1. Create Unix domain socket server (orchestrator)
const SOCKET_PATH = '/tmp/windags-orchestrator.sock';
if (fs.existsSync(SOCKET_PATH)) fs.unlinkSync(SOCKET_PATH); // Clean stale socket
const server = net.createServer((connection) => {
const agentId = `agent-${Date.now()}`;
agents.set(agentId, connection);
let buffer = '';
connection.on('data', (chunk) => {
buffer += chunk.toString();
// Process complete messages (newline-delimited)
let newlineIdx;
while ((newlineIdx = buffer.indexOf('\n')) !== -1) {
const line = buffer.slice(0, newlineIdx);
buffer = buffer.slice(newlineIdx + 1);
try {
const message = JSON.parse(line);
handleAgentMessage(agentId, message);
} catch (err) {
console.error(`Invalid JSON from ${agentId}:`, err);
}
}
});
connection.on('close', () => agents.delete(agentId));
});
server.listen(SOCKET_PATH);
fs.chmodSync(SOCKET_PATH, 0o600); // Owner-only access
// 2. Agent connection pattern
function connectAgent(): Promise<net.Socket> {
return new Promise((resolve, reject) => {
const socket = net.connect(SOCKET_PATH);
socket.on('connect', () => resolve(socket));
socket.on('error', reject);
});
}
// 3. Message sending with error handling
function sendMessage(socket: net.Socket, msg: object): Promise<void> {
return new Promise((resolve, reject) => {
const line = JSON.stringify(msg) + '\n';
socket.write(line, (err) => err ? reject(err) : resolve());
});
}
Expert vs novice differences:
unlink() socket path before bindingwrite() → silent failuresThis skill should NOT be used for:
distributed-systems skill insteaddata-pipeline-engineer skill insteadnetworking skill insteadapi-design skill insteadDelegate to other skills when:
websocket-streaming skilldaemon-development skillmulti-agent-coordination skillagent-interchange-formats skilldata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.