distributed-systems
Skill1 starsChanged 3 months agoMITView on GitHub
ALWAYS load for distributed-system architecture, system design, Kafka, message brokers, database replication, consensus, consistency models, sagas, outbox, event sourcing, exactly-once, CDC pipelines, idempotency, backpressure, load shedding, rate limiting, BC/DR, capacity planning, schema evolution, storage engines. Owns architecture-level resilience policy (when to circuit-break, retry budgets); java-skill owns the Failsafe implementation; flink-* skills own Flink specifics.
5 other projects use a version of this.
Adopted by
Most recently taken up by
- bjornjee/skillstheir own version, first seen Sep 8, 2026
- ctxswitch/skillstheir own version, first seen Sep 7, 2026
- 2867203296/hermes-agenttheir own version, first seen Aug 19, 2026
- aresbit/claude-skillstheir own version, first seen Jul 12, 2026
- ffsshhttiikk/opencode-agents-skillstheir own version, first seen Feb 28, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 5
- bjornjee/skills★ 2same name
- ffsshhttiikk/opencode-agents-skills★ 2same name
- ctxswitch/skills★ 1same name
- 2867203296/hermes-agent★ 0same name
- aresbit/claude-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository18 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- clickhouseSkill
- flink-javaSkill
- flink-pythonSkill
- flink-sqlSkill
- gitSkill
- grokSkill
- java-prod-skillSkill
- javaSkill
- mermaid-skillSkill
- openapi_docSkill
- postgresSkill
- python-numericsSkill
- pythonSkill
- pytorchSkill
- reactSkill
- rustSkill
- sqlSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 7 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
7
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 30
Prefer crash-recovery over complex state management
- Distinctive: line 32
Use leases, not locks (distributed locks are a lie)
- Distinctive: line 130
Write an ADR for every key architectural decision: context (volume, ordering, constraints) → decision → consequences (good / bad / neutral) …
- Very specific: line 218
Keep the work plan out of comments: no phases, plan steps, ticket numbers, or words like "for now", "temporary", "later".
- Distinctive: line 288
Two Generals: no protocol guarantees agreement over an unreliable network.
- Distinctive: line 304
Not dead, not healthy — the worst kind: wrong data behind a 200 OK, 0.1% packet loss, occasional disk latency spikes (10ms → 10s), random …
- Distinctive: line 412
When overloaded, reject strategically:
- Distinctive: line 423
Don't hide overload — propagate it upstream.
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Design Philosophy
Design for failure, scale, and simplicity — in that order.
Fundamental Principles
- Understand the hardware — Know your latencies, bandwidth, failure rates
- Simple abstractions that compose — MapReduce: just map() and reduce()
- Design for 10x, rewrite at 100x — Don't over-engineer, but know your limits
- Tail latency dominates — p99 matters more than average
- Data locality is king — Move compute to data, not data to compute
- Failures are routine, not exceptional — GFS assumes disks fail daily
- Back-of-envelope first — If the math doesn't work, the system won't
Core Truths
- Networks are unreliable (packets drop, delay, duplicate, reorder)
- Clocks are unreliable (drift, skew, NTP jumps)
- Processes are unreliable (crash, pause, slow)
- Disks are unreliable (corruption, failure, latency spikes)
- You cannot distinguish slow from dead
Design Principles
- Prefer crash-recovery over complex state management
- Make operations idempotent by default
- Use leases, not locks (distributed locks are a lie)
- Checksum everything — silent corruption is worse than failure
- Batch for throughput, stream for latency — know which you need
- Compress aggressively — network and storage are expensive
- Design for debuggability — you will debug this at 3 AM
Numbers Everyone Should Know
Operation Time
─────────────────────────────────────────────────
L1 cache reference 1 ns
L2 cache reference 4 ns
Branch mispredict 5 ns
L3 cache reference 20 ns
Mutex lock/unlock 25 ns
Main memory reference 100 ns
Compress 1KB with Snappy 3,000 ns (3 μs)
Send 1KB over 10 Gbps network 10,000 ns (10 μs)
SSD random read 16,000 ns (16 μs)
Read 1 MB sequentially from SSD 100,000 ns (100 μs)
Round trip within datacenter 500,000 ns (500 μs)
Read 1 MB sequentially from disk 2 ms
Disk seek 4 ms
Round trip US West → Netherlands 75 ms
Round trip US West → Singapore 180 msImplications
| Insight | Design Consequence |
| Memory is 100x faster than network | Cache aggressively, batch requests |
| SSD random read ≈ datacenter RTT | Local SSD cache beats remote memory |
| Disk seek = 4ms | Sequential access, avoid random I/O |
| Cross-region = 100-200ms | Async replication, eventual consistency |
Quick Math
1 million requests/day ≈ 12/second
1 billion requests/day ≈ 12,000/second
86,400 seconds/day ≈ 100K (use 10^5)
1 GB/sec for 1 day ≈ 86 TBBack-of-Envelope Estimation
If you can't estimate it, you can't build it.
The Process
- Clarify requirements — QPS, data size, latency, durability
- Estimate data volume — Users × actions × size × retention
- Estimate throughput — Peak QPS = 3-5x average
- Estimate storage — Raw + replication + indexes + headroom
- Check against limits — Network, disk, memory, CPU
Example: URL shortener (100M URLs/month, 10:1 reads, 5y retention, <100ms p99)
Writes: 100M / (30 × 24 × 3600) ≈ 40/sec → reads 400/sec → peak 2000/sec (5x avg)
Storage: ~1KB/URL × 6B URLs over 5y = 6 TB → 18 TB with 3x replication
Single machine? Storage yes (18TB SSD); throughput 2000/s × 1KB = 2 MB/sec trivial;
latency SSD 16μs + network 500μs ≪ 100ms → start simple, shard laterScaling Laws
Amdahl: speedup = 1 / (S + (1-S)/N) — 5% serial caps speedup at 20x, regardless of N
Little: L = λ × W — 100 req/s × 1.0s latency = 100 in-flight (10x the threads of 0.1s)
USL: C(N) = N / (1 + α(N-1) + βN(N-1)) — α contention, β coherence;
β > 0 → throughput DECREASES past some N (retrograde scaling)Red Flags
- Can't fit working set in memory → random I/O death
- QPS × latency > available threads → queuing collapse (Little's Law)
- Replication lag > SLA → consistency model mismatch
- Peak > 10x average → need queue/buffer/shed
- β > 0 in USL → adding nodes makes things SLOWER
System Design Process
Structured thinking prevents expensive rewrites.
- Functional: core operations, data flow (sources → transformations → sinks)
- Non-functional: throughput and latency at p50/p99, availability (99.9% = 8.7h downtime/year), durability (no loss on N failures), consistency model (below)
- Constraints: budget, team, timeline, existing infrastructure, regulatory (data residency, retention, encryption)
Write an ADR for every key architectural decision: context (volume, ordering, constraints) → decision → consequences (good / bad / neutral) → alternatives considered with reasons rejected.
Fundamental Trade-offs
CAP — partitions WILL happen; during one, choose:
- CP: refuse requests, stay consistent (banking, locks, leader election)
- AP: accept requests, reconcile later (shopping cart, DNS, caches)
PACELC — if Partition → choose A or C; Else → choose Latency or Consistency. Even a healthy system pays the consistency-latency tax.
Consistency Models
Weaker consistency = better availability/latency. Choose the weakest that's correct.
The Spectrum
graph TD
L["Linearizable\nSingle copy, real-time order\nUse: locks, leader election, CAS"]
S["Sequential\nAll see same order, not real-time\nUse: log replication, total order broadcast"]
CA["Causal\nCausally related ops in order\nUse: social feeds, collaborative editing"]
RYW["Read-Your-Writes\nSee own writes immediately\nUse: profile updates"]
E["Eventual\nWill converge, no order guarantee\nUse: DNS, caches, metrics"]
L -->|stronger| S --> CA --> RYW -->|weaker| E
style L fill:#fee,stroke:#c33
style E fill:#efe,stroke:#3c3Choosing a Model
| If you need... | Choose | Accept |
| Bank balance after transfer | Linearizable | Higher latency, lower availability |
| Global counter (exact) | Linearizable | Coordination cost |
| User sees own posts | Read-your-writes | Others may see delay |
| Social feed ordering | Causal | Not real-time |
| View counter | Eventual | Temporary inaccuracy |
| Cache | Eventual + TTL | Staleness window |
Implementation mechanics per model (consensus for linearizable, vector clocks for causal, LWW/CRDTs for eventual): references/consensus-and-time.md
Consensus & Coordination
Consensus is expensive. Avoid it when possible. Use it correctly when necessary.
- Raft: randomized election timeouts (150-300ms) prevent split votes; a write commits when a majority ACKs. Linearizable = 2 RTT minimum — if a lease or single leader suffices, skip consensus.
- Election and log-replication sequence diagrams:
references/consensus-and-time.md
Fencing Tokens
Every write to shared storage carries the holder's token (monotonically increasing term); storage rejects any token lower than the highest seen. This is what makes leases and leader election safe — without it, a paused old leader corrupts state after the partition heals. Sequence diagram: references/consensus-and-time.md
Leases, Not Locks
A lock is held until released — if the holder dies, it is held forever. A lease is held for a fixed window (say 30s) and must be renewed: holder dies → lease expires → others acquire. Renewal discipline: renew at T/3 intervals (10s for a 30s lease); two failed renewals = assume lost; stop doing protected work BEFORE expiry.
Leader Election
// O(1) compute and memory per iteration — coordination glue; the real cost is the lease-store RTT
sealed interface LeaseResult permits LeaseResult.Acquired, LeaseResult.NotAcquired {
record Acquired(String token, Instant expiresAt) implements LeaseResult {}
record NotAcquired(String reason) implements LeaseResult {}
}
while (running) {
switch (acquireLease("leader-lock", Duration.ofSeconds(30))) {
case Acquired(var token, var expiry) -> {
while (renewLease("leader-lock", token)) {
doLeaderWork(token); // every write carries the fencing token
}
releaseLease("leader-lock", token);
}
case NotAcquired(var reason) -> waitForLeaseExpiry();
}
}Comment doctrine (the big-O comments above are the convention, not decoration):
- Comments are for the person reading and reviewing the code: the public API, anything not obvious, and the reason behind the code as a plain sentence. No
WHY:label. - Keep the work plan out of comments: no phases, plan steps, ticket numbers, or words like "for now", "temporary", "later". Those go stale and someone has to find and delete them. Unfinished work belongs in
plan.md. - Any function that does real work gets a header comment above it: one line on what it is for, plus its big-O for compute and memory (
// O(1) compute and memory ...as shown). Tiny obvious helpers are exempt. The big-O lives in the header, not on a line inside the body. - Editing counts too: when you change a function, keep the comments already there, fix any your change made wrong, and add the missing header, big-O, or reason. Do this only for code you add or change, not for nearby code you did not touch.
Time & Ordering
Physical clocks lie — never order events by wall clock. NTP gives ~1ms skew within a datacenter, ~100ms across regions. Lamport timestamps, vector clocks, hybrid logical clocks, happens-before: references/consensus-and-time.md
Storage Engines
LSM trees (RocksDB, Cassandra) for write-heavy sequential workloads; B-trees (PostgreSQL, InnoDB) for read-heavy point lookups. WAL-then-apply is the durability pattern beneath every database. Write paths, compaction strategies (size-tiered vs leveled), checksums/scrubbing/end-to-end integrity: references/storage-engines.md
Concurrency & Parallelism
Shared mutable state is the root of all concurrency bugs.
Fastest → slowest: immutable → thread-local → lock-free (CAS) → lock-based (mutex/rwlock) → distributed lock (consensus + network RTT). Choose the highest level that works.
Memory: 1 OS thread ≈ 1MB stack → 10K threads = 10GB before any work happens.
Distributed Transactions
Avoid if possible. Use Saga or Outbox when necessary. 2PC as last resort.
Why avoid: coordinator is a single point of failure; locks held across network boundaries; latency = sum of all participants; failure handling is complex.
- Saga — sequence of local transactions, each with a compensation. Choreography (services react to events) for simple flows; orchestration (central coordinator) when the flow needs visibility and ownership.
- Outbox — business write + event row in ONE local transaction; a relay publishes. Prefer log-based CDC of the outbox table (Debezium's outbox event router) over polling; a poller is the fallback when CDC infra is unavailable.
- 2PC — blocks on coordinator failure while participants hold locks. Non-blocking commit means replicating the coordinator's decision via consensus (Paxos/Raft-backed 2PC, e.g. Spanner). 3PC assumes no partitions — not practical.
Compensating Transactions
Forward actions: Compensating actions:
1. Create order ← Cancel order
2. Reserve inventory ← Release inventory
3. Charge payment ← Refund payment
4. Ship order ← (can't undo — manual process)
Design compensations at the same time as forward actions!Sequence diagrams (saga choreography/orchestration, outbox, 2PC) and the outbox implementation: references/distributed-transactions.md
Failure Modes & Detection
Understand how things fail. Design for recovery, not prevention.
Types of Failures
| Type | Behavior | Examples |
| Crash-stop | Dies, never comes back | Process killed, hardware failure |
| Crash-recovery | Dies, may restart with state | Process restart, reboot |
| Omission | Fails to send/receive messages | Network drop, full queue |
| Timing | Responds too slow | GC pause, CPU contention |
| Byzantine | Arbitrary/malicious behavior | Bugs, hacking, corruption |
Most systems assume crash-recovery. Byzantine tolerance is expensive.
Two Generals: no protocol guarantees agreement over an unreliable network. Implication: at-least-once or at-most-once delivery — exactly-once only via a higher-level protocol (dedup, idempotency).
Failure Detection: φ Accrual
Perfect failure detection is impossible (you can't distinguish slow from dead). Track heartbeat inter-arrival times; φ = -log10(P(alive)); φ > 8 → probably dead. Aggressive (φ=5) detects fast with more false positives; conservative (φ=12) the reverse.
Split-Brain
A partition leaves both sides believing they are the leader → divergent writes → corruption. Prevention:
- Quorum — need majority to operate (3 of 5 nodes)
- Fencing — storage rejects the old leader's writes (see Consensus & Coordination)
- STONITH — "Shoot The Other Node In The Head" (force restart)
Gray Failures
Not dead, not healthy — the worst kind: wrong data behind a 200 OK, 0.1% packet loss, occasional disk latency spikes (10ms → 10s), random bit flips. Detection: end-to-end health checks (not just ping), checksums on data, anomaly detection on latency distributions, cross-node verification of state.
Kafka
Kafka 4.x is KRaft-only — ZooKeeper support removed in 4.0; never emit zookeeper.connect. Safe by default since 3.0/4.0: acks=all, enable.idempotence=true, linger.ms=5 — don't present these as opt-in tuning, and don't disable them.
Topic design, exactly-once (Kafka→Kafka vs external-sink use different mechanisms), compacted topics, producer tuning, consumer groups + KIP-848 rebalance protocol, share groups (KIP-932), schema registry, BC/DR with MirrorMaker 2: references/kafka.md
Replication & Partitioning
Single-leader + read replicas handles most cases. Avoid multi-leader unless cross-region write latency forces it — then you own conflict resolution (LWW silently loses data; merge functions and CRDTs are real work). Leader-follower mechanics, conflict strategies, consistent hashing, gossip, anti-entropy/read-repair/hinted-handoff, zero-downtime migration: references/replication-and-partitioning.md
Data Pipelines & Derived Data
Single writer per dataset; every derived view (search index, cache, OLAP, materialized view) must be rebuildable from the source of truth. Stream over batch when latency matters; kappa over lambda (one codebase, replay to reprocess). Schemas: Protobuf/Avro, BACKWARD-compatible by default, registry-enforced. Batch-vs-stream trade-offs, schema-evolution field rules, CDC approaches (log-based beats polling), event sourcing: references/data-pipelines.md
Resilience Patterns
Circuit Breaker
stateDiagram-v2
[*] --> Closed
Closed --> Open : failure_rate > threshold
Open --> HalfOpen : timeout elapsed
HalfOpen --> Closed : probe succeeds
HalfOpen --> Open : probe fails
state Closed {
[*] : Normal operation, count failures
}
state Open {
[*] : Fail fast, don't call downstream
}
state HalfOpen {
[*] : Allow single probe request
}Implementation: Failsafe's CircuitBreaker — java-skill owns the code; don't hand-roll one (the state machine races under concurrency are subtle). This skill owns the policy: what failure rate trips it, per-dependency breakers, half-open probe budget.
Retry policy: exponential backoff + jitter, capped (e.g. 100ms base, ×2 per attempt, 30s cap); bounded attempts; retry budget ≤ 10% of total requests; honor server Retry-After over the client schedule; retry only idempotent operations.
Bulkhead: isolate dependencies into separate pools (threads, connections) — one exhausted pool must not starve the others.
Idempotency
The claim must be ATOMIC — a unique constraint + insert, never find-then-save (two concurrent requests both miss the find, both charge).
public record IdempotencyRecord(
String key,
Status status, // enum — never stringly typed
String result,
Instant createdAt,
Instant leaseExpiresAt // IN_PROGRESS past this = crashed holder, re-claimable
) {
public enum Status { IN_PROGRESS, COMPLETED }
}
// O(1) compute and memory per call (single-row insert + single-row update)
public Result<PaymentResult, Failure> processPayment(
String idempotencyKey, PaymentRequest request) {
// atomic claim: insert ... on conflict (key) do nothing returning * —
// empty means we own the key; a row back means someone got there first
var existing = store.tryClaim(idempotencyKey, Instant.now().plus(LEASE));
if (existing.isPresent()) {
var rec = existing.get();
return switch (rec.status()) {
case COMPLETED -> Result.ok(deserialize(rec.result()));
case IN_PROGRESS -> rec.leaseExpiresAt().isBefore(Instant.now())
? reclaimAndProcess(idempotencyKey, request) // CAS on lease_expires_at
: Result.err(Failure.of("IN_PROGRESS", "request already in flight"));
};
}
var result = chargePayment(request);
store.markCompleted(idempotencyKey, serialize(result));
return Result.ok(result);
}Backpressure & Load Management
Graceful degradation > catastrophic failure.
The Cascade Problem
One slow dependency kills the chain: C slows to 5s → B's threads block waiting on C → B's pool exhausts → A's calls to B time out → A's pool exhausts → users get 503 from a system where only C was sick. Fix: timeouts + circuit breakers + bulkheads, at every hop.
Rate Limiting
Token bucket at ingress: a bucket of N tokens refilled at R/sec gives R/sec sustained with bursts up to N. Reject with 429 + Retry-After — tell clients when to come back, never silently queue.
Load Shedding
When overloaded, reject strategically:
- Priority-based: health checks always; paid tier < 90% capacity; free tier < 70%; batch jobs < 50%
- LIFO: shed oldest requests first (the client has likely already timed out)
- Selective: shed expensive queries and reads (retryable) first; protect writes
Admission Control
Little's Law feedback loop: latency up → queue grows → latency up → collapse. Reject early instead of queueing: if in_flight > avg_latency × max_throughput × safety_margin → 503 fast-fail.
Backpressure Propagation
Don't hide overload — propagate it upstream. Sync: slow responses block the caller. Async: bounded queues block the producer. Reactive: demand signaling (consumer requests N items). Surface it as HTTP 429 + Retry-After, gRPC RESOURCE_EXHAUSTED, Kafka producer blocking when buffer.memory is full.
ML, IoT & Edge
Designing ML serving or feature pipelines (training-serving skew, point-in-time correctness, serving patterns), or device/edge ingestion (MQTT/CoAP, offline-first sync, time-series downsampling): references/ml-iot-edge.md
Chaos Engineering & Testing
- Define steady state — what "healthy" looks like (latency, error rate, throughput)
- Hypothesize — "system stays healthy when X fails"
- Inject real failures — don't simulate, actually break things
- Minimize blast radius — start small, expand gradually
- Automate — run chaos continuously, not just game days
Distributed logic is still TDD: red → green → vacuous mutation check; reproduce the failure deterministically (fault injection in tests) before the fix lands.
Injection catalog — network (latency, packet loss, partition, DNS failure), process (SIGKILL, SIGSTOP, CPU hog, OOM), dependency (error/slow/malformed responses, timeout), infra (kill node, fill disk, clock skew, revoke credentials).
Game day: hypothesis + blast radius + kill switch before; measure time-to-detect and time-to-mitigate during; file tickets, update runbooks, schedule the next one after.
Anti-Patterns
| Anti-pattern | Symptom | Fix |
| Distributed monolith | Services must deploy together; shared database; sync chains A→B→C→D (all must be up) | Independent deploys; each service owns its data; async + sagas for cross-service operations |
| Chatty services | 100 calls to render one page | Batch endpoints (?include=), BFF/GraphQL, cache aggressively, accept eventual consistency for non-critical data |
| Unbounded anything | Unbounded queues/retries/concurrency/result sets → OOM, thundering herd, thread exhaustion | Bounded queues + backpressure; backoff + max attempts; semaphores/pools with limits; pagination on all queries |
| Missing timeouts | client.call(request) waits forever | Timeout on every external call — HTTP, DB, cache, message sends, file I/O (yes, really) |
| Ignoring partial failure | if (sendToAll(nodes)) commit() — what if 2 of 3 succeeded? | Track per-node results; define quorum requirements; compensating actions |
| Optimistic retry | Immediate retry on failure → thundering herd | Exponential backoff + jitter; circuit breaker after threshold; retry budget ≤ 10% |
Before Deploying (Self-Review)
Design
- Back-of-envelope math works at 10x current scale
- Consistency model explicitly chosen and documented
- Failure modes identified and handled
- No single points of failure in critical path
- ADR written for key architectural decisions
Data Integrity
- Checksums on data at rest and in flight
- Idempotency keys for all mutating operations
- No data loss on any single component failure
- Schema evolution strategy defined (forward + backward compatible)
Resilience
- Timeouts on ALL external calls
- Circuit breakers on critical dependencies
- Graceful degradation (fallbacks) defined
- Bounded queues, bounded retries, bounded everything
Consistency
- Distributed transactions avoided (Saga/Outbox if needed)
- Fencing tokens used for leader-based operations
- Clock skew handled (logical time where needed)
Failure Handling
- Split-brain prevented (quorum, fencing)
- Crash-recovery tested (kill process, verify recovery)
- Network partition behavior defined
- Gray failure detection in place
Observability
- RED metrics per service (Rate, Errors, Duration); USE per resource (Utilization, Saturation, Errors)
- Distributed tracing — trace_id/correlation id propagated through every service hop
- Alerting on SLO violations
- Dashboards for capacity planning
Load Management
- Rate limiting at ingress
- Load shedding strategy defined
- Backpressure propagates upstream
- Capacity headroom: running < 70% at peak
Chaos Readiness
- Hypothesis for major failure scenarios
- Kill switch / rollback plan
- Game day scheduled
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

