Methodology
How the numbers on Kick Info are produced — collection schedule, computation, and the design choices behind the metrics.
Last updated May 5, 2026
Most analytics dashboards present numbers without explaining where they come from or how to interpret them. Kick Info tries to do the opposite. This page documents the collection pipeline, every aggregation we run, and the trade-offs we made — so a viewer can decide for themselves how much to trust each figure on the site.
1. Data sources
Everything visible on Kick Info comes from public endpoints Kick.com exposes for its own website. We do not have a private agreement with Kick. We do not scrape pages, log in, or access non-public data. The endpoints we read are:
kick.com/stream/livestreams/en— the paginated live-streams directory that powers Kick’s landing page. We use this to discover every channel currently broadcasting.kick.com/api/v2/channels/{slug}— the per-channel profile endpoint with current follower count, avatar, banner, bio, partner status, and basic livestream metadata.kick.com/api/v2/channels/{slug}/livestream— the active livestream endpoint with current viewer count, stream title, category and start time.kick.com/api/v1/subcategories— the paginated categories list, used to populate category names, slugs and banner artwork.
All endpoints are accessed with normal HTTP requests, the same ones a browser makes when you visit Kick. We respect rate limits with retries and exponential backoff, and avoid producing request patterns that look like abusive scraping.
2. Collection schedule
The collector runs as a background process on the same server that hosts the website. It schedules four main jobs, each with a different cadence chosen to balance freshness against load:
2.1 Live polling — every 2 minutes
For every channel currently broadcasting, we hit the per-channel livestream endpoint to record a snapshot of the viewer count. This is the freshness floor for the live-stream panels and the viewer-count chart on each channel page. A streamer’s in-progress numbers can lag by at most ~2 minutes plus network round-trip.
2.2 Directory discovery — every 5 minutes
We walk the public live-streams directory to find newly-live channels we haven’t encountered before. Kick’s Cloudflare layer occasionally soft-blocks the walk with HTTP 403s during peak traffic, so the job retries with exponential backoff (4 s, 8 s, 16 s, 32 s) and only closes “stale” sessions when the walk fully completed — partial walks would falsely mark live streamers on unwalked pages as offline.
2.3 Follower sampling — every 5 minutes
Every channel currently live gets a fresh follower-count sample on every run, plus a small rotating slice of stale non-live channels. The earlier “sample every channel every five minutes” approach hit Kick’s rate limits and only managed 5–15% coverage per run; the live-priority rotation now gets reliable samples for the channels where follower deltas matter most.
2.4 Materialised aggregations — every 1–5 minutes
The rankings, language splits, and home-page KPIs aren’t computed on every page load. Instead, the collector rebuilds materialised tables in the background: HomeSnapshot (every 1 minute), LiveStreamSnapshot (every 2 minutes), ChannelStats, CategoryStats and LanguageStats(every 5 minutes). Each ranking page is then a sorted SELECT over a small pre-computed table rather than an aggregation across millions of viewer snapshots. That’s why pagination feels instant even on a dataset of 85,000 channels and several million stream sessions.
3. How viewer counts are aggregated
A single live stream produces a continuous timeline of viewer-count snapshots. Computing “average viewers” for that stream is where the methodology becomes interesting.
3.1 Why we use a time-weighted average
The naive approach — averaging every viewer-count snapshot — is wrong when snapshot intervals aren’t uniform. Imagine a stream where one snapshot is taken right when viewers peak (say, 20,000) and the next ten are taken every two minutes thereafter as viewers settle down. Averaging arithmetically gives the peak more weight than it deserves. We instead compute the area under the viewer-count curve (using linear interpolation between snapshots, capped at five minutes per gap to avoid wildly misattributing time across long gaps in our coverage) and divide by the stream’s total duration. The result is the average a hypothetical observer watching the stream end-to-end would have experienced.
3.2 Hours watched
Hours watched is just “sum of viewer-time” — the same area under the curve, expressed in viewer-hours instead of an average. A two-hour stream with 1,000 concurrent viewers produces 2,000 viewer-hours of viewing. We sum hours watched across all of a channel’s streams in the window to get the channel-level total, and across all channels in a language to get the language-level total.
3.3 Channel rankings
For the /channels rankings, average viewers is total viewer-hours in the window ÷ total broadcast-hours in the window. This is what people mean by “average concurrent viewers across the channel’s streams” — it weights long streams more than short ones, and is the metric every comparable analytics service uses.
4. Follower deltas
Every follower count we display starts as a sample we recorded at a specific timestamp. Deltas — “followers gained in 30 days”, “followers gained this stream” — are computed by finding the closest sample on each side of the window of interest and subtracting.
Two failure modes are worth knowing about. First, very new channels won’t have a sample older than their first stream, so “gained this stream” falls back to the earliest-ever sample, which can understate growth if we joined them late. Second, channels we discovered mid-stream may have a first follower sample dated after the stream started, which has the same effect. Both modes converge to accurate numbers after ~24 hours of tracking.
5. Live-channel filtering
Two filters apply to every “live channels” counter on the site:
- Deduplication by channel.Stream-restart races occasionally leave two open sessions for the same channel for a few minutes. We collapse those to one row per channel in the materialised live snapshot, picking the higher viewer count when there’s a tie.
- Bot filter. Channels whose current viewer count exceeds their total follower count are hidden from all live displays and rankings. A 6,000-viewer channel with 12 followers is almost certainly view-botted; real audiences are tied to real follower counts. This filter removes about 6% of live channels.
6. Caching
The site sits behind Cloudflare. We send long-lived Cache-Controlheaders from the origin so most page responses are served from Cloudflare’s edge:
- Home page: 1-minute edge cache. The home page reads a single materialised row that recomputes every minute, so the cache freshness is bounded by computation freshness.
- Rankings (
/channels,/games,/languages): 10-minute edge cache. Each unique combination of sort, range, language and page is cached independently. - Live-streams list (
/channels/live): 1-minute edge cache. - Channel pages: 5-minute edge cache. Live-now badges and current-viewer counts get a separate, shorter-lived 30-second cache so they stay visibly fresh.
- Category banner images and avatar art (
/cdn/categories/…): immutable 1-year cache.
The compound effect is that a typical page load hits our server’s origin in under 5% of requests; the other 95% come straight from Cloudflare’s edge. That’s why the site feels fast even though it’s running on a single small server.
7. Image hosting
Category banners and channel avatars used to hot-link directly to Kick’s CDN. We now mirror category banners to our own domain (/cdn/categories/{id}.webp) so the browser never makes third-party image requests, ad-blocker rules don’t hide them, and the URLs stay stable even if Kick’s CDN shape changes. The mirror is built by a collector job that walks Kick’s paginated subcategories list and downloads each banner once into a shared Docker volume.
8. Known limitations
- Coverage gaps from Cloudflare blocks.When Kick’s edge rate-limits us with 403s, the corresponding minutes show no new viewer snapshots for the affected streams. The per-stream chart will look flat or jump on the next successful poll. We design around this — the live-poll job retries with backoff, and partial walks don’t cause incorrect “offline” assignments — but the data isn’t magical.
- Discovery delay.If a brand new streamer goes live and they’re on the back pages of the live directory when we walk it, it can take 5–10 minutes for them to show up in our database. Once discovered they get the full 2-minute live-polling treatment.
- Slug changes.When a streamer renames their Kick channel, our database keeps both the old and new slug (the old one becomes an alias and redirects to the new). We can’t catch every rename instantly though, and a renamed channel may briefly look offline until the next discovery cycle reconciles things.
- Average viewers for the current live session. The KPI cards on a channel page during a live stream use the snapshot-derived average, which can lag the truth by up to two minutes. Closed-session averages are accurate to the minute.
9. Reproducing the numbers
Every metric on the site is deterministic from the underlying viewer-snapshot and follower-snapshot tables. If you spot a figure you suspect is wrong, email hello@kickinfo.net with the URL and what you expected — we can run the same computation from the raw timeline and explain what produced it.
10. Changes to this page
We update this methodology whenever the collection pipeline or aggregation logic changes in a way that affects user-visible numbers. The “last updated” date at the top reflects the most recent change.