{
  "id": 15870380,
  "title": "Building a \"Trending This Week\" Page: Time-Decayed Play Counts, Log-Space Scores and Cached Reads in Next.js",
  "url": "https://urgent.news/2026/10/21/building-a-trending-this-week-page-time-decayed-play-counts-log-space",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-21T10:08:31.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/abidali671/building-a-trending-this-week-page-time-decayed-play-counts-log-space-scores-and-cached-reads-31a"
  },
  "original_language": "en",
  "account": "Everyone wants to see what's trending right now on a soundboard. The obvious solution is a list sorted by total plays, but that list quickly becomes stale as older, funnier clips retain their top positions. Meme Tap solves this problem by displaying the most-tapped clips this week. To achieve this, the post describes a method using an exponentially decayed score stored in log space, a lightweight play-counting endpoint, and a cached read path in the Next.js App Router.\n\nThe first attempt to implement a trending page is to count plays within the last 7 days, but this approach has two issues. First, plays from 6 days and 23 hours ago count as fully as those from a minute ago, causing rankings to jump around at odd moments. Second, scanning a week's worth of events on every refresh is inefficient.\n\nTo address these issues, the post proposes using exponential decay with a half-life of 48 hours. This means that every play contributes a weight that halves every 48 hours. So, a play right now is worth 1, a play two days ago is worth 0.5, and a play from four days ago is worth 0.25. The score of a sound is the sum of these weights over all its plays. By choosing an epoch in the past, the score remains consistent as time passes, allowing storage of a single number per sound and sorting directly without background jobs.\n\nTo prevent overflow in the logarithmic calculation, the post suggests adding logarithms instead of actual weights. The `logAdd` function combines two log scores without overflow. The `currentWeight` function converts the stored log score back into the equivalent number of fresh plays for display or debugging. The database schema consists of a single table storing the log score and update time for each sound. The `sound_trending` table is indexed on the log score for efficient querying.\n\nThe database insertion process involves adding the log score of a new play to the existing log score for a sound. The `INSERT` statement uses the `ON CONFLICT` clause to update the log score if the sound already exists. The `GREATEST` and `LEAST` functions ensure that the correct log addition is performed.",
  "summary": "A soundboard needs a \"what's hot\" page. The obvious version is a list sorted by total plays, and it goes stale almost immediately. The clips that were funny two years ago have a huge head start, so they sit at the top forever and nothing new can climb past them. What people actually want is \"what is everyone tapping right now\". On Meme Tap the trending page is described as the sound buttons…",
  "key_points": [
    "Exponential decay with 48-hour half-life addresses play freshness and efficiency",
    "Logarithmic calculations prevent overflow in score storage",
    "soundtrending table indexed on log score for efficient querying"
  ],
  "editors_take": "Replacing static play counts with exponential decay ensures that trending lists reflect immediate popularity rather than historical dominance, allowing the platform to maintain relevance without expensive background processing.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}