api-design
This skill should be used when the user needs to "design the API", do "endpoint design", pin down a "request/response shape", choose a "pagination" strategy…
This skill should be used when the user designs a "message queue", reaches for "Kafka", "RabbitMQ", "SQS", "Kinesis", "pub/sub", or "event-driven" architecture, asks about "async processing", "background jobs", "stream processing", or wrestles with "exactly-once vs
$ npx -y skills add proyecto26/system-design-skills --skill messaging-streaming --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/messaging-streamingContext preview
The summary Claude sees to decide when to auto-load this skill.
This skill should be used when the user designs a "message queue", reaches for "Kafka", "RabbitMQ", "SQS", "Kinesis", "pub/sub", or "event-driven" architecture, asks about "async processing", "background jobs", "stream processing", or wrestles with "exactly-once vs
name: messaging-streaming description: This skill should be used when the user designs a "message queue", reaches for "Kafka", "RabbitMQ", "SQS", "Kinesis", "pub/sub", or "event-driven" architecture, asks about "async processing", "background jobs", "stream processing", or wrestles with "exactly-once vs at-least-once", "delivery guarantees", "message ordering", "duplicate handling / dedup", "dead letter queue", "backpressure", "saga orchestration", or "durable workflow". Use it whenever a slow or spiky operation should move off the request path, or two services must be decoupled, even if the user doesn't say "queue".
Move work off the synchronous request path and decouple producers from consumers, so a slow, spiky, or failure-prone operation doesn't block the caller. Getting this wrong is subtle: a queue silently changes the delivery and ordering guarantees, and under load it can absorb a spike gracefully *or* become the thing that hides a meltdown until the backlog is unrecoverable.
A step is too slow to do inline (image transcode, fan-out, third-party call); the write path is spiky and needs a buffer to smooth bursts (→ `back-of-the-envelope` for the spike factor); two services must be decoupled so one can fail or deploy independently; or many consumers need the same event stream. The async hand-off buys responsiveness, isolation, and elasticity (scale producers and consumers separately).
The caller needs the result *now* to proceed (a synchronous read, a balance check before confirming) — a queue only adds latency and a place for work to get lost. Strong read-after-write within one request. Trivial in-process work that a function call handles. Don't add a broker before a number or a coupling problem justifies it (YAGNI): it's a new stateful system to operate, monitor, and reason about under failure. "We'll need Kafka eventually" is name-dropping, not a requirement.
acceptable? This decides whether a queue belongs here at all.
or must every message be processed (at-least-once + idempotent consumers)?
user, per account)? Global ordering is expensive; per-key usually suffices.
replayable? (→ `back-of-the-envelope`.) One-shot work vs. a replayable log.
independent subscribers each reading every event?
it go, and who looks at it?
**Sync vs. async — settle this before picking a tool.** Stay synchronous when the caller needs the result to continue and the call is fast and reliable; a direct request is simpler to build, trace, and reason about. Go async when the work is slow, spiky, fan-out-heavy, or the caller can react to the result later — this trades immediate consistency and an easy stack trace for responsiveness and isolation. Only after choosing async do the options below apply. Building request/reply *over* a queue to fake a synchronous answer is a smell — a direct call is the better design.
**Queue (work/task queue)** — one logical consumer group competes to drain messages; a message is delivered to one worker and removed when acked. *Use when* there are background jobs or commands to process exactly once-ish, and workers should scale to drain a backlog.
**Pub/sub (fan-out)** — each subscriber gets its own copy of every message; producers don't know subscribers. *Use when* multiple independent consumers react to the same event (notify, index, audit) and loose coupling matters.
**Stream (durable, replayable log)** — an append-only, partitioned, retained log; consumers track their own offset and can replay history. *Use when* the design needs ordering per partition, multiple consumers at different positions, event sourcing, or reprocessing (→ `data-storage` for event sourcing/outbox).
**Durable workflow (orchestration engine)** — code that survives process crashes; the engine persists each step and resumes where it left off, with built-in retries, timers, and compensation. *Use when* a multi-step process with retries, human delays, and rollback (a saga) would otherwise become a fragile hand-rolled mesh of queues, state flags, and cron jobs.
Delivery semantics cut across all of these: **at-most-once** (fire and forget, may drop), **at-least-once** (retries until acked, may duplicate — the practical default), **exactly-once** (no loss, no dup). True end-to-end exactly-once is impractical: a broker's "EOS" (e.g. Kafka) is **intra-cluster only**, so across systems you always implement it as **at-least-once + idempotent/deduped consumers** (→ `api-design` idempotency keys). See `references/deep-dive.md` for the mechanics.
| Option | What it solves | What it worsens | Change it when | |---|---|---|---| | Queue (work queue) | Decouples + buffers; scale workers to drain backlog | At-least-once means duplicates; ordering not guaranteed across workers | Replay or many independent consumers are needed → stream/pub-sub | | Pub/sub (fan-out) | One event, N decoupled reactions; add consumers freely | No replay (transient); slow subscriber can lag or drop; fan-out amplifies load | History/replay or per-key ordering is needed → stream | | Stream (log) | Ordering per partition, replay, multi-consumer, event sourcing | Operationally heavier; partition key is a hot-shard risk; consumers must manage offsets | Simple one-shot jobs don't need a log → queue | | Durable workflow | Crash-safe long-running sagas; retries/compensation built in | New runtime + programming model; latency overhead; lo
Design scalable systems the way strong engineers actually do — by reasoning, not by memorizing diagrams.
Repo: proyecto26/system-design-skills
This skill should be used when the user needs to "design the API", do "endpoint design", pin down a "request/response shape", choose a "pagination" strategy…
This skill should be used when a system design needs a diagram — "draw the architecture", "diagram this system", "show the components", "make an…
This skill should be used when the user needs to "estimate QPS", "back-of-the-envelope" (BOTEC) numbers, "how much storage / bandwidth", "how many servers",…
This skill should be used when the user wants a "blob store" or "object storage", names "S3" or an S3-compatible store, needs to "store images / video /…
This skill should be used when the user asks about a "caching strategy", "cache invalidation", "what to cache", "read-through vs write-through vs write-back",…
This skill should be used when the user asks about the "CAP theorem", "PACELC", a "consistency model", "eventual vs strong consistency", "read-your-writes",…