A rule engine and trigger framework
Match product events against versioned rules and run actions safely: rule shape, evaluation, idempotent actions, rate limits, testing and audit.
On the roadmap:Staff Engineer · step 4: Real-time at scale
Lesson 4 of 6 · 11 min read · quiz · exercise
What it is
A rule engine (or trigger framework) lets you say "when this happens and if these conditions hold, do that", without writing a new code path each time. Examples: send a welcome message when a user signs up, flag an order when the amount is unusual, award a badge after five purchases.
Product and operations teams want to change these often, so the rules should be data that a service evaluates, not code that must be redeployed.
Figure SDA-SQR-04-1 · From event to action · © forcsguy.com
What a rule contains
- Identity and version:
id,version,owner,enabled. Never edit in place; publish a new version so you can audit and roll back. - Trigger: an event type, or a schedule for time-based rules.
- Condition: a structured tree such as
all of [ plan = free, country in (IN, US), purchases >= 5 ], or a restricted expression language. Avoid arbitrary code. - Action: a named action with parameters (
send_email(template_id),add_badge(name)). - Controls: cooldown, per-user and global limits, start and end dates.
Evaluating efficiently
- Index rules by event type so an event only looks at its few candidate rules, not all rules.
- Fetch extra user data (attributes, counters) lazily and cache it for the duration of the event, as lookups usually cost more than the comparisons.
- For time-based conditions ("14 days without login") run a scheduled scan or use delayed events, rather than polling every user.
- Evaluate in workers that are partitioned by user, so state like cooldowns and counters for one user is handled in order.
Safe, idempotent actions
Events can be delivered more than once and workers retry. Guard every action with an idempotency key, for example rule:version:user:window, stored in a unique-key table or key-value store before (or together with) performing the action.
Figure SDA-SQR-04-2 · Idempotent action execution · © forcsguy.com
Operating a rule engine
- Validation at publish time: reject unknown fields, huge conditions and loops.
- Dry run and replay: run a new rule against recent historical events and report how many it would fire, before enabling it.
- Kill switch per rule and globally, since a bad rule can email a million users.
- Limits: maximum rule size, evaluation time and actions per event.
- Audit: who changed which version and when; for each event, which rules fired or were skipped and why.
- Know the cost: a large pile of rules becomes software nobody understands. Fowler's advice is to prefer plain code for logic that rarely changes, and use rules for what truly varies.
Real-world reading
Check your understanding
Question 1 of 3
0 correct so far
Why should rules be data rather than code deployed with the app?
Go deeper
- Rules engine by Martin Fowler: a balanced view on when engines help
- Drools documentation by Drools community: a mature open-source rules engine
- Enterprise Integration Patterns by Hohpe and Woolf: idempotent receiver and message router patterns
Practise it: An event storm
Everything below is already set up for this lesson: change the design, run the traffic, and see whether you meet the goal.
- 1The task
- 2Build and test
An event storm triggers many rules at once and each fires an action.
Goal: Under 1% errors, queue clears within 30 s.
Callers do not need the write applied this very second. What can hold it?
Try it yourself
Design triggers for a product: 'when a user has not logged in for 14 days, send a re-engagement email, at most once a month'. Describe rule format, evaluation, the action and the safeguards.
Click what a strong design here would need:
More in Building blocks
© 2026 forcsguy.com. Original lesson text and diagrams. Books and sites linked above belong to their authors.