Abandoned signup recovery
Bring back users who started signup and didn't finish
A user types their email, clicks "Sign up," and... stops. Maybe they got distracted. Maybe verification email didn't arrive. They're a warm lead.
Bring them back via "abandoned signup" emails.
Track abandonment
Capture email when typed, separately from completed registration:
// On email blur, before they click submit:
fetch("/api/track-email", {
method: "POST",
body: JSON.stringify({ email, started_at: new Date().toISOString(), source: "registration" }),
});Store:
CREATE TABLE signup_attempts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL,
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
completed_at TIMESTAMPTZ,
source TEXT
);On successful registration: mark completed.
// In post-registration hook
await db`UPDATE signup_attempts SET completed_at = NOW() WHERE email = ${identity.traits.email} AND completed_at IS NULL`;Reminder emails
Cron, every hour:
SELECT email FROM signup_attempts
WHERE completed_at IS NULL
AND started_at < NOW() - INTERVAL '1 hour'
AND reminder_1_sent_at IS NULL
LIMIT 100;Send "Finish signing up?" email:
Subject: Finish creating your account
Hi,
You started signing up for [Your App] but didn't finish.
Click below to pick up where you left off:
https://your-app.com/register?email={{ email }}
Need help? Reply to this email.The URL pre-fills the email when they return.
Update:
UPDATE signup_attempts SET reminder_1_sent_at = NOW() WHERE email = ...;Reminder cadence
Multiple reminders, decreasing eagerness:
1 hour: nothing
24 hours: first reminder
3 days: second reminder
7 days: final reminder
30 days: archiveDon't spam.
Don't reminder if they completed elsewhere
SELECT sa.email FROM signup_attempts sa
LEFT JOIN identities i ON i.traits->>'email' = sa.email
WHERE sa.completed_at IS NULL
AND i.id IS NULL -- no Olympus identity for this email yet
AND ...If identity exists by email but signup_attempts doesn't link, maybe they signed up via social (Google). Don't email them.
Privacy
You're emailing someone who didn't complete signup, didn't fully consent. Could be perceived as spam.
Best practice:
- Send only 1-2 reminders.
- Easy unsubscribe link.
- Include "If this wasn't you, ignore this."
- After unsubscribe, never email this address again.
In some jurisdictions (EU), you need explicit consent for marketing emails. "Transactional" emails (like "finish your signup") are usually OK.
Track conversion
Did the reminder work?
SELECT
reminder_n,
COUNT(*) AS sent,
COUNT(CASE WHEN completed_at IS NOT NULL THEN 1 END) AS converted,
COUNT(CASE WHEN completed_at IS NOT NULL THEN 1 END) * 100.0 / COUNT(*) AS conv_rate
FROM signup_attempts_with_reminders
GROUP BY 1;Typical: 5-15% conversion on first reminder, dropping each subsequent.
Compare to no-reminder control group (split A/B).
What else can you do
Pre-fill on return
URL ?email=... pre-fills. Could go further: ?token=... with a magic-link-like UX:
"Click here to continue your signup."
→ takes them past email entry, just need password.Saves a step.
Asynchronous "complete your profile"
If they did sign up but never completed profile (skipped name, photo, etc.):
"You're 80% set up. Finish your profile:"
[Open profile]Different from signup abandonment, they HAVE an account.
Don't overdo
Some users started signup elsewhere or genuinely changed their mind. Multiple reminders annoy.
Hard cap: 3 reminders max, then stop forever.