Viral score
Every video gets a 50–99 score computed in src/lib/viral.ts. It blends engagement quality with posting velocity, then normalizes within the scraped batch.
The formula
engagement = (likes + 4·comments + 6·shares + 3·collects) / views
velocity = views / hours_since_posted
rawScore = 0.55 · ln(1 + engagement·1000)
+ 0.45 · ln(1 + velocity/1000)
viral_score = 50 + 49 · (rawScore − batchMin) / (batchMax − batchMin)Why these weights
- Shares ×6 — the strongest algorithmic signal on every platform.
- Comments ×4 — conversation drives distribution more than passive likes.
- Collects ×3 — saves signal durable value.
- 55/45 split — engagement quality slightly outweighs raw reach, so small-but-brilliant videos can outrank big-but-empty ones.
Edge cases
- Hidden view counts — Instagram often hides plays. When views are 0, reach falls back to
likes × 10and engagement switches to a comment-rate-based proxy. - Freshness — velocity divides by hours since posting (minimum 1h), so a 3-hour-old video with 1M views outscores a 3-month-old one with the same numbers.
- Batch normalization — scores are relative within each scrape batch, mapped to 50–99. Cross-platform comparison stays meaningful because Analyze scores a video against all peers of the same platform in your DB.
Score bands
- 95–99 — exceptional, top-of-feed material
- 85–94 — strong, proven patterns worth stealing
- 70–84 — solid performers
- 50–69 — trending, but unremarkable