The marketing team was forced to rely on massive, unsegmented batch email campaigns scheduled arbitrarily, entirely ignoring where individual users were in their lifecycle. This lack of contextual targeting meant conversion rates were dismal, and users frequently complained about receiving irrelevant messages. The delay between a user action and a relevant email was often 24 to 48 hours because lists had to be manually exported and uploaded to the provider. Furthermore, the system lacked structural safeguards against duplicate sends; when the network timed out during a batch run, the retry logic would blindly resend the entire batch, angering users. The marketing team was completely dependent on engineering to change any campaign logic, severely bottlenecking their ability to iterate.

The core of the system is a Flask-based event listener that continuously consumes user action payloads from an internal queue. This listener evaluates each event against a configurable rules table, mapping actions to specific email templates and delays, allowing marketing to update campaigns without code changes. To ensure absolute reliability, an idempotency layer was built into the database architecture; every event generates a unique key that is checked before any SendGrid API call is made. This guarantees that even if a message is processed multiple times due to a worker crash or network timeout, the external API is only ever called once.
The legacy system relied on cron jobs running massive SQL queries to find users who met certain criteria, which was slow and unscalable. The solution was to pivot entirely to an event-driven architecture. The core application now publishes granular events (e.g., 'user_signup', 'cart_abandoned') to a lightweight message queue. A dedicated Flask consumer continuously listens to this queue, instantly mapping incoming events to specific email sequences. To remove the engineering bottleneck, this mapping logic was abstracted into a configurable rules table in the database. When the consumer receives an event, it checks the table to determine the correct template and required delay, then schedules the execution. This decoupled architecture meant marketing could instantly adjust a cart abandonment delay from 60 minutes to 30 minutes without a single line of code being touched.
class TriggerEngine:
RULES = {
'user_signup': ('welcome', delay=0),
'cart_abandoned': ('recovery', delay=3600),
'order_completed': ('receipt', delay=0),
}
def handle_event(self, event: str, user_id: str):
if event not in self.RULES:
return
template, delay = self.RULES[event]
if self.in_cooldown(user_id, event):
return
self.schedule_email(
user_id=user_id,
template=template,
send_at=now() + delay
)
self.set_cooldown(user_id, event)The most damaging flaw in the previous system was its vulnerability to network timeouts. If a batch send timed out halfway through, the naive retry logic would restart the batch, spamming the first half of the list twice. To solve this definitively, a strict idempotency layer was engineered. For every triggered event, the system generates a unique, deterministic hash composed of the event type, the user ID, and the date. Before the consumer initiates a call to the SendGrid API, it attempts to insert this idempotency key into a highly optimized database table with a unique constraint. If the insert fails because the key already exists, the consumer immediately recognizes the request as a duplicate and safely discards it as a no-op. This architectural guarantee completely eliminated duplicate sends, regardless of how aggressively the queue retried failed jobs.
The transition to behavior-triggered sequences fundamentally transformed the communication strategy, completely replacing ineffective batch campaigns. Relevant, highly contextual emails now land in user inboxes within 30 seconds of their triggering action, significantly boosting engagement. By enforcing strict idempotency, user complaints regarding duplicate sends dropped to absolute zero. Furthermore, decoupling the campaign logic empowered the marketing team to iterate independently, drastically accelerating their operational velocity.
"Users get the right email at the right moment — and never twice."