understand · icp and the trigger window
The trigger window
How long a buying window stays open.
In ICP and the trigger window
wiki · stage 3 · icp and trigger detection · component 2 of 2
Fit says who could buy. The window says when. For a founder who just launched, the window opens about three days after launch and closes near day 45, peaking in days 5 to 21 with a second spike at 28 to 35. Before it, a message is noise; after it, it reads as a rebuke.
Timing is a separate layer.
Fit changes slowly and lives on the lead. Timing goes stale in days and lives on the signal.
Every trigger has a clock.
Each trigger type gets a freshness window, fitted from data once there's enough, guessed and labelled until then.
The exit is not a target.
"Should I give up" is real pain, but it marks the window closing. Help in public; don't sell.
what it is
The window of dissatisfaction, in industry terms
Industry names: trigger event, buying window, timing in signal-based selling. Craig Elias's term is the Window of Dissatisfaction: "unhappy with Status Quo but not searching for Alternatives yet." It opens when something breaks the person's belief that their current approach works, and closes when they fix it, buy something or give up.
For the launch trigger the window has a measured shape from the Sep 19 research: 26 dated founder posts across five weeks. Directional, not a tracked cohort, so the bars on this page are priorities, not rates.
Window opens — forcing event · something breaks: traffic dies on day 2 to 4, trials expire around day 28 to 35.
Peak — highest priority · days 5 to 21, tactical questions: "where did your first users come from?"
Second spike — the money doesn't arrive · days 28 to 35, first-month numbers.
Exit — window closes · day 60 and later; existential posts.
Freshness — fresh_for · how long a signal stays actionable; a field on every detector.
Decay curve — reply rate by age · the data that replaces a guessed window with a fitted one.
how it works
How the window becomes a ranking
The launch date is the trigger, and it comes free from launch directories with no inference. Pain phrases since launch confirm the window is open. Together they rank the queue: who is likely to reply this week.
- Find the launch date — launch feeds: Show HN, PeerPush, Product Hunt
- Compute days since — day 0 = launch; place the founder on the curve
- Check for pain — a pain phrase posted since launching?
- Score the window — peak, secondary, cooling or closed
- Add fit signals — paid slot, TrustMRR band, follower count
- Gate on reachability — founder handle found, or skip
- Rank the queue — likely to reply this week first
- Expire — drop from the queue when the window closes
- Find the launch date — launch feeds: Show HN, PeerPush, Product Hunt
- Compute days since — day 0 = launch; place the founder on the curve
- Check for pain — a pain phrase posted since launching?
- Score the window — peak, secondary, cooling or closed
- Add fit signals — paid slot, TrustMRR band, follower count
- Gate on reachability — founder handle found, or skip
- Rank the queue — likely to reply this week first
- Expire — drop from the queue when the window closes
The curve
day 0–2 · Euphoric — send nothing
launch day traffic; the founder is celebrating
day 3–10 · "Traffic died, what now" — primary
the traffic dies, day 2 to 4; tactical questions start
day 11–21 · Trial purgatory — activation help
signups don't activate; the founder refreshes analytics
day 28–35 · "My first month numbers" — secondary
trials expire; the money doesn't arrive
day 36–60 · Cooling — light touch
the founder is deciding what to do next
day 60+ · Rationalizing an exit — nothing
existential posts: "should I give up?"
Two forcing events shape it. The traffic dies on day 2 to 4: day zero is roughly 60% of a launch's traffic, days 1 to 7 about 25%. The money doesn't arrive on day 28 to 35: about 35 to 45% of signups activate within 7 days and 5 to 10% of those pay within 30, so a 50-signup launch produces one or two customers, often zero.
the object
Timing on a signal
Timing is stored on the signal, not the lead, because it goes stale on its own clock. The lead reads it when it is ranked.
signal_timing
| field | type | what it holds |
|---|---|---|
trigger_id | enum | which trigger, e.g. launched_recently |
event_at | timestamp | when the trigger happened: the launch date or the post time |
captured_at | timestamp | when your system saw it; the gap is detection lag |
age_days | derived | days since event_at, at ranking time |
phase | enum | pre, peak, trial, second_spike, cooling, closed |
fresh_for_days | int | the window for this trigger; guessed until fitted |
expires_at | timestamp | event_at + fresh_for |
window_source | enum | guess, research, fitted |
sample
{
"trigger_id": "launched_recently",
"event_at": "2026-10-03T16:00:00Z",
"captured_at": "2026-10-03T18:20:00Z",
"age_days": 13,
"phase": "trial",
"fresh_for_days": 45,
"expires_at": "2026-11-17T16:00:00Z",
"window_source": "research"
}ranking signals
What ranks the queue inside the window
The Sep 19 research's weights. 'Gate' means required: without a founder handle there is no one to reach.
timing
3–21 days since launch
- weight
- highest
- why
- the window at its peak
budget
Paid for the launch slot
- weight
- high
- why
- proven budget and dissatisfaction
pain
Posted a pain phrase since launching
- weight
- high
- why
- stated, not inferred
pain
Low upvotes on a paid tier
- weight
- medium
- why
- paid and it didn't work: the sharpest state
fit
TrustMRR row at $0–500
- weight
- medium
- why
- confirms the segment
fit
Under 2,000 followers
- weight
- medium
- why
- no distribution of their own
timing
28–35 days since launch
- weight
- medium
- why
- the second spike
gate
Founder handle found
- weight
- gate
- why
- required to reach them
Phrases that confirm the window is open
Ranked by frequency times clarity. The compound that matters most: an elapsed-time phrase and a zero in the same post.
"launched N days ago" + "0 users" — the whole ballgame: elapsed time and a zero together
"crickets" / "went quiet" — on a first-person launch
"nobody knows it exists" — the distribution gap, named
"I'm a builder, not a marketer" — reliable on Reddit, not on X
"refreshing analytics" — the purest tell
"should I give up" — real pain, but the window's exit: help, don't sell
failure modes
How it goes wrong, and how to catch it
Messaging the euphoric — Day 1 congratulations followed by a pitch. · Catch it: nothing before day 3; the phase field blocks it.
Selling to the exit — "Should I give up" treated as a hot lead. · Catch it: phase closed routes to help-in-public, never an offer.
Guessed windows treated as facts — A 45-day window applied to every trigger type. · Catch it: window_source shows guess vs fitted; fit it once replies exist.
Detection lag — A signal caught on day 9 is ranked as if caught on day 2. · Catch it: store event_at and captured_at; rank on age, not capture time.
Retrospective posts — A war story from last year read as current pain. · Catch it: past-perfect tense and no current numbers: discard as retrospective.
data to capture
Record it so a model can learn from it later
Every decision on this page is training data if it is recorded in the guide's shape from day one.
1 · log the decision · 2 · version whatever decided · 3 · freeze the inputs · 4 · keep the negatives · 5 · log the odds · 6 · every human touch is a label · 7 · one chain of ids · 8 · keep the raw
record
- event_at and captured_at on every signal (posted time and capture time)
- the phase and age at the moment the lead was ranked, frozen
- reply and signup outcomes per signal, with age at touch
- discards for being outside the window
label
reply and signup per trigger, by age in days
trains
a fitted freshness window per trigger (the decay curve) to replace the guessed one, and a value ranking of triggers
test
- knob: each trigger's freshness window (for example, 24 hours vs 72 hours for a pain post)
- mode: offline from the decay curve first, then by lead cohort
- win rule: replies per touch, holding playbook and copy constant