Download Tracking (Optional)
Download tracking tells you not just that a subscriber polled their feed, but that they actually downloaded an episode — which episode, when, and from which podcast app.
Without it, your Benecaster dashboard shows feed activity: last seen, how often they check in, whether their token is healthy. With it enabled, each episode in your dashboard gets a download count, a per-subscriber download history, and a breakdown by podcast app. That’s the difference between knowing someone is subscribed and knowing they listened.
Enabling Download Tracking
Download tracking has two levels, and no global on/off switch — there is no site-wide “download proxy” setting anywhere in Benecaster.
Show level (the default for every episode on that show). Open the show’s settings, go to Details → Show Flags, and toggle Enable download tracking on all episodes. Every episode on the show inherits this setting unless you override it individually.
Episode level (overrides the show default for that one episode). Open the episode, go to the Media tab, and set Download tracking to Inherit from show (the default — follows the show-level toggle), Force on for this episode, or Force off for this episode. Use the override when one episode should behave differently from the rest of the show — a single promoted episode you want data on even though tracking is off show-wide, or one episode you want excluded even though tracking is on.
No other configuration is needed at either level — Benecaster handles everything automatically once tracking is on for an episode.
Per-show, with a per-episode override, is deliberate. The proxy is the one part of Benecaster that meaningfully increases load on your server, so being able to turn it on for one show, one season, or a handful of episodes lets you get the numbers you actually want without paying for the ones you do not.
To disable it, turn off the show-level toggle, or set the episode override to Force off for this episode. Disabling stops new download records from being created; existing data stays in the database until the retention window passes or you clear it.
With the Analytics Dashboard add-on, the Downloads by tier box counts a show once its show-level toggle is on or any published episode is set to Force on for this episode. Until then it says Download tracking is off for this show, so there are no downloads to show. (under All my shows, …for every show in view…), explains both ways to turn it on, and links Open this show’s Details tab →. Downloads are counted from the moment tracking is on; nothing earlier is recovered. See Analytics Dashboard Overview.
What Gets Recorded
When a subscriber downloads an episode, Benecaster logs:
- Which subscriber (by token)
- Which episode
- When the download happened (stored in UTC, so a download’s day is the UTC day)
- Which podcast app made the request
This data powers the download count column in your episode list, the download history on each subscriber’s detail panel, and — if you have the Analytics Dashboard add-on — the Downloads by tier box: downloads per tier, the top episodes, and By podcast app, which names each app the way Benecaster recognises it. Downloads from an app Benecaster does not recognise are Other apps, and downloads that named no app are Unknown app. The box counts feed downloads only; the download link on an episode’s web page is not counted.
Downloads Can Be Refused, and Refusals Are Not Recorded
A download link serves only what that listener’s own feed carries. Before redirecting, Benecaster checks the episode against the feed the listener is entitled to: their tier’s episodes, plus any episode they hold through an add-on or a purchase. Anything else is refused with “Invalid or expired download link.” — an episode from a higher tier, one that is still scheduled and not yet released, or one outside an early-access window the listener is not in. A follower’s link reaches your public episodes and nothing more. A listener whose feed has fallen back to your public episodes is served what that feed carries, including which version of an episode they receive: a subscriber over your plan’s subscriber limit, a subscriber during your license’s grace period, and someone with no membership who still owns an episode outright.
A download is the same version of the episode the listener’s feed lists. When an episode has Tier Audio Variants, the file served is the variant for the tier their feed takes the episode from, worked out from the tiers they hold now. A member holding two tiers gets the version their feed shows, and after a Tier Mapping change or a switch of membership plugin the download follows the new mapping, just as the feed does.
An episode that isn’t published can’t be downloaded. A download link answers Download not found unless the episode and its show are both published. Trashing, unpublishing or scheduling an episode, or unpublishing its show, stops the links already sitting in podcast apps straight away, even though the episode’s access dates are kept for when it comes back.
Your paying subscribers are not affected by this in practice: every episode in their feed downloads as normal. The check only ever refuses an episode the listener’s podcast app would not have been shown in the first place. Episode pages, the web player and the feeds themselves apply the same rules independently.
A download is also refused when the show is not entitled to serve it — a cancelled or expired license, a payment failure that ran its full 30 days, or a show that is disconnected. The subscriber’s download URL returns an error reading “This show is no longer available for download.” Followers are the exception and keep downloading, because a follower’s feed only ever carried your public episodes.
A refused download is not logged, so you cannot see refused attempts in your download stats. Only completed downloads are recorded, and that is deliberate: every field in the log — the tier, the audio variant, the byte range — describes a download that finished. A refusal has none of them, so a logged refusal would be counted as a genuine download, and a lapsed show’s numbers would go up at exactly the moment they should collapse.
What this looks like in your charts: a lapsed show’s downloads fall to zero, apart from followers. There is no way to tell “nobody tried” from “everybody was refused” — so read a flatline during a license problem as the license problem, not as an audience that left.
What It Costs You
Download tracking has no setup complexity, but it does add load to your WordPress site. Here’s why: when a subscriber’s app downloads an episode, the request briefly passes through your WordPress installation — Benecaster logs it, then immediately redirects the app to the actual audio file hosted wherever you keep it. Your server never serves the audio itself.
That redirect is a WordPress request. On a small show with a modest subscriber base, it’s negligible. On a show with hundreds of active subscribers releasing multiple episodes per week, you could see thousands of extra PHP executions weekly.
Two things to watch as your show grows:
Hosting load. Entry-level shared hosting (Bluehost, SiteGround Shared, DreamHost Shared, and similar) may struggle with this additional request volume — particularly around episode release days when many subscribers sync at once. If your site feels sluggish after enabling download tracking, or your host’s control panel starts showing elevated resource usage, the proxy is the likely cause. Managed WordPress hosting (Kinsta, WP Engine, Flywheel) handles it comfortably at most show sizes.
Database size. Benecaster stores a record for each download, and those raw records are only kept for about 30 days before being rolled up (see Clearing Download Data below) — the raw table does not grow without bound. Within that 30-day window, though, a large, active show releasing several episodes a week to hundreds of subscribers can still generate tens of thousands of rows. This is generally fine — the data is indexed — but it is real disk usage while it lasts, and the busier your show, the more of it there is at any given time.
Clearing Download Data
If you want to reclaim database space or start fresh, go to Benecaster → Settings → Tools → Clear download analytics data. This permanently removes all stored download records. It doesn’t affect subscriber records, tokens, episode data, or anything else.
You can also configure how long records are retained before automatic pruning, under Benecaster → Settings → Tools → Analytics Data — see Settings Reference for details.
The download log is handled differently from the other analytics tables in that retention setting, and it’s the one where “Forever” is safe. Every night, download rows older than 30 days are automatically summarized into a permanent, much smaller table of daily counts (by episode, tier, and podcast app) and the original detailed rows are removed. Your episode and subscriber download counts stay accurate — they read from the summary once rows age past 30 days — but the raw table itself never grows without bound. “Safe” means that: it does not mean the raw table stays small at any given moment — a large, active show can still hold tens of thousands of rows within the 30 days of detail it keeps (see Database size above). Subscriber events and daily snapshots, the other two tables under that same retention setting, are not summarized this way and do grow with whatever window you choose there.
Whatever retention window you choose, pruning never removes download counts from your charts. The retention cleanup — nightly at 01:00, or Prune now — never deletes download rows outright. It first adds every whole day (UTC) before the cutoff to the permanent daily counts, and removes the raw rows only once those counts are confirmed. Because it works in whole UTC days, a raw download can be kept up to one day past your retention period, and a day whose counts could not be confirmed is kept and tried again the next night. Subscriber events and daily snapshots, by contrast, are deleted outright once they pass the window.
If You Notice Problems
Download tracking is one of the first things to check when something feels off with your site’s performance or database size. Specifically, look here if:
- Your hosting dashboard shows higher-than-expected PHP request counts or CPU usage, especially around episode release days
- Your database is growing faster than you’d expect given your subscriber count
- WordPress admin pages are noticeably slower on busy days
- Your host has flagged resource overuse
In any of these cases: check which shows have download tracking on (Details → Show Flags) and whether any episodes carry a Force on for this episode override. Turning off the show-level toggle, or setting the busiest episode’s override to Force off for this episode, immediately stops new requests for it flowing through the proxy, and a handful of recent, heavily-downloaded episodes is usually where the volume is coming from. You can confirm it’s the source by checking how quickly your database is growing — rapid growth correlates with high download volume when tracking is on.
If you’re on shared hosting and seeing consistent issues, the practical options are: disable tracking, switch to managed WordPress hosting, or reduce the retention window so the table stays smaller over time.
For Developers
Each download fires the benecaster_download_redirected action immediately before the 302 redirect is issued — you can use it to log to an external analytics service, enrich download records, or trigger workflows based on download activity. See the hook reference for parameters and examples.
The 302’s target also runs through the benecaster_episode_audio_url filter — the same filter the feed and the web player run, so a CDN rewrite or signed-URL callback registered there reaches tracked downloads too, not just feed and player requests. The third argument, $tier_slug, is the tier the listener’s feed takes this episode from (public for a follower), so a callback gets the same slug for a download as it got for that episode in the listener’s feed. The show’s Enclosure URL prefix wraps whatever your callback returns, and returning an empty string refuses the download outright — the app gets a 404, and nothing is written to the download log, so a refusal never counts as a download. See the hook reference for the full parameter list and examples.
See Also
Need this built rather than just documented? See our services →