Batch benchmarking

Benchmarking shares the same concurrency story as scoring at scale, with two twists:

  1. benchmark_channel is heavier — it fetches recent videos for each channel before percentile-ranking. Server-side concurrency is capped at 5 per key regardless of plan.
  2. Caching is your friend — channel-level signal is stable over hours, not seconds. Cache benchmark results in your own store.

Example: rank a list of competitor channels

import asyncio
from brightbean import AsyncBrightBean

CHANNELS = [
    "https://www.youtube.com/@channelA",
    "https://www.youtube.com/@channelB",
    # ...
]

async def main():
    async with AsyncBrightBean() as client:
        sem = asyncio.Semaphore(5)  # match the per-key concurrency cap

        async def one(url):
            async with sem:
                return url, await client.benchmark_channel(url=url)

        results = await asyncio.gather(*(one(u) for u in CHANNELS))
        for url, res in results:
            print(f"{url}\t{res.niche.slug}\t{res.channel.engagement_percentiles.overall}")

asyncio.run(main())

Caching strategy

A pragmatic two-layer cache:

Layer TTL Key
In-memory (within a single batch) for the run channel_id
Persistent (Redis / Postgres / Sqlite) 24h–7d channel_id

Why 24h–7d? Subscriber counts and view distributions don’t shift meaningfully on a sub-day timescale. If a channel’s posting cadence is your concern, key off sample_window_days from the response and only refresh when the window is older than your tolerance.

When to refresh

Refresh sooner if:

Otherwise weekly is plenty.

Budgeting

Each benchmark_channel is 5 credits, each benchmark_video is 3. For a 200-channel competitive set with weekly refresh:

200 channels × 5 credits × ~4 refreshes/month = 4,000 credits/month

Comfortably inside the Starter tier (10,000/day).