Use CasesAISQLautomation

Database-Driven Email Campaigns: Trigger Messages Based on User Activity

Most email campaigns are time-based: you sign up, you get a welcome email. Seven days later, you get a follow-up. Fourteen days after that, a re-engagement n...

James Okonkwo· Developer AdvocateMarch 27, 20268 min read

Most email campaigns are time-based: you sign up, you get a welcome email. Seven days later, you get a follow-up. Fourteen days after that, a re-engagement nudge. The timing is predictable. The relevance is often low.

The better approach the one that actually drives conversions and reduces churn is sending emails based on what users are doing (or not doing) in your actual application database. A user who hasn't logged in for 12 days gets a different message than one who logged in yesterday but never completed onboarding. A customer whose usage just crossed a threshold that predicts upgrade is worth reaching out to immediately, not on a generic schedule.

This guide explains how to set up database-driven email triggers without stored procedures, custom scripts, or a data engineering team.

The Difference Between Time-Based and Behavior-Based Email

Time-based email is easy to set up. Mailchimp, ConvertKit, and every other email tool does it out of the box. You define a sequence, users enter it, messages go out on a schedule.

The limitation: time-based campaigns don't know anything about what's happening in your application. They treat a highly engaged user and a completely dormant user exactly the same if they're both on "day 7."

Behavior-based email is triggered by conditions in your database:

  • A user's last_login_at crosses 10 days ago → send a re-engagement email
  • A row appears in payments for a trial user → send an upgrade confirmation
  • A user's feature_usage_count hits 50 for the first time → send a "power user" message
  • A subscription's status changes to 'churned' → notify the customer success team
  • These triggers require watching your database not a fixed schedule. The result is messages that arrive at exactly the right moment, with context that makes them feel relevant rather than automated.

    How Database Triggers Differ from Traditional Email Automation Triggers

    Email platforms have their own concept of "triggers" a user clicks a link, opens an email, visits a page. These work off marketing data: pixels, cookies, UTM parameters.

    Database triggers work off your application data: the actual rows and columns that reflect what users have done inside your product.

    The distinction matters for several use cases:

    Scenario | Email Platform Trigger | Database Trigger

    User hasn't logged in | Not available (no pixel in app) | last_login_at < NOW() - INTERVAL 10 DAY

    Trial about to expire | Requires CRM sync | trial_ends_at BETWEEN NOW() AND NOW() + INTERVAL 2 DAY

    Dropped below usage threshold | Not available | monthly_events < 5 AND previous_month_events > 20

    Payment failed | Requires Stripe webhook config | payment_status = 'failed'

    For SaaS companies, most of the high-value triggers live in the database not in marketing pixels.

    Setting Up Database-Driven Email Triggers Without Engineering

    Traditionally, this required a data engineer or backend developer to:

  • Write a cron job or scheduled task
  • Query the database on a schedule
  • Call an email API when conditions matched
  • Handle errors, retries, deduplication
  • Maintain the script as the schema changed
  • That's significant overhead for what should be a straightforward business process: "when X happens in the database, send this email."

    AI for Database handles this with action workflows. You define the condition in plain English, connect an action (webhook, email, Slack message), and the system watches your database on a schedule.

    Here's how a churn risk workflow looks:

    Condition: "Users who had more than 10 logins last month but fewer than 3 this month"

    Action: Call webhook → POST to your email provider's API with user data

    Under the hood, the system generates and runs:

    SELECT u.id, u.email, u.name,
           COUNT(CASE WHEN s.created_at >= DATE_TRUNC('month', NOW() - INTERVAL '1 month')
                       AND s.created_at < DATE_TRUNC('month', NOW()) THEN 1 END) AS last_month_logins,
           COUNT(CASE WHEN s.created_at >= DATE_TRUNC('month', NOW()) THEN 1 END) AS this_month_logins
    FROM users u
    JOIN sessions s ON s.user_id = u.id
    GROUP BY u.id, u.email, u.name
    HAVING last_month_logins > 10 AND this_month_logins < 3;

    No stored procedure. No cron job. No backend code. The condition runs on your schedule, and when rows match, the webhook fires with the user data.

    Practical Workflow Examples

    1. Dormant User Re-engagement

    Use case: Users who haven't logged in for 10+ days but were active before.

    Database condition:

    SELECT id, email, name, last_login_at
    FROM users
    WHERE last_login_at < NOW() - INTERVAL '10 days'
      AND last_login_at > NOW() - INTERVAL '30 days'
      AND status = 'active';

    Plain English: "Active users whose last login was between 10 and 30 days ago."

    Action: POST to Mailchimp, Customer.io, or any email API with {{email}}, {{name}}, {{last_login_at}} from the matching row.

    Schedule: Run daily at 9 AM. Send each user the email only once (deduplication handled by tracking sent notifications in a table or by checking against a sent log).

    2. Trial Expiration Warning

    Use case: Trial users whose trial ends in 2 days.

    Database condition:

    SELECT id, email, name, trial_ends_at, plan_type
    FROM users
    WHERE plan_type = 'trial'
      AND trial_ends_at BETWEEN NOW() AND NOW() + INTERVAL '2 days';

    Action: Send a "Your trial ends in 2 days" email via webhook to your email provider. Pass trial end date so the email copy can reference it dynamically.

    Schedule: Run daily. Include a check in your workflow to avoid sending this to users who've already converted.

    3. Feature Adoption Follow-up

    Use case: Users who completed a specific action for the first time today (e.g., created their first dashboard).

    Database condition:

    SELECT u.id, u.email, u.name, MIN(d.created_at) AS first_dashboard_created
    FROM users u
    JOIN dashboards d ON d.user_id = u.id
    GROUP BY u.id, u.email, u.name
    HAVING MIN(d.created_at) >= CURRENT_DATE;

    Action: Send a "Nice work here's what to do next with your dashboard" email.

    Schedule: Run every few hours during business hours.

    4. High-Value Account Alert

    Use case: Notify your sales team when a company's usage crosses a threshold that predicts upgrade.

    Database condition:

    SELECT o.id, o.name, o.owner_email, COUNT(e.id) AS events_this_month
    FROM organizations o
    JOIN events e ON e.org_id = o.id
    WHERE o.plan = 'free'
      AND e.created_at >= DATE_TRUNC('month', NOW())
    GROUP BY o.id, o.name, o.owner_email
    HAVING COUNT(e.id) > 200;

    Action: POST to a Slack webhook with company name and usage count. Or send an internal email to the sales team.

    Connecting Your Email Provider via Webhook

    Most email platforms (Mailchimp, Customer.io, ActiveCampaign, SendGrid, Postmark, Loops) expose webhook or API endpoints for triggering transactional emails.

    In AI for Database, an action workflow calls a webhook with a JSON payload built from the query results. You map database columns to the fields your email API expects:

    {
      "email": "{{email}}",
      "first_name": "{{name}}",
      "custom_fields": {
        "last_login": "{{last_login_at}}",
        "plan_type": "{{plan_type}}"
      }
    }

    Your email tool receives this, looks up the right template, and sends the message. The content, timing, and targeting are all driven by your database the email tool just handles delivery.

    Handling Deduplication

    One critical detail: your condition-based workflow will match the same users every time it runs until the condition is no longer true. You need to avoid sending the same email to the same user repeatedly.

    Common approaches:

  • Track in a notifications table: Insert a row into sent_notifications when a workflow fires. Add a check to your condition query: AND u.id NOT IN (SELECT user_id FROM sent_notifications WHERE type = 'dormant_reengagement').
  • Use a status flag: Add a column like reengagement_email_sent_at to your users table. Update it after the workflow fires. Include AND reengagement_email_sent_at IS NULL in your condition.
  • Use your email tool's deduplication: Many email APIs (Customer.io, Loops) deduplicate automatically based on email address + event type.
  • Option 3 is the simplest if your email provider supports it. Options 1 and 2 give you more control and visibility.

    What This Approach Replaces

    Setting up database-driven email workflows this way replaces several expensive or fragile alternatives:

  • Custom backend scripts: Cron jobs that break silently, live in one engineer's laptop, and are impossible for non-technical teammates to modify
  • ETL to a data warehouse + then to email tool: Adds latency (data is hours stale) and infrastructure cost
  • Zapier/Make with database steps: Works for simple cases but becomes unwieldy at scale, and the database integration options are limited
  • The AI for Database approach runs directly against your production (or read replica) database, so conditions are evaluated against current data not data from a sync that ran three hours ago.

    Making Your Email Campaigns Actually Relevant

    Time-based drip sequences have their place onboarding sequences, weekly newsletters. But for the moments that actually move the needle churn prevention, expansion revenue, re-engagement the trigger needs to come from what's happening in your data, not a calendar.

    Database-driven email campaigns close the gap between what your product knows about users and what your communication with them reflects. When the timing and conditions are right, the message lands differently.

    AI for Database makes this accessible without requiring a data engineer or backend developer for every new workflow.

    Try it free at aifordatabase.com.

    Ready to try AI for Database?

    Query your database in plain English. No SQL required. Start free today.