event-driven-architecture
Skill8 starsChanged 9 days agoMITView on GitHub
Designs reliable event-driven systems - events vs commands, event styles, schema evolution, ordering and partition keys, at-least-once delivery with idempotent consumers, transactional outbox, retries and dead-letter queues, replay, lag monitoring, choreography vs orchestration. Use when adding a message broker or queue, publishing or consuming events (Kafka, RabbitMQ, SQS, Pub/Sub, Service Bus), messages are duplicated, lost or out of order, or a consumer is stuck on a poison message. Not for in-process event emitters.
13 other projects use a version of this.
Adopted by
Most recently taken up by
- delorenj/skillstheir own version, first seen Nov 7, 2026
- jars-demo/jars-skillstheir own version, first seen Oct 25, 2026
- troskater/flowdeck-claudetheir own version, first seen Oct 25, 2026
- nimadorostkar/Claude-Skills-collectiontheir own version, first seen Oct 13, 2026
- kimtth/agent-skill-100-lines-or-lesstheir own version, first seen Jun 26, 2026
- agent-packs/registrytheir own version, first seen Jun 15, 2026
Other versions13 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 13
- travisjneuman/.claude★ 106same name
- nimadorostkar/Claude-Skills-collection★ 33same name
- delorenj/skills★ 17same name
- rade-nugroho/Agentic-Enteprises-Skill★ 9same name
- daemon-blockint-tech/Agentic-Enteprises-Skill★ 8same name
- ffsshhttiikk/opencode-agents-skills★ 2same name
- kimtth/agent-skill-100-lines-or-less★ 2same name
- codecharmhq/claude-code-skills★ 1same name
- mmondora/claude-skills★ 1same name
- agent-packs/registry★ 0same name
3 more not listed
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 repository60 other files it gives its agents.
- api-designSkill
- auth-implementationSkill
- background-jobsSkill
- building-agentsSkill
- caching-strategiesSkill
- ci-cd-pipelinesSkill
- cloud-cost-optimizationSkill
- codebase-onboardingSkill
- code-review-changesSkill
- concurrency-patternsSkill
- database-migrationsSkill
- database-schema-designSkill
- database-testingSkill
- data-pipelinesSkill
- data-privacy-retentionSkill
- dependency-upgradesSkill
- design-docsSkill
- design-systemsSkill
- dockerfilesSkill
- domain-driven-designSkill
- file-storage-uploadsSkill
- frontend-securitySkill
- git-workflowSkill
- graphql-apisSkill
- grpc-servicesSkill
- incident-responseSkill
- infrastructure-as-codeSkill
- internationalizationSkill
- kubernetes-deploymentsSkill
- large-scale-migrationsSkill
- legacy-refactoringSkill
- llm-evalsSkill
- llm-integrationSkill
- mcp-serversSkill
- micro-frontendsSkill
- ml-experimentsSkill
- monorepo-managementSkill
- nosql-designSkill
- observabilitySkill
- orm-patternsSkill
- performance-profilingSkill
- postgres-operationsSkill
- rag-systemsSkill
- react-patternsSkill
- realtime-apisSkill
- resilience-patternsSkill
- root-cause-debuggingSkill
- search-integrationSkill
- security-auditSkill
- seo-and-ssrSkill
- sql-optimizationSkill
- system-designSkill
- test-strategySkill
- threat-modelingSkill
- typescript-patternsSkill
- unit-testingSkill
- verify-before-doneSkill
- web-accessibilitySkill
- web-performanceSkill
- writing-skillsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
14 rules. 0 are common, 13 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 13 edited versions we read keep these.
13
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 18
Not for: in-process observers or UI event handlers.
- Very specific: line 28
Don't disguise commands as events (PleaseSendEmailEvent).
- Distinctive: line 38
Default: event-carried state transfer for integration events between services.
- Distinctive: line 43
Define the envelope: Every event carries: unique event ID, type, schema version, occurred-at timestamp (UTC), producer/source, the …
- Distinctive: line 44
Define the payload as a contract: Use a schema (Avro, Protobuf or JSON Schema) stored in a registry or the repo.
- Distinctive: line 49
Plan schema evolution: before the first release. Read references/schema-evolution.md.
- Distinctive: line 92
When strict order is impossible, make handlers order-tolerant with version checks.
- Distinctive: line 97
Don't retry permanent errors (validation failure, unknown schema version): send straight to the DLQ.
- Distinctive: line 98
Don't block a partition forever on one bad message: after N attempts move it to a DLQ or a delayed retry topic so later messages continue.
- Distinctive: line 99
Every DLQ has: an alert, an owner, a way to inspect messages, and a tested replay tool.
- Distinctive: line 104
Keep events long enough to rebuild consumers (topic retention, or an archive in object storage).
- Distinctive: line 134
Event chains nobody can trace: - no correlation IDs; a failed flow can't be followed across services.
- Distinctive: line 139
Every event has a named type in domain language, a versioned schema, a standard envelope and a documented ordering key.
- Distinctive: line 141
Every consumer is idempotent, and a duplicate-delivery test proves it.
“Common” is measured: kept by at least 6 in 10 of the 13 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
Event-Driven Architecture
Assume every message can arrive twice, late, or out of order, and that producers and consumers will be deployed at different times. A design is correct only if it stays correct under those conditions: idempotent consumers, explicit ordering keys, compatible schema changes, and a place for messages that can't be processed.
When to use
- Introducing a broker, queue or stream between services.
- Designing event contracts or changing an existing event schema.
- Bugs with duplicate processing, lost messages, ordering, or stuck consumers.
- Choosing between choreography (events) and orchestration (a coordinator) for a multi-step process.
Not for: in-process observers or UI event handlers. For whether to go async at all, see the system-design skill.
Messages: events, commands, queries
| Type | Meaning | Naming | Coupling |
| Event | A fact that happened; producer doesn't know who listens | Past tense: OrderPlaced | Low: any number of consumers |
| Command | A request for one specific receiver to do something | Imperative: ChargePayment | Higher: sender expects a handler |
| Query | A request for data with a response | GetOrderStatus | Usually better as a synchronous API |
Don't disguise commands as events (PleaseSendEmailEvent). If you need a specific outcome from a specific service, it's a command; send it to that service's queue.
Event styles
| Style | Payload | Use when | Watch out |
| Event notification | IDs and minimal facts | Consumers need to know something changed; they fetch details if needed | Callbacks to the producer add load and coupling |
| Event-carried state transfer | The relevant state at the time | Consumers keep their own local copy; producer must not be called back | Larger messages; consumers hold stale-but-consistent copies |
| Event sourcing | Events are the system of record; state is rebuilt from them | Strong audit/temporal needs, complex domains | High complexity: snapshots, projections, schema evolution forever. Don't adopt casually |
Default: event-carried state transfer for integration events between services.
Workflow
- Name the events in domain language (see the domain-driven-design skill). One event per meaningful business fact, not per database row change.
- Define the envelope. Every event carries: unique event ID, type, schema version, occurred-at timestamp (UTC), producer/source, the aggregate/entity ID, and correlation and causation IDs for tracing. The CloudEvents specification is a good standard envelope (required attributes:
id,source,specversion,type). - Define the payload as a contract. Use a schema (Avro, Protobuf or JSON Schema) stored in a registry or the repo. Payloads include everything consumers need without calling back, and nothing internal.
- Choose the partition/ordering key. Pick the entity whose events must be processed in order (usually the aggregate ID:
orderId). Order is guaranteed only within a partition/key, never across the whole topic. - Publish reliably with the transactional outbox (below). Never "write to the database, then publish" as two independent steps.
- Make every consumer idempotent (below).
- Design failure handling: bounded retries with backoff, then a dead-letter queue with alerting and a replay path.
- Plan schema evolution before the first release. Read references/schema-evolution.md.
- Monitor: consumer lag (messages and time), DLQ depth, processing error rate, end-to-end latency from occurred-at to processed.
Delivery semantics
- At-least-once is the realistic default. Brokers redeliver after timeouts, crashes and rebalances; producers retry after ambiguous failures. Duplicates will happen.
- At-most-once (ack before processing) loses messages on crashes. Use only for data you can afford to lose (some metrics).
- Exactly-once claims are scoped. For example, Kafka transactions can make read-process-write between Kafka topics exactly-once, but side effects outside the broker (database writes, emails, payments) still need idempotency. Treat "exactly-once" as "effectively once via idempotency".
Transactional outbox
BEGIN;
UPDATE orders SET status = 'placed' WHERE id = :id;
INSERT INTO outbox (id, aggregate_id, type, payload, created_at)
VALUES (:event_id, :id, 'OrderPlaced', :payload, now());
COMMIT;
-- A relay (polling the outbox table, or change data capture such as Debezium)
-- publishes rows to the broker and marks or deletes them.- State change and event are committed atomically; the relay may publish an event more than once, which idempotent consumers absorb.
- Publish in
created_at/sequence order per aggregate to keep ordering. - Clean up published outbox rows on a schedule.
Idempotent consumers
Pick one per consumer:
| Technique | How |
| Dedupe table | In the same transaction as the side effect, insert the event ID into processed_events with a unique constraint; on conflict, skip |
| Natural idempotency | Upserts and set-style updates (SET status = 'shipped') instead of increments |
| Version check | Apply only if event.version is greater than the stored version for that entity; ignore older or equal |
| Idempotency key at the external API | Pass the event ID as the idempotency key to payment/email providers that support it |
Ack/commit the message only after the side effect and dedupe record are committed.
Ordering
- Same key always goes to the same partition (Kafka partitions, SQS FIFO message groups, Pub/Sub ordering keys, Service Bus sessions).
- Increasing the partition count changes which partition a key maps to; ordering per key can break during the change. Plan partition counts up front.
- Concurrency inside a consumer (thread pools, async handlers) can reorder messages from one partition. Process per key sequentially if order matters.
- When strict order is impossible, make handlers order-tolerant with version checks.
Retries, poison messages and DLQs
- Retry transient errors (timeouts, 5xx, lock conflicts) a few times with exponential backoff and jitter.
- Don't retry permanent errors (validation failure, unknown schema version): send straight to the DLQ.
- Don't block a partition forever on one bad message: after N attempts move it to a DLQ or a delayed retry topic so later messages continue. (If strict per-key order matters, park the key's later messages too, or stop and alert.)
- Every DLQ has: an alert, an owner, a way to inspect messages, and a tested replay tool.
- Store the failure reason, attempt count and original topic/partition/offset with the dead-lettered message.
Replay and reprocessing
- Keep events long enough to rebuild consumers (topic retention, or an archive in object storage).
- Replays only work with idempotent consumers. Test replay in staging first.
- Kafka: reset a consumer group with
kafka-consumer-groups.sh --reset-offsets(--to-datetime,--to-earliest,--shift-by); it runs as a dry run unless--executeis given, and the group must have no active members. Resetting offsets or replaying in production reprocesses real side effects: show the dry-run result and get explicit confirmation first.
Choreography vs orchestration
| Choreography (services react to events) | Orchestration (a coordinator sends commands) |
| Few steps, loosely related reactions (send email, update search index) | Multi-step business process with ordering, timeouts and compensation (checkout, onboarding) |
| No single owner of the flow needed | One team owns the end-to-end flow and its state |
| Risk: the flow is invisible; hard to answer "where is order 123?" | Risk: the orchestrator becomes a god service |
For orchestrated multi-step flows with compensation, see the saga pattern in the resilience-patterns skill. Workflow engines (Temporal-style durable execution, cloud step-function services) are worth considering before hand-rolling saga state machines.
Broker notes (conceptual)
| Broker type | Model | Good for |
| Log / stream (Kafka, Kinesis-style, Event Hubs) | Append-only partitioned log; consumers track offsets; replayable | High throughput, many independent consumers, replay |
| Message broker (RabbitMQ, ActiveMQ) | Queues and routing (exchanges); messages removed on ack | Work queues, flexible routing, per-message acks |
| Cloud queue (SQS, Azure Service Bus, Google Pub/Sub) | Managed queue/topic; varying ordering and dedupe features | Low ops burden; check each service's ordering, dedupe window and retention limits in its docs |
Anti-patterns
- Dual write - updating the database and publishing in two steps; one will eventually fail without the other.
- Non-idempotent consumers -
balance = balance + amounton every delivery. - Global ordering assumptions - expecting topic-wide order from a partitioned system.
- Breaking schema changes - renaming or removing a field consumers read, deployed in one go.
- Leaking internals - publishing ORM entities or table rows as events; every schema change becomes a cross-team break.
- DLQ as a black hole - messages go there and nobody is alerted or owns them.
- Event chains nobody can trace - no correlation IDs; a failed flow can't be followed across services.
- Events for request/response - using two topics to fake a synchronous call; use an API.
Done when
- Every event has a named type in domain language, a versioned schema, a standard envelope and a documented ordering key.
- Producers publish through an outbox or an equivalently atomic mechanism.
- Every consumer is idempotent, and a duplicate-delivery test proves it.
- Retry policy, DLQ, alerting, owner and replay procedure exist for every consumer.
- Schema changes follow the compatibility rules and are checked in CI or by the registry.
- Lag, DLQ depth and end-to-end latency are monitored with alerts.
References
- references/schema-evolution.md - read before changing any event schema or choosing a registry compatibility mode.
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.

