Skip to content

Touch Velocity

Touch velocity is the average number of engagement touches per day between a person’s first and last recorded touch. High velocity means many touches in a short window; low velocity means the same number of touches spread over a longer period. This page examines whether velocity predicts application behavior independently of total touch count.

The sweet spot is 0.5–2 touches per day sustained over 130–190 days — both the 0.5–1/day and 1–2/day buckets hit an identical 57.9% application rate (3.42x lift). Faster accumulation underperforms: the 2–5/day bucket drops to 41.9% despite a similar touch count, and the 5+/day bucket falls to 22.2% — likely a mix of bots, scrapers, or genuinely compressed engagement that doesn’t reflect real decision-making behavior.

The single-day bucket (36K people, 4% rate) is the starkest finding: engagement confined to a single calendar day — even when it involves multiple touches (9.6 on average) — is nearly as predictive as no touch at all. These are one-session visitors who never returned.

Velocity BucketPeopleApplicantsAvg TouchesAvg Span (days)App RateLift
1–2 / day10,1875,894179.4129.757.9%3.42x
0.5–1 / day9,3825,428138.5192.357.9%3.42x
2–5 / day8,7833,679162.557.141.9%2.48x
< 0.5 / day12,4894,68862.9303.737.5%2.22x
5+ / day8,6351,916101.111.222.2%1.31x
no engagement touch126,84312,91610.2%0.60x
single day36,7411,4709.60.04.0%0.24x

The strongest predictor is not how many touches a person accumulates, but the pace at which they accumulate them. Sustained moderate engagement — 0.5 to 2 touches per day over 4–6 months — produces the highest application rates (57.9%). Very fast accumulation underperforms, and single-day engagement is nearly indistinguishable from no touch at all. The data suggests nurture programs should aim for consistent contact over time rather than front-loaded intensity.

Total touch volume is a strong predictor of application behavior, but it conflates two different things: how much engagement happened and how quickly it happened. A person with 50 touches over 7 days is in a very different behavioral state than a person with 50 touches over 18 months.

Understanding velocity helps answer:

  • Is concentrated engagement (high velocity) a stronger signal than diffuse engagement?
  • Should nurture campaigns try to compress contact into shorter windows?
  • Do fast-moving prospects need different messaging than slow ones?

Velocity is calculated as total engagement touches divided by the number of days between first and last touch. Persons whose touches all fall on a single calendar day (span of 0 days) are placed in a single day bucket, since velocity cannot be computed over a zero-day span. Persons with no engagement touches are excluded.

Velocity buckets:

  • Single day (all engagement on one calendar day)
  • < 0.5 touches/day (very slow)
  • 0.5–1 touches/day (slow)
  • 1–2 touches/day (moderate)
  • 2–5 touches/day (fast)
  • 5+ touches/day (very fast)
WITH touch_spans AS (
SELECT
person_id,
COUNT(*) AS engagement_touches,
MIN(touched_at) AS first_touch_at,
MAX(touched_at) AS last_touch_at,
datediff('day',
CAST(MIN(touched_at) AS DATE),
CAST(MAX(touched_at) AS DATE)
) AS span_days
FROM person_touches
WHERE touch_category = 'engagement'
GROUP BY person_id
),
velocity AS (
SELECT
person_id,
engagement_touches,
span_days,
CASE
WHEN span_days = 0 THEN NULL
ELSE ROUND(engagement_touches * 1.0 / span_days, 3)
END AS touches_per_day,
CASE
WHEN span_days = 0 THEN 'single day'
WHEN engagement_touches * 1.0 / span_days < 0.5 THEN '< 0.5 / day'
WHEN engagement_touches * 1.0 / span_days < 1.0 THEN '0.5–1 / day'
WHEN engagement_touches * 1.0 / span_days < 2.0 THEN '1–2 / day'
WHEN engagement_touches * 1.0 / span_days < 5.0 THEN '2–5 / day'
ELSE '5+ / day'
END AS velocity_bucket
FROM touch_spans
),
applied AS (
SELECT DISTINCT person_id
FROM person_tags
WHERE tag_type = 'applied'
AND tag_value = 'Yes'
),
labeled AS (
SELECT
p.id AS person_id,
COALESCE(v.velocity_bucket, 'no engagement touch') AS velocity_bucket,
v.engagement_touches,
v.span_days,
v.touches_per_day,
CASE WHEN a.person_id IS NOT NULL THEN 1 ELSE 0 END AS applied
FROM persons p
LEFT JOIN velocity v ON p.id = v.person_id
LEFT JOIN applied a ON p.id = a.person_id
),
overall AS (
SELECT ROUND(SUM(applied) * 1.0 / COUNT(*), 3) AS overall_application_rate
FROM labeled
)
SELECT
l.velocity_bucket,
COUNT(*) AS people,
SUM(l.applied) AS applicants,
ROUND(AVG(l.engagement_touches), 1) AS avg_touches,
ROUND(AVG(l.span_days), 1) AS avg_span_days,
ROUND(AVG(l.touches_per_day), 2) AS avg_touches_per_day,
ROUND(SUM(l.applied) * 1.0 / COUNT(*), 3) AS application_rate,
o.overall_application_rate,
ROUND((SUM(l.applied) * 1.0 / COUNT(*)) / NULLIF(o.overall_application_rate, 0), 2) AS application_rate_lift
FROM labeled l
CROSS JOIN overall o
GROUP BY l.velocity_bucket, o.overall_application_rate
ORDER BY application_rate DESC;