Creuto is now an OpenAI Select Partner Read More

Software Architecture & Technical

GitHub Actions API run count: 2,500+ replaces the total

The GitHub Actions API run count now reports 2,500+ above that threshold. Which dashboards, clean-up jobs and cost reports break, and how to rewrite them.

GitHub Actions API run count: 2,500+ replaces the total

The GitHub Actions API run count stopped being a number on 25 September 2026. When a workflow-run query matches more than 2,500 records, the API and the UI now report "2,500+" instead of attempting to return the exact figure. Pagination is unchanged — still up to 1,000 items — and the change is rolling out on github.com and GitHub Enterprise Cloud now.

Nothing returns an error. Nothing logs a deprecation. The scripts that break are the ones that read total_count and then do arithmetic with it, which in most engineering organisations means the CI dashboard, the artifact clean-up job and whoever built the monthly cost report.

What GitHub changed, and why the count was never trustworthy

The change applies to searches by workflow, event, status, branch or actor. GitHub's reasoning is worth reading carefully, because it reframes the change as a correction rather than a limitation: queries retrieving more than 2,500 records "frequently timeout and return the number of records found before the timeout rather than the true count". The old behaviour returned a precise-looking number that was already wrong. The new behaviour returns an honest bound.

That distinction matters when someone objects that the dashboard used to work. It did not. It reported whatever the query had counted when it ran out of time, which is why the same filter could return different totals on two consecutive refreshes.

What breaks when the GitHub Actions API run count stops being exact

Four patterns, in roughly the order teams discover them.

  • Pagination loops driven by the total. Any script shaped like pages = ceil(total_count / per_page) now computes its bound from a capped value, so it stops early and reports success. This is the quiet one: no error, just a partial result treated as complete.
  • Clean-up and retention jobs. A job that deletes runs older than N days, driven by a status or branch filter, will process a truncated set and leave the rest behind. It keeps running green every night while the backlog grows.
  • Cost and usage reports. Anything multiplying a run count by an average duration to estimate minutes now underestimates every repository busy enough to matter, and by an unknown margin, because 2,500+ has no ceiling.
  • Dashboards and SLO panels. A "runs this week" tile or a failure-rate calculation with a run count in the denominator silently caps. A failure rate computed as failures over total runs gets worse as the denominator saturates.

The changelog does not say how "2,500+" is represented in the JSON body, so before assuming your language coerces it safely, run the query against a repository that genuinely exceeds the threshold and inspect the raw response. A total that arrives as text where your code expects an integer fails differently in Python, Go and JavaScript — and only one of those three is likely to fail loudly.

Pagination did not change, but it was never what you thought

GitHub is explicit that paginated results of up to 1,000 items continue. Read the workflow runs REST documentation alongside it and the older constraint becomes the more important one: the endpoint returns up to 1,000 results for each search when you use actor, branch, check_suite_id, created, event, head_sha or status. With per_page capped at 100, that is ten pages and then nothing.

So a filtered query could never hand you more than 1,000 runs, however large the total said it was. Scripts that walked past page ten were already receiving empty pages and treating them as the end of the data. The count change does not create that gap; it stops the total from hiding it.

How to count workflow runs now

The fix GitHub recommends is to narrow the filter, and a date range is the narrowing that composes with everything else. The created parameter takes search syntax, so you partition the window and sum the partitions, keeping each slice under both the 2,500 threshold and the 1,000-result cap.

GET /repos/OWNER/REPO/actions/runs
  ?status=failure
  &created=2026-09-01..2026-09-07
  &per_page=100

Three rules make that reliable in practice. Size the slice from your busiest repository, not your average one — a week is fine for most, a day for a monorepo. Treat any slice that comes back at the threshold as a signal to split it further rather than a number to record. And make the partitioning function the only place in your tooling that knows about the limit, so the next threshold change is a one-line edit.

For anything that has to be exact, stop deriving history from a query at all. Record each run when it finishes and keep your own ledger, then query your table instead of GitHub's. That is more work on day one and less work permanently, and it survives the next API change without a migration. It is the approach we take to reporting on the pipelines we build during CI/CD implementation, because a report nobody can reproduce six months later is not a report.

What to check this week

Grep your automation for total_count and for actions/runs. The list is usually shorter than people expect and lives in three places: a scheduled workflow in the repository itself, a Lambda or cron job somewhere in the platform account, and a spreadsheet or BI query someone built two years ago that nobody owns. The third one is the one that will be quoted in a meeting.

Then sort the hits by consequence. A dashboard that under-reports is embarrassing; a clean-up job that silently skips records costs storage and, eventually, an audit finding. Worth doing in the same pass: anything reading Actions data with a token broad enough to write, because a reporting script rarely needs more than read access, and what a comment can do to an Actions workflow makes over-scoped automation credentials a poor place to economise on effort.

The wider point is about where CI truth lives. Run counts, durations and failure rates are the numbers engineering leaders make decisions on — whether to invest in faster pipeline runs, whether a flaky suite is getting worse, whether the runner bill is justified. If those numbers come from an API query that can be capped, rate-limited or reshaped by a changelog entry, the decision rests on someone else's query planner. Moving that data into your own store is a half-day of DevOps and cloud engineering work and the last time you will have to read a changelog to find out whether your dashboard is lying.

Frequently asked questions

GitHub reports 2,500+ because queries matching more than 2,500 workflow runs frequently timed out and returned whatever had been counted before the timeout rather than the true total. The bounded value is more accurate than the precise-looking number it replaces, and it also improves query performance.

Searches for workflow runs filtered by workflow, event, status, branch or actor are affected, in both the GitHub Actions REST API and the web UI. The change is rolling out on github.com and GitHub Enterprise Cloud from 25 September 2026.

Yes. GitHub continues to return paginated results of up to 1,000 items, and per_page is capped at 100. The workflow runs documentation notes that a search using actor, branch, check_suite_id, created, event, head_sha or status returns up to 1,000 results, which predates this change.

Narrow the query with a date range using the created parameter, which accepts search syntax, and sum the partitions so each slice stays below the threshold. For reporting that must be exact, record each run as it completes into your own store and query that instead of the API.

Search your automation for total_count and for the actions/runs endpoint. Pagination loops that compute a page count from the total, retention jobs that delete old runs, cost estimates that multiply run counts by duration, and failure-rate panels with a run count denominator are the four patterns that break silently.

Written by

Akash Mohapatra

Akash Mohapatra

Co Founder & Director

26 Sep 2026

·

6 min read

Share

LET'S CONNECT

Connect with Creuto!

Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.

We don't just aim to fit in – we strive to stand out. Experience the perfect blend of innovation, excellence, and trust that makes us truly unforgettable. Discover the difference with Creuto.

© 2026 Creuto All Rights Reserved