RedditapisRedditapis
reddit datasetreddit data apireddit data collectiondataset buildingoriginal researchapi tutorialdata engineering

Building a Reddit Dataset From the API: What You Get That a Static Dump Does Not

The public archives ship monthly. We measured what one live call returns instead: 1,000 posts across ten communities, 22 fields each, a median newest record 12 minutes old, and 496 of those rows already changed 11 minutes later.

Emma·
Guide to building a Reddit dataset from the public data API in 2026, comparing measured freshness, field counts, record mutability and coverage against the monthly static data dumps

Every page that ranks for "reddit dataset" hands you a file.

TL;DR: We measured both sides on 2026-09-02. One live call per community across ten communities returned 1,000 posts, 100 per call, 10 of 10 answering HTTP 200, each record carrying 22 top-level fields. The median newest record was 12.03 minutes old and the freshest was 21 seconds old. The freshest public monthly dump on the same day covered data through 2026-07-31, which is 32.73 days back, because those archives publish a median of 9 days after the month they cover ends across 15 consecutive releases. We then re-read the same 1,000 records 11.4 minutes later and 496 of them had already changed score or comment count. The archive still wins one column: 25 of those 1,000 year-old top posts no longer name an author through the live API, and a dump written a year ago still does.

We went looking for the page that teaches building one instead, and it is not there. The top ten results for the head term on 2026-09-02 were a subreddit, three forum threads asking where to get data, an academic corpus loader, a Stanford embedding set, a GitHub repository last touched in 2016, a Kaggle listing, a TensorFlow catalog entry and a vendor selling a packaged Reddit dataset on a data marketplace. Ten results, every one of them a thing you download or a person asking what to download. Nobody on that page shows you the other option.

Not affiliated with Reddit Inc. redditapis.com is an independent third-party REST proxy for Reddit's data API. This guide is vendor-neutral: it reports our own measurements with their dates and sample sizes, names the places where a static archive is genuinely the better tool, and says plainly which figures are measured and which are cited.

This post is that missing page, and it does not argue by assertion. Every number below came out of a pass we ran on 2026-09-02: ten communities, 1,000 posts, a re-read of the same 1,000 ids eleven minutes later, 1,000 more posts from the past year, five sequential pages against one community, and a read of the public archive release feed itself. The raw output and the falsification condition for each pass are recorded, and each figure says whether it was measured, derived or cited.


TL;DR

Every page that ranks for "reddit dataset" hands you a file. We measured what the other option returns. On 2026-09-02 one call per community across ten communities returned 1,000 posts, 100 per call, 10 of 10 answering HTTP 200, each record carrying 22 top-level fields. The median newest record was 12.03 minutes old and the freshest was 21 seconds old. The freshest public monthly dump on the same day covered data through 2026-07-31, which is 32.73 days back, because those archives publish a median of 9 days after the month they cover ends, measured across 15 consecutive releases. Then we re-read the same 1,000 records 11.4 minutes later: 496 of them had already changed their score or comment count. That is the argument. A dump is a photograph of a moving thing, and half of what it says about new posts stops being true inside twelve minutes. The archive still wins on one count, and we measured that too: 25 of 1,000 year-old top posts no longer name their author through the live API, and an archive written a year ago still does.


What actually is a Reddit dataset in 2026?

It is one of two very different things, and the phrase hides the difference. A Reddit dataset is either a file somebody exported at a moment in the past, or a store you keep filling from a live source.

  • The export. A corpus written once, covering a stated date range, distributed as a download. Its contents never change, which is both the feature and the limit.
  • The store. A table you fill from a live source on a cadence, whose rows you can re-read and correct. Its coverage grows and its mutable fields stay current, at the cost of running something.

Both are legitimate. They answer different questions, they cost different things, and almost every published guide describes only the first one. The word "dataset" pulls toward the file, because that is what the word has meant since researchers first started sharing corpora, and the pull is strong enough that people building live pipelines still describe what they are doing as "getting the dataset".

Hero statistic card showing that the median age of the newest post returned by one live call across ten communities was twelve point zero three minutes on 2026-09-02, with the freshest single record twenty one seconds old

The distinction shows up the moment you ask a question with a tense in it. What are people saying about this product this week is a live question, and no file answers it. What did discussion of this topic look like across 2019 is a historical question, and a live API answers it slowly and expensively while a file answers it in one scan. Most of the confusion in this subject comes from people asking a live question and reaching for a historical tool because that is what the search results offered.

The autocomplete tail for the head term makes the pull visible. On 2026-09-02, Google's own suggestions for "reddit dataset" were: reddit datasets, reddit dataset kaggle, reddit dataset download, reddit dataset for sentiment analysis, reddit dataset pushshift, reddit dataset huggingface, reddit dataset github, reddit dataset.csv, reddit dataset pyg, reddit dataset graph. Ten suggestions, of which seven name a static download source or a file extension. That is not Google being wrong. It is Google reflecting what people actually type, which is a request for a file, because for most of the last decade a file was the only thing on offer.

That changed and the guidance did not. Our own state of the public JSON endpoints covers what happened to the free path, and the hub this post sits under covers the full method landscape. The short version is that the bulk archive lane narrowed sharply, the credentialed API lane stayed open, and the published advice mostly still points at the lane that narrowed.

How fresh is the data one live API call returns?

Twelve minutes old at the median, and twenty one seconds old at best. On 2026-09-02 we made one listing call per community against ten communities, at limit=100 sorted by new, and measured the gap between the read time and the newest created_utc in the returned page. The median across those ten calls was 12.03 minutes. The fastest community, r/AskReddit, returned a post that had existed for 0.35 minutes. The slowest, r/webscraping, returned one 504.24 minutes old, and that is a property of how quiet the community is rather than anything about the API.

AGE OF THE NEWEST RECORD ONE CALL RETURNED

Freshness by community, one pass, ten calls

PointValue (min)
r/AskReddit0.35 min
r/MachineLearning0.8 min
r/technology3.1 min
r/datasets6.77 min
r/SaaS9.03 min
r/LocalLLaMA15.03 min
r/redditdev28.14 min
r/dataisbeautiful223.01 min
r/Python406.8 min
r/webscraping504.24 min
Minutes between the read time and the newest created_utc in each returned page, measured 2026-09-02. The spread is a property of how busy each community is, not of the API.

Here is the whole pass rather than a summary of it, including the window each page covered and what each request cost in wall clock:

What one live call returned, per community, read in one pass

CommunityPosts returnedWindow coveredAge of newest recordRequest latencySource
r/AskReddit1000.47 hours0.35 min5.011 smeasured
r/MachineLearning100407.56 hours0.80 min16.665 smeasured
r/technology10029.45 hours3.10 min2.854 smeasured
r/datasets100537.38 hours6.77 min4.364 smeasured
r/SaaS10018.46 hours9.03 min3.128 smeasured
r/LocalLLaMA10038.49 hours15.03 min4.551 smeasured
r/redditdev1002,692.91 hours28.14 min7.596 smeasured
r/dataisbeautiful100145.86 hours223.01 min29.406 smeasured
r/Python100851.40 hours406.80 min12.805 smeasured
r/webscraping1001,150.16 hours504.24 min4.407 smeasured

n = 1,000 · as of 2026-09-02

Method: Each row is a single GET against the community listing endpoint at limit=100 sorted by new, run sequentially from one curl client on 2026-09-02 starting 17:26:37 UTC with compression disabled. Window is the difference between the newest and oldest created_utc in the returned page. Age of newest record is the read time minus the newest created_utc, computed once per row rather than once for the pass. Latency is curl's own time_total for that request. The latency column is the weakest claim here: one client, one network path, one moment, and it should not be read as a service level. A re-read returning fewer than 100 items on a limit=100 call, or a newest record materially older than these figures for the same communities, would falsify the pass.
Ten communities chosen to span four orders of magnitude of activity, from a firehose to a quiet developer forum, so the freshness result cannot be blamed on picking only busy places. Every row is one live request.

Two things in that table deserve more attention than the freshness column. The first is that all ten calls returned exactly 100 items, which is the ceiling on this endpoint and is worth internalising early because it shapes everything downstream. The second is the window column, which ranges from 0.47 hours to 2,692.91 hours. The same 100 records covered under half an hour in one community and 112 days in another, a ratio of 5,729.6 to one. If you build a collection loop that pages a fixed number of posts per community per run, you have silently built ten different sampling regimes and you will not notice until somebody compares two communities and gets nonsense.

Bar chart of how old the newest record was in each of nine communities on 2026-09-02, ranging from zero point three five minutes in r/AskReddit to four hundred and six point eight minutes in r/Python

Latency is the number we are least confident in and it is reported plainly for that reason. Median 4.781 seconds, mean 9.08 seconds, fastest 2.854 seconds, slowest 29.406 seconds. That is one client on one machine on one network path making sequential requests on one afternoon, which is exactly the wrong shape of sample for a performance claim. We publish it because a real number with its limits stated is more useful than silence, not because it is a benchmark. If you want that properly, the latency, uptime and cost benchmark is the post that does it with a sampling design built for the question.

How fresh is the newest public Reddit data dump?

Thirty two days old, and that is the freshest it gets. The largest actively maintained public monthly archive publishes as a release feed, so the cadence is not something you have to take anyone's word for. We read it directly through the GitHub API on 2026-09-02 and got fifteen consecutive monthly releases, the newest being the July 2026 data, published on 2026-08-09.

The person who runs the most visible self-hosted archive project describes the cadence plainly, and it is worth reading in his words rather than ours:

"the data from 2025-12 has been released already, it is usually released every month, it just needs to be split and reprocessed for 2025 by watchful1."

Which means that on the day we ran the live pass, nothing in the freshest public dump was dated later than 2026-07-31. Against our read moment that is 32.73 days, or 47,126.6 minutes. Set beside the live median of 12.03 minutes, the ratio is 3,917 to one, derived as 47,126.6 divided by 12.03. Against the fastest community in our basket it is 134,648 to one.

Bar chart of how many days after each covered month ended the corresponding public monthly Reddit dump was published, ranging from six days to eleven days across eight recent releases

None of that is a criticism of the people running those archives. The cadence is regular, the releases arrive, and the median lag from the end of a covered month to its publication is 9 days across all fifteen releases we read, with a minimum of 6 and a maximum of 16. That is a well-run monthly process. The arithmetic is simply that no monthly process can hand you a record from this morning, and a lot of published advice talks about these archives as though it could.

When each monthly public dump actually appeared

ReleaseData covered throughPublishedDays after the month endedSource
2026_072026-07-312026-08-098measured
2026_062026-06-302026-07-1211measured
2026_052026-05-312026-06-1110measured
2026_042026-04-302026-05-109derived
2026_032026-03-312026-04-109measured
2026_022026-02-282026-03-087measured
2026_012026-01-312026-02-076measured
2025_122025-12-312026-01-109derived
2025_112025-11-302025-12-1716measured
2025_102025-10-312025-11-1110measured
2025_092025-09-302025-10-1211measured
2025_082025-08-312025-09-1211measured
2025_072025-07-312025-08-087measured
2025_062025-06-302025-07-076measured
2025_052025-05-312025-06-087measured

n = 15 · as of 2026-09-02

Method: One GET against the GitHub releases API for the arctic_shift repository at per_page=15 on 2026-09-02, HTTP 200. The published date is the release's own published_at field. Days after the month ended is derived as the difference between that timestamp and 23:59:59 UTC on the last day of the month the release tag names, so it is arithmetic on two dates rather than a figure anyone published. Median 9 days, minimum 6, maximum 16. This measures ONE archive's schedule, the one whose maintainer states the cadence publicly, and other archives exist with different coverage. A public dump published on a faster cadence would falsify the comparison, and an August 2026 release appearing after this post is written will move the staleness figure without changing the cadence argument.
Read from the release feed itself rather than from anyone's description of it. The cadence is genuinely regular and genuinely monthly, which is the point: no monthly process can hand you a record from this morning.

The maintainer of the most visible self-hosted archive project said the cadence out loud in January 2026, in a Hacker News thread that reached 286 points, when somebody asked the obvious question:

https://news.ycombinator.com/item?id=46602324

The question was whether the underlying data updates on a cadence or is a fixed historical snapshot, and whether self-hosters would need to re-download for fresh content. The answer, from the project author, was that the December 2025 data had been released and that it is usually released every month, with a further step where a second maintainer splits and reprocesses it. That is the honest, unvarnished description of the pipeline from the person running it, and it is the number we use for the dump side of every comparison in this post.

Five step flow showing why the freshest public monthly archive is a month behind: the month ends, the release is published a median of nine days later, a second maintainer splits it by community, you download it, and you build an index before the first query

The same question keeps getting asked on Reddit itself, which is a decent sign that the answer is not obvious to buyers. On the thread announcing a self-hosted archive tool, one commenter asked whether the data only ran from 2005-06 to 2022-12 and whether new data would be updated at all:

r/pushshift·u/Yekab0f

redarc - A selfhosted Pushshift alternative

00
Open on Reddit

That is the first question a person asks about an archive, and it should be.

There is a second lag inside the first one, and it is the reason the effective staleness is worse than the release date suggests. The monthly release is the raw month. Turning it into the per-community splits that most people actually download is a separate step run by a different maintainer, and on the Hacker News thread the project author noted that the 2025 data still needed to be split and reprocessed at the time he wrote. So the chain is: the month ends, the release appears a median of 9 days later, the split appears some further interval after that, and only then does the practical artefact exist. Every one of those steps is somebody doing unpaid work well, and none of them makes the file newer.

The practical consequence is that you should never date a hybrid corpus by the release you downloaded. Date it by the newest record actually inside the file, check that number rather than assuming it, and store it beside the data. A corpus whose stated coverage comes from a filename rather than from a scan of its own contents is a corpus whose freshness nobody has ever verified. We keep a current view of what replaced the older bulk archives if you want the full landscape of who publishes what, and the Arctic Shift path for agent workloads covers the specific archive whose release feed we measured here.

How much does a stored Reddit row change after you save it?

Half of them changed inside twelve minutes. This is the measurement that turned the argument from a preference into a number, and it is simple enough to reproduce in an afternoon. We took the exact 1,000 post ids from the freshness pass, waited, and re-read all 1,000 through the bulk id endpoint. The gap was 11.4 minutes. 496 of 1,000 records had changed their upvotes or their comments value.

Donut chart showing that of one thousand Reddit post records re-read eleven point four minutes after first capture, four hundred and ninety six had changed at least one field and five hundred and four were unchanged

Broken out, 443 records changed score and 116 changed comment count, with 63 doing both. The largest single score move was plus 458 points on a post in r/technology, and the largest comment move was plus 40 on a post in r/AskReddit. The rate is not uniform: 69 of 100 moved in r/technology and 13 of 100 in r/datasets.

The same 1,000 records, re-read 11.4 minutes later

CommunityRows re-matchedScore changedComment count changedUnchangedLargest score moveSource
r/technology100692331+458measured
r/dataisbeautiful10067931+44measured
r/AskReddit100216139+6measured
r/LocalLLaMA100561439+8measured
r/webscraping10059041+5measured
r/MachineLearning10056044+10measured
r/Python10055045+4measured
r/redditdev10029071+3measured
r/SaaS10018976+6measured
r/datasets10013087+3measured

n = 1,000 · as of 2026-09-02

Method: The 1,000 post ids captured in the freshness pass were re-requested through the bulk id endpoint, one call of 100 comma-separated fullnames per community, on 2026-09-02. T0 was 17:26:37 UTC and T1 was 17:38:03 UTC, a gap of 11.4 minutes. Score and comment count were compared field to field against the values stored at T0. The obvious confound is deliberate and is stated rather than hidden: the first pass sorted by new, so this is a sample of young posts, which are the fastest moving records on the platform. The honest reading is that a stored row about a NEW post decays this fast, not that every row does. A re-read over a comparable gap in which the large majority of rows were unchanged would falsify it. The pass was repeated once more at T2 17:53:47 UTC, a gap of 38.8 minutes from the same T0, which returned 565 changed of 1,000 against 496 at 11.4 minutes, with score movement rising from 443 records to 496 and comment movement from 116 to 165. Two windows moving in the same direction is a considerably stronger position than one window, and a second reading below the first would have indicated a defect in the comparison rather than a settled corpus.
1,000 of 1,000 ids re-matched, so no row is missing from this comparison. A record counts as unchanged only when both its score and its comment count are identical to the first read.

The obvious objection to a single eleven-minute window is that we picked it, so we ran the same comparison again at a longer gap. Re-reading the identical 1,000 ids 38.8 minutes after first capture returned 565 changed records against 435 unchanged, up from 496. Score movement rose from 443 records to 496 and comment movement from 116 to 165, and the largest single score move grew from plus 458 to plus 1,523 on the same community. The curve goes one way, which is what it should do if this is decay rather than noise. A second window returning fewer changed records than the first would have meant our comparison was broken rather than that the data had settled.

The confound here is real and we are going to say it before anyone else does. The first pass sorted by new, so this is a sample of young posts, and young posts are the fastest moving records on the platform. A row about a three year old thread does not behave like this. The honest claim is narrower than the headline: a stored row about a NEW post decays this fast, which matters enormously if your pipeline collects new posts, which is what almost every pipeline does.

Bar chart of how many records out of one hundred changed a field in eleven point four minutes, per community, from sixty nine in r/technology down to thirteen in r/datasets

The implication for dataset design is direct. Any field that can move needs a refresh path or a timestamp saying when it was true, and preferably both. A score column with no as-of time is not data, it is a rumour with a decimal point. This is why the collection design later in this post has two loops rather than one, and why bulk fetching by id is the endpoint that does the unglamorous half of the work.

What does a Reddit post record contain, field by field?

Twenty two fields at the top level, and they were identical across all 1,000 records we read. That consistency is worth stating on its own, because a schema that varies by community or by post type is a genuine engineering problem and this one did not vary at all in our sample.

ONE POST RECORD, READ LIVE

The 22 fields a listing call hands you per post

Community listing, 2026-09-02

The fields are author, author_info, comments, created, created_utc, crosspost_origin, id, is_crosspost, is_self, link_url, locked, name, over_18, permalink, spoiler, stickied, subreddit, text, title, upvote_ratio, upvotes and url. The author_info field is itself an object carrying four more, fullname, premium, is_blocked and flair, so a post is 26 leaf fields if you count that way. Payload worked out at 1,620.8 bytes per record, derived from 1,620,777 response bytes across 1,000 records with compression disabled.

Donut chart classifying the twenty two top-level fields on a Reddit post record into identity and origin, content and links, state flags, engagement, type and relationship, and timing

Grouping those 22 by what they do is an editorial call rather than a measurement, so treat the split as our classification rather than the platform's: five identity and origin fields, five content and link fields, four moderation state flags, three engagement fields, three type and relationship fields, and two timing fields. What that grouping makes obvious is how much of a post record is state rather than content. Seven of the 22 fields describe the current condition of the post rather than what it says, and every one of those seven is a field that can change after you store it.

There is a second thing that grouping reveals, and it is the whole reason the comparison in this post is not just about dates. If a field is not in a file, you cannot get it out of the file. A person on the archive threads found that the hard way and asked about it directly, having noticed that the Posts rows in a monthly dump did not carry a removed field even though he collected it himself in his own process. That is not a complaint about the archive. It is the structural point: an export carries the fields whoever built it chose to carry, and a re-read of a live source carries whatever the source returns today.

Why does a comment record carry three times as many fields as a post?

Because comments live inside a moderation and threading system that posts mostly sit above. A comment record read from the comment tree endpoint on 2026-09-02 carried 70 top-level fields, against a post's 22, a user profile's 19 and a community about record's 17.

What each record type actually carries, counted off live responses

Record typeFields returnedEndpoint readWhat the extra fields buy youSource
Post22Community listingEngagement, moderation state, crosspost lineage and authorship in one objectmeasured
Comment70Post comment treeThread structure, award state, edit and removal markers, moderation fieldsmeasured
User19User profileAccount age and split karma totals, the only real cohort variable availablemeasured
Community17Community about recordSubscriber count, creation date, type and description for sizingmeasured

n = 4 · as of 2026-09-02

Method: Four requests on 2026-09-02: one community listing at limit=100 whose 1,000 records were checked for key-set identity and were identical in all 1,000, one comment tree read at limit=50, one community about record, and one user profile. Field counts are len of the response object's keys, taken with no transformation. The comment count of 70 is the union and the median across the returned comments, which were equal, so no comment in that sample carried a reduced shape. A response carrying a different key set for the same record type on a later read would falsify these counts, and that is worth re-checking before you pin a schema to them.
Counts are of top-level keys on the live response. The post record additionally nests four fields inside author_info, so a post is 26 leaf fields rather than 22 if you count that way, and the table states the top-level number to stay comparable across types.

Statistic panel showing fields returned per record type, twenty two for a post, seventy for a comment, nineteen for a user and seventeen for a community, all counted off live responses

The extra 48 fields on a comment are not padding. They fall into five families, none of which a post record needs:

  • Threading. parent_id and the reply structure, which is what lets you rebuild a conversation rather than a bag of text.
  • Edit and removal state. edited, removal_reason, collapsed_reason and the approval fields, all of which move after the record is written.
  • Moderator speech. distinguished and the mod-note fields, which mark which comments carry authority.
  • Award and flair machinery. Counts and template ids that describe how a community decorated the comment.
  • Author context. Flair type, richtext and CSS class, which are community-scoped rather than account-scoped.

The point of that list is not the field names. They carry the parent relationship that lets you reconstruct a thread, the edit marker, the removal and approval state, the distinguished flag that marks moderator speech, award counts, collapse reasons and the author flair machinery. If your dataset is about discussion rather than about submissions, that is the record type you want, and it changes the storage maths: a comment corpus is both wider and far more numerous than a post corpus over the same window.

This is also the clearest single argument against treating any Reddit corpus as interchangeable with any other. Two datasets both called "Reddit data" can differ by a factor of three in how much they know about each row, and a schema mismatch on ingestion is the most common way that difference becomes somebody's afternoon. The comment endpoint guide covers the tree structure, and comment search covers finding comments across communities rather than inside one thread.

The practical consequence for a build is that you should decide which record type is your spine before you write a schema. A posts-spine corpus with comments attached is a different shape from a comments-spine corpus with post metadata denormalised onto each row, and converting between them later means a full rewrite of every query you have written in the meantime.

Start building with Redditapis

Reads $0.002, votes $0.005, writes $0.012, DMs $0.025. $0.50 free credits.

How many records does one call return, and how far back does it reach?

One hundred, always, and how far back those hundred reach depends entirely on the community. This is the single most misunderstood property of listing endpoints and it breaks more analyses than any other, because the count is fixed and the window is not.

Measured on 2026-09-02, the same 100-post page at limit=100 covered 0.47 hours in r/AskReddit and 2,692.91 hours in r/redditdev. That is 28 minutes against 112 days from an identical request. The median across the ten was 276.71 hours. If you build a job that pulls one page per community per hour, you are oversampling the quiet communities by a factor in the thousands and undersampling the fast ones so badly that you miss most of what happens.

The fix is to sample by time window rather than by record count. Decide the period you care about, page until the oldest record in your last page precedes it, and record how many calls that took. That figure, calls per community per window, is the number you actually need for capacity planning, and it is different for every community in your basket.

That walkthrough is a good illustration of the older shape of this work, pulling Reddit data through an R package, and it is also a small demonstration of the staleness problem in a different medium: it carries a 2023 update in its own title because the thing it teaches keeps moving underneath it. Tutorials go stale the same way corpora do.

How do you page through more than one hundred posts?

With the cursor the response hands you, the after value, passed back verbatim on the next request. We tested it five pages deep against r/technology on 2026-09-02 and it walked cleanly: 500 unique ids, no duplicates, no gaps, 24.14 seconds of wall clock, and a non-null cursor still present on page five.

Five sequential pages against one community, timed

PageItems returnedCumulative unique idsLatencyResponse bytesSource
11001004.129 s83,868measured
21002004.267 s84,474measured
31003004.774 s84,413measured
41004005.480 s84,199measured
51005005.420 s83,786measured

n = 500 · as of 2026-09-02

Method: Five sequential GETs against the community listing endpoint for r/technology at limit=100 sorted by new on 2026-09-02 starting 17:44:48 UTC, each passing the previous response's after cursor back verbatim. Wall clock for all five was 24.14 seconds, which is 20.71 records per second derived as 500 divided by 24.14. The 500 records covered 167.92 hours. Latency creeping upward across the five pages is real but the sample is far too small to call it a trend, and it is reported rather than explained. A page returning fewer than 100 items before the cursor ran out, or a duplicate id across pages, would mean the cursor is not walking cleanly and would falsify this.
Cumulative unique ids rises by exactly 100 per page, so the cursor is walking cleanly with no overlap and no gap. Page 5 still returned a non-null cursor, so the depth here is a stopping choice rather than a limit.

Statistic panel showing five sequential pages returned five hundred unique records in twenty four point one four seconds, which is twenty point seven one records per second, covering one hundred and sixty seven point nine hours

Twenty point seven one records per second is the honest throughput figure for sequential paging from one client. It is not fast, and it should not be, because a listing endpoint is a read against a live system rather than a bulk export. What it is, is predictable: a hundred records per call, roughly five seconds per call, and a cursor that keeps working. For a corpus of a hundred thousand posts that is a thousand calls and something under two hours of wall clock, which most people find surprisingly manageable once they have stopped imagining they need the whole platform.

The two mistakes we see most often with cursors are worth naming. The first is treating the cursor as an offset and trying to compute it, which does not work because it is opaque and the endpoint documentation says so. The second is discarding it between runs, which turns every scheduled job into a first page and guarantees you re-collect the same recent records forever while the older ones you wanted stay out of reach. Store the cursor with the job state. The pagination guide covers both in detail, and the rate limit guide covers how fast you can reasonably run the loop.

One more property worth knowing before you design around it: latency crept up across our five pages, from 4.129 seconds on page one to 5.420 seconds on page five. Five samples is nowhere near enough to call that a trend and we are not calling it one. It is in the table because it is what we measured, and because if you see the same shape at page fifty it is worth investigating rather than assuming.

What happens to a Reddit record after a year?

Some of it goes away, and this is the column where a static archive genuinely beats a live read. We pulled the top 100 posts of the past year from each of the same ten communities on 2026-09-02, 1,000 records in total, all HTTP 200. 25 of those 1,000 now return a deleted or empty author. 7 are locked. None returned a removal marker in the body text, which is a null result worth stating rather than omitting.

What a year does to a record, read through the live API today

CommunityTop posts readAuthor no longer presentLocked nowOldest post in sampleSource
r/technology10092364.2 daysmeasured
r/Python10040364.2 daysmeasured
r/AskReddit10044358.9 daysmeasured
r/dataisbeautiful10020363.2 daysmeasured
r/redditdev10021363.4 daysmeasured
r/LocalLLaMA10020361.1 daysmeasured
r/MachineLearning10010355.0 daysmeasured
r/datasets10010361.0 daysmeasured
r/SaaS10000360.6 daysmeasured
r/webscraping10000363.9 daysmeasured

n = 1,000 · as of 2026-09-02

Method: One GET per community against the community top endpoint at t=year and limit=100 on 2026-09-02, all 10 returning HTTP 200 and 100 items. Author no longer present counts records whose author field is empty or marks a removed account. Locked now counts the locked flag as it stands today. 0 of 1,000 returned a removed marker in the body text, which is worth stating because it is a null result rather than an omission. The direction of this finding matters and is easy to misread: it measures what the LIVE record says today, not what an archive says. It does not show the API losing data, it shows the API reflecting a deletion the platform honoured.
This is the column where the archive wins. A dump written a year ago still carries the author names that these 25 records no longer return, and any honest comparison has to say so.

Bar chart of how many of one hundred top posts from the past year no longer name an author, per community, from nine in r/technology down to one in r/MachineLearning and r/datasets

Read the direction of that finding carefully, because it is easy to get backwards. This does not show the API losing data. It shows the API reflecting deletions the platform honoured, which is the correct behaviour and in most jurisdictions the required one. An archive written a year ago holds the original author name because it was written before the deletion, and that is exactly why an archive is the right tool for some questions and the wrong tool for others.

Somebody on Hacker News made this case better than we can:

"Reddit is becoming maddening to use because half the old links I click have comments overwritten with garbage out of protest for something. Ironically the original content is available in these archives (which are used for AI training) but now missing for actual users like me just trying to figure out how someone fixed their printer driver 2 years ago."

That comment is worth reading in full alongside the thread it sits in:

https://news.ycombinator.com/item?id=46606273

That is a real cost of a live-only pipeline and it deserves to sit in the post rather than in a footnote. The corollary is also worth stating: if your dataset needs to preserve content that authors later remove, you are making a decision with consequences beyond engineering, and the right time to think about it is before you build rather than after somebody asks.

The 9-of-100 figure in r/technology against 0-of-100 in r/SaaS and r/webscraping is a real spread and we do not have a confident explanation for it. Larger, more contentious communities plausibly generate more account deletions, but ten communities is far too small a sample to assert that, so it is reported as an observation rather than a finding.

Which endpoint should you point at which part of your dataset?

Five surfaces, and each one answers a different question. Choosing wrongly is the most common reason a build takes three times longer than it should, because the wrong endpoint makes you page for data that another endpoint would have handed you in one call.

Numbered list of six Reddit API routes showing what each returns and what each is best for, covering community listings, keyword search, bulk id lookup, comment trees, community profiles and author history

In short:

  • Community listing for the spine of the corpus, up to 100 posts per call with a cursor.
  • Search for topic corpora that span communities rather than sit inside one.
  • Bulk id for the refresh loop, up to 100 record ids per call.
  • Comment tree for discussion work, 70 fields per comment record.
  • Community about for sizing metadata, 17 fields in one object.

The community listing endpoint is the spine. It returns up to 100 posts per call with a cursor, and it is what you page on a schedule to keep a community's history filling in. The search endpoint is for topic corpora that span communities, and it is the right tool when your dataset is defined by a subject rather than by a place. The bulk id endpoint takes up to 100 comma-separated record ids in a single call and hands back their current state, which makes it the refresh loop. The comment tree endpoint gives you the 70-field comment records for a thread. The community about record gives you 17 fields of metadata for sizing.

THE TWO LOOPS A LIVING DATASET NEEDS

Where each endpoint feeds the corpus

Author history is the fifth surface and it is the one people forget. Reading an account's own submissions or comments is how you build cohort and overlap analysis, and it is the only route to questions like which other communities the people posting here also post in. It is also the most expensive per unit of insight, because it is one call per account, so budget it deliberately rather than discovering it mid-build.

There is a sixth thing that is not an endpoint at all and belongs in this list anyway: a push channel. If your dataset needs to react to new content rather than merely accumulate it, polling is the wrong shape and the webhook and polling comparison covers the trade properly. Monitoring with webhooks is the build guide for that half.

How do you actually build the collection loop?

Two loops, running on different cadences, writing to the same table. Almost every home-built Reddit pipeline we have seen ships the first one and skips the second, which is why their engagement columns quietly drift away from reality.

Five step flow showing the collection loop from an empty table to a living corpus: pick the window, page with the cursor, upsert by id, re-read the movers, and stamp every row with an as-of time

The collection loop pages new posts. Pick the time window first, page until the oldest record in the page predates your watermark, upsert every record keyed on its id, and store the cursor with the job state so the next run resumes rather than restarts. The refresh loop takes ids you already hold, batches them a hundred at a time into the bulk id endpoint, and writes the current score and comment count back. How often you run the refresh loop is a real design decision and our mutability measurement gives you the input for it: at 11.4 minutes, half of a fresh cohort had already moved.

A reasonable default that falls out of that number is to refresh aggressively for the first day of a record's life, then back off sharply. A record's score moves most in its first hours and then settles, so a fixed refresh interval either wastes most of its calls on old records or misses most of the movement on new ones. Age-tiered refresh is more code and considerably fewer calls.

The person who built the original large Reddit archive described his own first collection method in a public thread in November 2025, and it is a useful reality check on how exotic any of this is:

r/redditdev·u/One_Performance_9259

Is there a way to (legally) scrape more than 2000 posts on Reddit?

00
Open on Reddit

"You can ask for posts by their ids going backwards. You can't specify a specific subreddit with this method but you can go back as far as you want. When I created Pushshift, my first large Reddit dump was done by using the sequential IDs directly."

He walked the sequential record ids backwards. The canonical bulk archive that half this SERP is descended from was itself assembled by reading a live API in a loop, which is the strongest possible argument that the archive lane and the API lane were never really two different lanes. One of them just got exported to a file.

For the code shape, the Python tutorial walks the request layer, and the analytics dashboard build walks the storage and rollup layer with a schema you can copy. If you would rather not write either, the build versus buy comparison is the honest version of that decision including the cases where building wins.

How should you store a dataset whose rows keep moving?

Append the history, project the current state, and never let a mutable field sit in a table without a timestamp beside it. Three objects do it: a records table for what never changes, an observations table for what does, and a current view that joins the latest observation onto each record. That is the whole design, and it is boring on purpose.

Architecture diagram of four layers for a self-updating Reddit dataset: collection with listing, search and refresh workers, normalisation with field mapping and as-of stamping, storage with append-only history and a current-state view, and a query layer

The shape, in the smallest form that works:

records      (id PK, subreddit, author_first_seen, created_utc,
              title, body, first_collected_at)
observations (record_id FK, observed_at, upvotes, comments,
              upvote_ratio, locked)
current      VIEW: records JOIN latest observation per record_id

The concrete version: one table holds immutable facts about a record, the id, the author as first seen, the created timestamp, the title and body as first collected, the community. A second table holds observations, one row per read, carrying the record id, the observed score, the observed comment count, the observed lock state and the time of the read. A view joins the latest observation onto each record to give you the current-state table everyone actually queries.

That shape costs you one extra table and buys three things that are genuinely hard to retrofit. You can answer questions about trajectory rather than only about state, which is where most of the interesting analysis lives. You can date every figure you publish, which is what makes a dataset citable rather than merely large. And when a field turns out to have been wrong, you can see when it changed instead of guessing.

The alternative, which is what most pipelines do, is a single wide table that gets overwritten in place. It is simpler for a week. Then somebody asks how fast this post grew, and the honest answer is that the information was collected and then deliberately discarded, four hundred and forty three times in eleven minutes in our sample alone.

Storage volume is not the constraint people expect. At 1,620.8 bytes per post record, a million posts is about 1.6 GB of raw JSON, and the observation table is far smaller per row because it holds five columns rather than 22. A comment corpus is a different matter, given 70 fields per record and a much higher record count per community, and that is the case where you should think about column stores before you think about anything else.

The cheapest Reddit API. Try it free.

Reads from $0.002 per call. $0.50 free credits. No credit card required.

What does a static dump still do better?

Three things, and pretending otherwise would make this post worse. A static archive beats a live read on history, on completeness of the record after somebody deletes it, and on cost per unit of volume once you are working at the scale of billions of rows rather than millions. Each of those is a real advantage and each one is measurable, so they are worth stating precisely rather than conceding vaguely.

  • History. One scan over local storage beats paging a live endpoint backwards for years, and for deep history the cursor will not take you there in practice anyway.
  • The deleted record. 25 of 1,000 year-old top posts no longer name an author through the live API. A file written before those deletions still does.
  • Cost per unit of volume. At 20.71 records per second per client, a billion-row corpus is not something you page for.

THE SAME SIX QUESTIONS, ASKED OF BOTH SOURCES

What each source can and cannot answer

Live managed APIMonthly public dump
Newest record available12.03 min old, median of 1032.73 days old at best
Current score and comment countYes, on every readFrozen at export time
A field nobody exportedRequest it againNot recoverable from the file
Storage before the first queryNone, query on demandHundreds of gigabytes
Small or new communitiesAny community by nameTop splits only
Author of a since-deleted postNo, reflects the deletionYes, holds the original
Both freshness figures were measured on 2026-09-02: the API side across ten communities and 1,000 posts, the dump side from the release feed's own published dates. The last row is the archive winning, and it is in the table for that reason.

History is the obvious one. If your question is about 2014, a live listing endpoint is a bad way to reach it: you would page for a very long time, and for many communities the cursor will not take you that far in practice. An archive scan answers the same question in one pass over local storage. The academic corpus loaders and precomputed embedding sets that rank on this term exist precisely because researchers needed exactly that and building it live was never the right shape.

Completeness of the deleted record is the finding from our churn pass, running the other way. Twenty five of a thousand year-old top posts no longer name an author through the live API. An archive written before those deletions still does, which is simultaneously the archive's strongest technical argument and the source of every ethical question anyone has ever asked about these corpora.

Cost per unit of volume is real too. If you want billions of records, paging a live API at roughly twenty one records per second per client is not the tool, and nobody should pretend it is. That is what the AI training corpus guide exists to cover, and its answer is a hybrid: bulk archive for the historical base, live API for the current tail, with a documented schema alignment between them. The same shape applies to retrieval-augmented generation over Reddit, where the historical base is a one-time cost and the freshness of the tail is the whole product.

What a dump does not do better is anything with a tense in the present. The comparison grid above is not a scorecard with a winner. It is a routing table.

The hybrid shape deserves one more sentence because it is what most serious builds converge on and it is rarely described honestly. You take the archive once, for the base, and you accept its cutoff as a known boundary rather than pretending it is the present. You run the live loop forward from that boundary. The hard part is neither half, it is the seam: the two sources use different field names for the same facts, they disagree about deleted records by construction, and a naive union produces duplicate rows for every record that appears in both. Deduplicate on the record id, prefer the live row for any mutable field, keep the archive row for anything the live read no longer returns, and write down which source each column came from. That last step is the one people skip, and it is the one that makes the resulting corpus explicable a year later.

What does a Reddit dataset cost you to hold, either way?

Less than people expect on the live side, and considerably more than the download page implies on the archive side, because the download is only the first bill. A post record is 1,620.8 bytes, so a million posts is roughly 1.6 GB of raw JSON, which is a laptop-sized problem. A bulk corpus is a terabyte-sized one, and the storage is only the first of three costs it carries.

Comparison grid asking six questions of a live managed API and a monthly public dump, covering newest record available, current score and comment count, fields you can add later, storage before the first query, coverage of small communities, and whether the author of a deleted post is still present

On the live side, the arithmetic is straightforward. 1,620.8 bytes per post record means a hundred thousand posts is roughly 162 MB of raw JSON, and a million is about 1.6 GB. Collection at 20.71 records per second from one client puts that million at roughly 13.4 hours of sequential wall clock, derived as 1,000,000 divided by 20.71 divided by 3,600. Both of those are laptop-sized problems, and neither requires you to hold anything you did not ask for.

On the archive side, the first bill is bandwidth and disk and it is large. The threads are full of people meeting it. One person coming to the torrents for the first time put it like this:

"Hey guys i have never worked with Torrents. Is there a way to avoid downloading ALL comments and submissions? It show that it would be approximatly 2 TB which i dont have on my computer left. I only need submissions and comments from March 2021 and March 2022.."

He needed two months and was quoted two terabytes. Another, on a thread announcing a full submission corpus, said he wished he owned better hardware so he could examine the data as a whole and that so far he had only been able to look at it in parts:

r/datasets·u/Stuck_In_the_Matrix

Full Reddit Submission Corpus now available (2006 thru August 2015)

00
Open on Reddit

The second bill is the index, and it is the one nobody quotes. A file is not a dataset until something can query it. On the Hacker News thread, a commenter asked directly whether there was any cheap way to search, noting that he already owned a large technical archive that was useless without search and that he did not want to grep everything. That is the real cost structure of a bulk corpus: download, then storage, then an index, then the operational work of keeping all three alive.

The per-community splits published on Academic Torrents exist to cut the first bill, and they are genuinely useful, but they carry their own limit that people discover late. As one commenter on a 2025 r/datasets thread put it while recommending exactly that route, the dump torrents cover only a limited number of subreddits. Coverage of the top N communities is not coverage.

If your comparison is against a managed API rather than against your own collection code, the price per call is the other half of the sum and the pricing breakdown covers it. The point of this section is narrower: the free file is not free, and the two costs it hides are the ones that arrive after you have already committed.

Collecting publicly visible content through the data API under Reddit's own terms is the documented route, and it is the one every measurement in this post used. The bulk archives sit on different footing, and you do not have to take our word for that because the people who maintain them say so in public.

The Reddit Data API Terms govern programmatic collection, and the API documentation is the reference for what each route returns. That is the surface you are working against when you build the live version, and it is a surface with a stated contract.

The archive position is more complicated and is worth quoting rather than paraphrasing. The person who maintains the per-community dump splits wrote this on a 2023 thread about exactly that question:

"I agree that reddit doesn't really have any legal methods of stopping people from just having the data. It's entirely possible they will try to sue people who make money off the data, especially lots of money. But they really don't care about research projects."

"That said, it is definitely unauthorized. Pushshift did not have permission from reddit to collect the data. Many, many other research projects have used it anyway, but it's still unauthorized." On a 2023 thread specifically about the legality of using the data dumps going forward, the person who maintains the per-community splits wrote that Reddit does not really have any legal methods of stopping people from simply having the data, that they probably do not care about research projects, and then added, plainly, that it is definitely unauthorised, that the archive did not have permission from Reddit to collect the data, and that many research projects have used it anyway. Another commenter in the same thread made the copyright argument in the opposite direction, that the content belongs to the people who wrote it rather than to Reddit.

Both of those views can be held by reasonable people and neither of them is legal advice, including when we repeat them. What matters for a build decision is the asymmetry: one route has a published contract you can read and comply with, and the other has a maintainer describing it as unauthorised. If your dataset is going into anything commercial, that asymmetry is the whole decision. We cover it at length in the legal read on collecting Reddit data and in what commercial use actually requires.

There is a third consideration that is not legal and matters anyway. Our churn pass found 25 of 1,000 year-old posts whose author is no longer returned. A live pipeline honours those deletions automatically because it re-reads. A stored corpus honours them only if you build something that does, and building that something is a choice you make once and then live with.

How big a sample do you need before the numbers mean anything?

Decide the window first, then page until you have covered it, and publish the window next to every figure. Sample size is the wrong question and it is the one everybody asks.

Numbered list of five questions no archived Reddit record can answer, covering current score, whether the author is still present, whether the thread was locked since, a field nobody exported, and anything from the last month

Our own freshness pass is the demonstration. Every one of the ten calls returned exactly 100 records, an identical sample size by every conventional measure, and those ten identical samples covered periods ranging from 0.47 hours to 2,692.91 hours. Comparing r/AskReddit and r/redditdev on those two pages is comparing 28 minutes against 112 days. No statistical test rescues that, and no amount of extra rows fixes it, because the defect is in the sampling frame rather than in the count.

The habit that fixes it is small. Every table you publish carries the window and the read date, and every chart caption says the same. Our tables carry asOf and sampleN for exactly this reason, and the methodology field on each one names what would falsify the result. That last part is the discipline that costs the most and pays back the most: if you cannot write down what result would prove you wrong, you have not made a measurement, you have made an assertion with a number in it.

There is a second sampling trap specific to this platform and it is worth naming because it is invisible. Automated accounts post on fixed schedules, so their contributions land in the same hour bucket every day. Any activity histogram built without filtering them describes a scheduler rather than a community. Our companion work on what the API tells you about an audience measured that directly and found the apparent peak posting hour of a large community moving by twelve hours once automation was filtered out. If your dataset is about human behaviour, the author column needs a filter before the timestamp column means anything.

For the sizing half of the question, the ranked list of communities by API-measured size is the place to start, and the subreddit analytics comparison covers what you can buy instead of measuring yourself.

What breaks first when you build this yourself?

The refresh loop, because it is invisible when it is missing. Everything else in a Reddit collection pipeline fails loudly and therefore gets fixed in the first week: a broken cursor stops the row count growing, a schema mismatch fails on insert, a rate limit returns a status code you can read. The refresh loop fails silently, and a silent failure in a data pipeline is the expensive kind.

Node graph showing six Reddit API surfaces feeding one stored corpus, with the listing endpoint supplying new rows and ids, the bulk id endpoint supplying updates, and search, comments and community metadata feeding the same store

Ranked by how long it takes to notice:

  • Missing cursor. Minutes. The row count stops growing and you see it on the first run.
  • Schema mismatch. Minutes. The insert fails with a type error.
  • Rate limit. Hours. An HTTP status code you can read and back off from.
  • Missing refresh loop. Never, until somebody compares your numbers to the site.
  • Pinned input window. Never, because the job keeps succeeding against a source that stopped moving.

Here is the same list as prose. A missing cursor breaks immediately and obviously, because your job re-collects the same first page every run and the row count stops growing. A schema mismatch breaks on the first insert. A rate limit breaks with an HTTP status you can read. All three of those get fixed because they announce themselves.

A missing refresh loop announces nothing. The rows are there, the counts look right, the dashboard renders, and the engagement columns are simply a snapshot of the moment each row happened to be collected. In our measurement, 496 of 1,000 rows were already wrong 11.4 minutes in. After a day, a naive corpus of new posts is a corpus of first-observation values wearing the label "score". Nobody notices until somebody compares your numbers to the site.

The second failure by time-to-notice is the pinned window. A collection job that hardcodes a start date, or that reads the newest available file rather than asserting the file is new, will keep running successfully forever against an input that stopped moving. The producer looks healthy, the consumer looks healthy, and the dataset stops growing at a date nobody chose. The defence is one line: make an empty or unchanged input a hard error rather than a quiet no-op, and print the input you actually read on every run.

Third is the silent partial. A collection loop that swallows exceptions to keep going will happily record a run as complete when three of ten communities returned nothing. Count what you scanned against what you meant to scan, print both, and fail when they differ. That is the same discipline as the sample-window rule, applied to your own job rather than to your analysis.

The practitioners on the archive threads have their own version of this list, and it is mostly about the import rather than the collection. One described the design as stream everything or gather every N minutes and store everything in a database, then noted that importing from the bulk archive would be the painful half because the dataset is enormous. That split, easy live collection and painful historical import, matches what we see, and it is a good argument for doing the live half first and deciding later whether you actually need the history.

How do you check whether your own dataset has gone stale?

Run three assertions on a schedule and make each one fatal. Not a warning, not a dashboard tile, fatal, because a stale dataset looks exactly like a healthy one from the outside.

The first assertion is on the newest record. Read the maximum created_utc in your store, compare it to now, and fail if the gap exceeds what your collection cadence should permit. Our live pass gives you a calibration point: a median newest record 12.03 minutes old across ten communities, so a store whose newest row is a day old is not lagging, it is broken. Run the assertion per community rather than globally, because one dead community hides inside a healthy aggregate indefinitely.

The second assertion is on mutable fields. Take a random hundred records you hold, re-read them through the bulk id endpoint, and compare. A pipeline in good health will show some drift, because that is the nature of the data. A pipeline whose refresh loop has silently stopped will show drift that grows monotonically every time you run the check, and that pattern is the signal. Zero drift on a sample of new posts is also a finding, and not a good one: our measurement says roughly half of a fresh cohort should move inside twelve minutes, so a clean zero means the check is not checking.

The third assertion is on coverage. Count the communities you collected in the last window against the communities you meant to collect, and print both numbers. A count with no denominator cannot be wrong, which is what makes it useless. This is the same rule as the sampling one and it is broken the same way, by reporting a total that sounds large instead of a fraction that would look small.

For the freshness of the sources themselves rather than of your store, the archive release feed is public and readable in one request, which is how we measured the cadence in this post. The release feed tells you the newest month available, and the self-hosted archive project documents the import path. If you run a hybrid, checking that feed monthly is a five-second job that stops your historical base drifting a year behind without anyone noticing.

The failure mode this whole section exists to prevent has a shape, and researchers hit it constantly. Somebody builds a corpus, publishes work from it, and the corpus keeps being cited long after its last row. The static datasets that rank for this term are a museum of exactly that: a GitHub corpus from 2016, a catalog entry wrapping a fixed record count, a Kaggle listing with no refresh path. None of them is dishonest. Each one simply stopped, and nothing on the page says when.

The people who used the archive when it did update were clear about what they lost when it stopped:

Adarsh Mathew

Adarsh Mathew

@adarshmathew92

Looks like the Pushshift archive is dead. Enabler of so much interesting research, including mine. Thanks for everything, @jasonbaumgartne. Your work was invaluable, even if some entities chose to exploit it.

And the description of what the thing actually was, from someone watching it end, is the most precise sentence anyone has written about this whole subject:

Reddit Lies

Reddit Lies

@reddit_lies

Reddit just terminated Pushshift's access to Reddit's API. Pushshift was a constantly updating archive of Reddit comments and posts. This intentional obfuscation of data will have dire consequences for the platform. Watchdog remains unaffected. https://t.co/RzE7yjrfDT

The word that matters there is "constantly updating". What ended was not the file. It was the refresh.

Verdict

Build the live one, and keep a copy of the archive if your questions have a past tense. That is the recommendation the measurements support, and the reason is a gap of three orders of magnitude on freshness against a single genuine advantage the archive holds on deleted records. Both halves of that sentence were measured on the same day, and both are reported below with the sample sizes and the conditions that would falsify them.

The measurement is unambiguous on freshness. One call per community across ten communities on 2026-09-02 returned a newest record with a median age of 12.03 minutes, and the freshest was 21 seconds old. The freshest public monthly dump that day could contain nothing later than 2026-07-31, which is 32.73 days back, because those releases publish a median of 9 days after their covered month ends across the 15 consecutive releases we read. That is a ratio of 3,917 to one on the median, and it is a property of a monthly cadence rather than a failure of anyone's engineering.

The measurement is equally unambiguous on why that gap compounds. 496 of 1,000 records changed score or comment count in 11.4 minutes, 443 on score and 116 on comments, with a single post moving 458 points. A row you exported yesterday is not a slightly older version of the truth about a new post, it is a different number wearing the same column name. Re-read at 38.8 minutes rather than 11.4, the figure rose to 565 of 1,000 and the largest single move to plus 1,523 points, so the decay is monotone rather than a quirk of one short window.

Against that, the archive holds one thing the live read cannot. 25 of 1,000 posts from the past year no longer name an author through the API, concentrated at 9 of 100 in r/technology. If you need what the record said before somebody removed it, the file is the only place it exists, and that fact carries obligations as well as capabilities.

The build itself is smaller than its reputation. 100 records per call, 22 fields per post record and 70 per comment, 1,620.8 bytes per record, 20.71 records per second paging sequentially from one client, a cursor that walked five pages deep with 500 unique ids and no duplicates. Two loops, one for collection and one for refresh, an append-only observations table, and an as-of stamp on every mutable field. That is the entire design, and none of it is exotic.

You can run every measurement in this post against the documented endpoints on any plan, or sign up and reproduce the whole pass in an afternoon. If you do it on a different day and the median newest record comes back materially older than twelve minutes, that is a finding worth having and this post would need updating. The parts most likely to move first are the archive's newest release, which will advance by a month while the cadence stays the same, and the latency figures, which were one client on one afternoon and were never a benchmark. Everything else is arithmetic on 3,000 records we read out loud, and it is written down so somebody can check it. For the wider view of what the data API returns beyond posts, the data API overview, the user endpoint and the search tutorial are the next three stops, and PRAW remains the reference for how the same response shapes look from a Python client.

Where these numbers come from.

Each row is a figure in this post and the artefact it was read from. Reddit's access rules and the third-party archives around them keep moving, so check the date on a source before you build against it.

Reddit Data API documentation
The endpoint reference for listings, about records and user profiles. Retrieved 2026-09-02, HTTP 200.
Reddit Data API Terms
Governs programmatic collection of public Reddit data. Retrieved 2026-09-02, HTTP 200.
Arctic Shift monthly releases
The public monthly dump release feed. Read through the GitHub API on 2026-09-02, HTTP 200: 15 consecutive releases from 2025_05 to 2026_07, newest published 2026-08-09.
Show HN: Self-host Reddit, 2.38B posts, works offline, yours forever
286 points, 2026-01-13. The thread where the maintainer states the monthly cadence on the record. Retrieved 2026-09-02, HTTP 200.
The maintainer on release cadence
The specific comment: the data from 2025-12 had been released, and it is usually released every month. Retrieved 2026-09-02, HTTP 200.
redd-archiver
The self-hosted archive project itself. Repository metadata read through the GitHub API on 2026-09-02: created 2025-12-28, last pushed 2026-08-24, 343 stars.
Per-community dump splits on Academic Torrents
The per-subreddit splits that make a bulk archive usable without a full download. Retrieved 2026-09-02, HTTP 200.
ConvoKit Reddit Corpus documentation
The academic NLP toolkit that ranks second for the head term. A loader for a fixed corpus. Retrieved 2026-09-02, HTTP 200.
SNAP Reddit user and subreddit embeddings
Precomputed embeddings over a fixed historical crawl, ranked fourth for the head term. Retrieved 2026-09-02, HTTP 200.
TensorFlow Datasets catalog entry for Reddit
A catalog wrapper over a fixed corpus with a stated record count, ranked ninth. Retrieved 2026-09-02, HTTP 200.
reddit-dataset on GitHub
A static scrape checked into git, ranked fifth for the head term. The clearest example of a corpus with no refresh path. Retrieved 2026-09-02, HTTP 200.
PRAW documentation
The Python client whose attribute surface mirrors the API response shape. Retrieved 2026-09-02, HTTP 200.

Frequently asked questions.

One built from live API calls. We measured both on 2026-09-02. A single listing call returned a newest record with a median age of 12.03 minutes across ten communities, and 21 seconds in the fastest one. The freshest public monthly dump on the same day covered July 2026, so nothing in it was newer than 2026-07-31, which is 32.73 days old at that moment. That gap is not a flaw in the archives. They publish a median of 9 days after the month ends, measured across 15 consecutive releases, and a monthly cadence cannot produce a record from this morning. See the archive landscape for who publishes what.

22 at the top level, identical across all 1,000 post records we read on 2026-09-02: author, author_info, comments, created, created_utc, crosspost_origin, id, is_crosspost, is_self, link_url, locked, name, over_18, permalink, spoiler, stickied, subreddit, text, title, upvote_ratio, upvotes and url. The author_info object nests four more, so 26 leaf fields per post. A comment record carries 70 fields, a user record 19, and a community about record 17. See what the comment endpoint returns for the comment shape in detail.

Faster than most pipelines assume. We captured 1,000 new posts across ten communities, then re-read the exact same ids 11.4 minutes later through the bulk id endpoint. 496 of 1,000 records had changed their score or their comment count, 443 on score and 116 on comments, with a largest single move of plus 458 points. The rate varied by community, from 13 of 100 in r/datasets to 69 of 100 in r/technology. That sample is deliberately young posts, which move fastest, and the post says so rather than generalising it to every row. See how to build a dashboard that tracks this over time.

For historical work, yes, and for one thing the live API genuinely cannot do. An archive written a year ago holds the author name and body text that the live record no longer shows after a deletion. We measured that: 25 of 1,000 top posts from the past year now return a deleted or empty author through the API, concentrated in r/technology at 9 of 100. If your question is about the past, the archive is the right tool. If your question is about now, a monthly file cannot answer it. See the hybrid corpus approach for combining both.

100, and that is the ceiling on every listing endpoint. What changes is how much time those 100 posts cover. Measured on 2026-09-02, one 100-post page spanned 0.47 hours in r/AskReddit and 2,692.91 hours in r/redditdev, a ratio of 5,729.6 to one. Paging deeper works: five sequential calls against r/technology returned 500 unique records with no duplicates in 24.14 seconds, covering 167.92 hours. See how cursor pagination works.

Two loops, not one. The collection loop pages new posts on a cadence and inserts them by id. The refresh loop re-reads records you already hold through the bulk id endpoint, which takes up to 100 ids per call, and updates the mutable fields. Most home-built pipelines ship the first loop and skip the second, which is why their score and comment columns drift silently. See bulk fetching records by id for the mechanics.

Collecting publicly visible Reddit content through the data API under Reddit's Data API Terms is the documented route, and it is what every measurement in this guide used. The bulk archives sit on different footing, and the person who maintains their per-community splits says so plainly in public: the data was collected without permission and remains unauthorised, whatever researchers have done with it since. We cover the position in more depth in the legal read on collecting Reddit data and what commercial use requires.

1,620.8 bytes per post, derived from 1,620,777 response bytes across 1,000 records read on 2026-09-02 with compression disabled. A million posts is therefore roughly 1.6 GB of raw JSON before indexing, which is a laptop-sized problem. The bulk archives are a different order of magnitude, and the friction shows: people on the archive threads describe 2 TB downloads and ask for a way to take only the months they need. See the build versus buy comparison.

The community listing endpoint for the spine of the corpus, the search endpoint for topic backfill across communities, and the bulk id endpoint for refreshing what you already hold. Add the comments endpoint when you need discussion rather than submissions, since a comment record carries 70 fields against a post's 22. The community about record, 17 fields, gives you the metadata for sizing. See the search endpoint tutorial for the backfill half.

Decide the time window first, then page until you have covered it, and record how many calls that took. A fixed post count is the trap, because one 100-post page covered 0.47 hours in one community and 2,692.91 hours in another on the same day. Two communities compared over different observation windows are not comparable at all, and no amount of extra rows fixes that. State the window next to every figure you publish, and see the community size rankings for a sizing baseline.

Keep reading.

Continue exploring related pages.

Reddit API documentation

The complete 2026 reference: auth, all 52 endpoints, and code.

Get a Reddit API key

Instant bearer token, no waitlist and no enterprise contract.

Reddit Responsible Builder Policy

Why Reddit denies API applications, and the managed REST bypass.

Reddit API use cases

14 use cases from AI training to brand monitoring and DMs.

Reddit Search API

Search posts, comments, users, and communities over one REST endpoint.

Reddit MCP server

Wrap the REST API as MCP tools for Claude, Cursor, and any MCP client.

Reddit API for AI agents

Live Reddit context for tool calls, MCP servers, and RAG pipelines.

Redditapis pricing

Endpoint-level costs and quick monthly totals - reads from $0.002 / call.

Reddit API cost calculator

Estimate monthly spend using your request volume.

Reddit API guides and tutorials

Tutorials, walkthroughs, and API deep-dives for developers.

Reddit API alternatives

Evaluate alternatives by cost model, limits, and integration fit.

Cheap Reddit API

The cheapest way to get Reddit data: $0.002 per call, no contract, no minimum.

Official Reddit API vs Redditapis

Access, setup, rate limits, and pricing, side by side.

PRAW alternative

A hosted Reddit REST API for any language, no app registration or OAuth.

Reddapi alternative

A maintained Reddit REST API with published pricing and write endpoints.

Reddit comment scraper alternative

The raw comment API: search and filter comments, historical and live, clean JSON.

Reddit scraper API

Hosted scraper API vs building your own: managed proxies, clean JSON.

RapidAPI Reddit alternative

A direct, maintained Reddit API with published pricing and write endpoints.

Bright Data Reddit alternative

A purpose-built Reddit API vs a general scraping platform: structured JSON, plus writes.

ScraperAPI Reddit alternative

A Reddit-native API vs a generic HTML fetcher: auth and pagination handled, typed JSON.

TikHub alternative

TikHub's Reddit surface is read-only; get comment, vote, and DM endpoints too.

EnsembleData alternative

No $100/month floor: pay per call from $0.002, plus write, vote, and DM endpoints.

Scrape Creators alternative

7 read-only Reddit endpoints vs a dedicated API with real write, vote, and DM paths.

FetchLayer alternative

Posts, comments, and search only; add vote, comment, and DM over the same REST auth.

Reddit monitoring API

Build your own keyword and brand-mention monitor: search, comment search, and subreddit streams over REST.

F5Bot vs Redditapis

F5Bot's Slack and Discord delivery needs its $49.99/mo Gold tier; Redditapis includes it from $19/mo.

Syften vs Redditapis

Syften caps you at 100 to 500 results a day; Redditapis allows 10,000 a day per monitor at the entry plan.

Octolens vs Redditapis

Octolens meters by mention with overage fees; Redditapis is flat-priced by subreddit slot from $19/mo.

Affiliate program

Earn 20% lifetime commissions - capped at $5,000/yr.

Reddit Vote API tutorial

Upvote and downvote a post programmatically via the REST API.

Reddit Data API: REST, no PRAW

REST endpoints for Reddit data with no PRAW and no OAuth dance.

Reddit scraping benchmarks

Real throughput, error rates, and cost benchmarks for Reddit scraping.

Reddit API answers

Direct answers on cost, access, rate limits, endpoints, and auth.

How much the Reddit API costs

Per-call pricing from $0.002 a read, with $0.50 in free credits.

Reddit API in Python

One requests call with a bearer token, no PRAW and no OAuth flow.

Reddit shadowban checker

Check if a Reddit account is shadowbanned in seconds, free and no login.

Similar reads.

More guides on the Reddit API, scraping, pricing, and MCP servers.

Guide to Reddit demographics in 2026, covering which audience fields the public Reddit data API returns, five behavioural proxies you can derive, and the measured limits of each
reddit demographicsreddit audience research

Reddit Demographics in 2026: What the API Tells You About Reddit Audience Research

Reddit has never exposed age, gender or income. Here is what the public data API does return, the five behavioural proxies you can build from it, and where each one breaks.

Emma·
Measured ranking of the subreddits AI agent builders use in 2026, covering post velocity, on-topic share and reply depth across 24 communities read live through the public Reddit data API
ai agent redditbest subreddits for ai agents

The Subreddits AI Agent Builders Actually Use: 24 Communities, Measured

Five curated lists rank the best subreddits for AI agent builders and none of them measured anything. We pulled 24 communities and 2,400 posts and ranked them on data.

Emma·
Guide to building a Reddit analytics dashboard from the API, covering polling cadence, storage schema, five subreddit metric formulas and the measured API call cost
reddit analyticssubreddit analytics

Build Your Own Reddit Analytics Dashboard From the API: Subreddit Analytics Without a Third-Party Tool

Which endpoints to poll, how often, what to store, and how to compute the five metrics that matter. With measured latency, payload sizes and a call budget from a live pass.

Emma·
Reddit's API blocked from GitHub Actions and other CI runners: a customer-reported 403 and what causes it in 2026. redditapis.com is an independent, third-party service, not affiliated with Reddit Inc.
reddit api github actionsreddit api blocked ci

Reddit's API Returns 403 From GitHub Actions: A Customer's Report and What We Verified

A redditapis.com customer reported Reddit's own API returning 403 from GitHub Actions runners with no OAuth path available. What we verified independently, and what still works.

Emma·
Reddit comment search API in 2026: why Reddit's own search returns parent posts instead of comment bodies, and the live REST endpoints that search comment text after Camas and Pushshift went dark. redditapis.com is an independent, third-party service, not affiliated with Reddit Inc.
reddit comment search apireddit comment search

Reddit Comment Search API: the Camas and Pushshift-Live Alternative (2026)

Reddit's API has no comment-search endpoint, its type=comment mode returns parent posts, not comment bodies. Here is why, what died with Camas and Pushshift, and how to search Reddit comment bodies by keyword over REST in 2026.

Emma·
Reddit's 'Your request has been rate limited' error explained for both browsing users and developers, with the fix ladder for each. redditapis.com is an independent, third-party service, not affiliated with Reddit Inc.
reddit rate limitedyour request has been rate limited

Your Request Has Been Rate Limited on Reddit: Why It Happens and How to Fix It

What Reddit's 'Your request has been rate limited' error means in 2026, why regular users and developers hit it, and the two-track fix ladder for each.

Emma·
Reddit RSS feeds versus the Reddit API in 2026: what the free .rss path returns, its limits, and when to move to the managed API. redditapis.com is an independent, third-party service, not affiliated with Reddit Inc.
reddit rss feedreddit api

Reddit RSS Feeds vs the Reddit API in 2026

What the free Reddit .rss path still returns in 2026, its hard structural limits, where Reddit now throttles it, and when to move from RSS feeds to the managed API.

Emma·
Reddit API pricing in 2026: free tier, commercial tier, and the $0.24 per 1,000 requests rate, on a dark orange-and-blue editorial cover. redditapis.com is an independent service, not affiliated with Reddit Inc.
reddit api costreddit data api

Reddit API Cost in 2026: What You'll Actually Pay (Official Tiers + Alternatives)

What the Reddit API costs in 2026: reportedly $0.24 per 1,000 calls, near $12,000 per 50M requests. The free tier, commercial tier, and a calculator to run your numbers.

Emma·