GitHub’s aggregate star-history endpoint replaces a costly workaround: downloading pages of individual stargazers and reconstructing a timeline from their timestamps. It returns daily star counts for up to 30 calendar weeks per request, without attaching user identities. For the roughly 251,000-star react/react example, that changes a full-history crawl from about 2,511 requests to about 24.
Why GitHub changed the stargazer workflow
The original GET /repos/{owner}/{repo}/stargazers endpoint answered a person-level question: who currently stars a repository? With a custom media type, clients could also read each star’s timestamp. Analytics tools reused that identity list to answer a different question: when did stars arrive?
As an Amazon Associate I earn from qualifying purchases.
That design exposed more information than a trend chart needs. Public identity lists also created a convenient scraping path for spam and phishing. GitHub therefore restricted stargazer and watcher lists to repository administrators and collaborators. The restriction addressed the privacy and abuse risk, but it also broke applications that only needed aggregate history.
GitHub reported nearly 37,000 slow stargazer-count queries in the week before access was restricted. Those queries averaged nearly three seconds, and database safeguards killed more than 1,000 of them. After the restriction, GitHub measured about 60% fewer stargazer requests and about 80% less total time spent on count queries.
#1 Best Overall
Why counting stars was so expensive
The old method paginated people, not events
Each old response contained at most 100 people. A repository with about 251,000 stars therefore required approximately 2,511 page requests to retrieve the full current list. A client then discarded the identities, grouped the timestamps by day, and built a chart.
There was another limitation: the underlying model represented the people who still starred the repository, not a permanent event stream. When someone removed a star, that record disappeared. The reconstructed history was consequently based on the current set of surviving star records rather than an immutable record of every star and unstar action.
Rank #2
Aggregate-then-paginate does not solve the database problem
A tempting redesign would group all matching stars by day and apply LIMIT and OFFSET to the grouped result. That reduces the number of rows returned, but it does not necessarily reduce the work needed to produce each page. The database may still scan, sort, and bucket the entire matching set before applying the limit.
For the react/react example, GitHub says that approach could examine roughly six million rows because all 24 history requests would repeatedly process the full star set.
How the aggregate endpoint works
Filter by an indexed week before grouping
The shipped design converts the request’s page and per_page values into an indexed calendar-week range on created_at. The database narrows the matching time window first, then groups only those records into daily counts. This ordering is the central performance improvement.
Each response covers up to 30 calendar weeks. Increasing page moves backward through the repository’s history, allowing a client to walk from recent weeks toward older ones without repeatedly recounting the entire repository.
Rank #4
What a client receives
The response is an aggregate series: dates and star totals, rather than usernames. That is enough for a chart, growth-rate calculation, or release-impact analysis while avoiding the identity exposure inherent in the old list endpoint.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Old and new designs compared
| Aspect | Stargazer-list workflow | Aggregate star-history endpoint |
|---|---|---|
| Primary answer | Which people currently star the repository? | How many stars were recorded on each day? |
| Identity exposure | Returns individual stargazers; clients often discarded those identities after downloading them. | Returns daily counts without attached identities. |
| Page size | At most 100 people per page. | Up to 30 calendar weeks per response. |
react/react full-history requests |
About 2,511 requests for approximately 251,000 stars. | About 24 requests. |
| Database strategy | Retrieve person records, then reconstruct the timeline outside the API. | Apply an indexed created_at week range, then group matching rows into daily counts. |
| Historical semantics | Based on the current set of people who still star; removed stars no longer have records. | Uses the same star-record semantics, presented as aggregate daily counts. |
How to query historical stars efficiently
- Start with the newest period. Request the repository’s aggregate history with a page size that covers up to the endpoint’s 30-week limit.
- Store the daily series as returned. Keep the dates and counts; do not try to rebuild the result by requesting stargazer identities.
- Advance the page number to move backward. The endpoint maps higher page values to older calendar-week ranges.
- Stop when no older period is returned. A repository may have a shorter history than the maximum range, so the final response can contain fewer weeks.
- Cache completed weeks. Historical pages do not need to be fetched on every chart view. Refresh the current page more often and retain older pages locally.
- Keep calendar boundaries intact. Treat the returned weeks as the API’s defined windows rather than converting them into rolling seven-day buckets without documenting that transformation.
Important limits and interpretation details
A 30-week window is a time limit, not a row limit
The endpoint limits how much calendar time one request covers, but it does not cap the number of stars inside that period. An unusually dense week can still contain a large matching set and therefore require substantial database work. Smaller windows can be a practical response when a repository has abrupt bursts of activity.
Best Value
Calendar weeks affect pagination
Pagination follows calendar-week boundaries. A release that lands near a boundary can place its daily counts in a different response page than a nearby date would. Consumers should persist the date labels from the response instead of assuming that every page represents an identical rolling interval.
Removed stars change what “history” means
Because the star model tracks the current surviving records, removing a star removes its record from the data being aggregated. The endpoint is therefore a history of currently represented star timestamps, not a tamper-proof audit log of every star event. Long-term trend analysis should state that qualification.
A privacy change that also improves capacity
The endpoint separates two jobs that the old API combined: identity access for repository administration and aggregate statistics for analytics. Applications that need only a chart can now request the smaller, purpose-built result instead of downloading thousands of identities. In GitHub’s engineering account, the change followed collaboration with maintainers whose projects depended on star trends.
“When the API change disrupted Star History, users rallied around the project. GitHub’s Community team listened and connected us with product engineering, who dug into our use case and worked alongside us to design a purpose-built endpoint. A difficult situation became a constructive collaboration between GitHub, Star History, and the broader community—ultimately leading to a better solution.”
For developers, the practical rule is simple: use the aggregate endpoint for trend data, reserve person-level endpoints for authorized administrative use, and design around week ranges rather than trying to make a paginated identity list behave like an event log.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

