What ARC is, and why 0.15.0 matters
ARC is GitHub's Kubernetes operator for self-hosted runners. It orchestrates and scales self-hosted runners for GitHub Actions, and lets you create runner scale sets that automatically scale based on the number of workflows running in your repository, organization, or enterprise.
The release sits on GitHub's public roadmap as a generally available item. The roadmap entry says it makes it easier to configure, operate, and troubleshoot self-hosted runners on Kubernetes, and it carries Free, Team and Enterprise SKU labels plus a GHES 3.23 label. GitHub also says the release incorporates vetted community contributions, so the improvements reflect real-world usage at scale.
The changelog groups the changes under reliability, scalability and observability for runner scale sets. GitHub says they matter most for clusters with many scale sets, where controller throughput, graceful shutdown and accurate metrics affect daily operations. That is GitHub's stated goal. The announcement includes no benchmarks, so treat any performance claims as unmeasured until you test them on your own cluster.
Section summary: ARC 0.15.0 is a GA operations release for teams running GitHub Actions on Kubernetes. Larger fleets get the most from it.
The nine headline changes
1. In-place resource updates on patch upgrades
Patch-version upgrades now update resources in place. That keeps a one-to-one mapping between an autoscaling runner set and its ephemeral runner set and causes less disruption between the two. The repository changelog lists it as "Upgrade resources in-place, causing 1-1 mapping between autoscaling runner set and ephemeral runner set" (PR #4516).
The announcement doesn't spell out every upgrade condition, and it doesn't promise zero disruption. Plan maintenance windows accordingly.
2. A configurable termination grace period that matches shutdown
terminationGracePeriodSeconds on the controller is now configurable and lines up with the controller manager's graceful-shutdown timeout (PR #4556). If those two values disagree, Kubernetes can kill the controller pod before the manager has finished shutting down. The announcement gives no default value, so check your chart before changing anything.
3. Re-registering a missing scale set
If the scale set ARC has on record no longer exists in the Actions service, ARC can now register it again (PR #4571). This fixes cases where ARC's view of the world and GitHub's no longer match. GitHub hasn't listed what causes those mismatches.
4. Patch requests instead of full updates
Controllers now send patch requests rather than full update requests, which shrinks Kubernetes API payloads (PR #4533).
5. Runner status moves to metrics
Runner status for EphemeralRunnerSet and AutoscalingRunnerSet is now reported through metrics instead of the status field, which means fewer status patch requests (PR #4557). Dashboards or scripts that read runner counts from those resources' status fields may need updating.
6. Listener QPS and burst limits
You can now set rate limits on the listener's Kubernetes client with QPS and burst settings (PR #4558). QPS sets the sustained request rate. Burst sets how many requests can arrive in a short spike.
This builds on earlier work for the controller itself. Writing about an earlier ARC release, Ken Muse noted that k8sClientRateLimiterQPS configures the number of queries per second (QPS) that the controller can make to the API server, while k8sClientRateLimiterBurst configures the burst size, which is the peak number of requests that can be made per second. Version 0.15.0 extends that control to the listener. The announcement doesn't name the exact chart keys or defaults for this release.
7. Reconcile concurrency, globally and per controller
You can set controller concurrency globally or per controller with max-concurrent-reconciles flags (PR #4626). Again, this extends earlier work. Muse explained that in a prior release, the runnerMaxConcurrentReconciles setting configures how many threads the EphemeralRunnerController uses for reconciliation. Instead of being limited to a single thread, it defaults to two threads (and the number is configurable).
One upgrade item to check. The repository's 0.15.0 list also includes "Set per-controller reconcile concurrency defaults and remove --default-max-concurrent-reconciles" (PR #4670). The GitHub Blog announcement doesn't mention this. If your deployment passes a flag by that name, check it against the 0.15.0 chart and controller arguments before you upgrade.
8. Event filtering means fewer reconciliations
Controllers now filter incoming events, so fewer of them trigger a reconciliation. The repository list includes "Filter owned-resource events in the workqueue" (PR #4647). The point is to cut repeated work, not to lose events. GitHub hasn't published the exact filtering rules.
9. Faster deletion after a successful exit
When a runner pod exits successfully, ARC now skips the server-side check for runner removal, so ephemeral runners are deleted faster. This only applies to successful exits. Under GitHub's documented flow, the ephemeral runner controller normally checks with the Actions service after a successful job to see whether the runner can be deleted. Version 0.15.0 skips that check when the pod has already exited cleanly. Failed exits work differently: an earlier release added "Ensure ephemeral runner is deleted from the service on exit != 0" (PR #4260), and the 0.15.0 announcement doesn't say failure handling has changed.
Section summary: Most of these changes cut Kubernetes API traffic or controller workload. The rest make upgrades, shutdowns and scale-set recovery more predictable.
Beyond the headline list
The repository's 0.15.0 notes contain many more items than the blog post. Examples:
- "Scale down runners whose pod never reports the runner container" (#4696)
- "Avoid listener pod recreation for prepended sidecars" (#4685)
- "Fix listener replacement loop for empty collections" (#4682)
- "Reject unsafe chart metadata integers" (#4679)
- "Introduce cache for lookups of desired resource state" (#4568)
- Health and readiness probes for the controller manager (#4459)
- An optional pprof flag on the controller manager (#4449)
- Bundled runner versions updated to v2.335.1 and later v2.337.0
These come from the repository changelog, not the GitHub Blog post.
How the changes fit ARC's architecture
ARC's documented flow shows why these changes matter together:
- The AutoScalingRunnerSet Controller calls the API one more time to either fetch or create a runner scale set in the GitHub Actions service before creating the Runner ScaleSet Listener resource. This is where the re-registration fix applies.
- In this pod, the listener application connects to the GitHub Actions Service to authenticate and establish an HTTPS long poll connection. The listener stays idle until it receives a Job Available message.
- The listener then patches the EphemeralRunnerSet's desired replica count through the Kubernetes API. This is the client the new QPS and burst settings control.
- The Ephemeral RunnerSet attempts to create new runners and the EphemeralRunner Controller requests a Just-in-Time (JIT) configuration token to register these runners.
- After the job, cleanup runs. This is where the faster deletion on successful exit helps.
With many scale sets and high job churn, every step multiplies API calls. Patching instead of updating, filtering events and moving status into metrics all cut that traffic. Concurrency and rate-limit settings let you decide how hard ARC pushes the API server.
Context: from 0.14.0 to 0.15.0
The previous minor release shipped on March 19, 2026. That version introduces multilabel support for runner scale sets, switches to the actions/scaleset library client, adds resource customization options, and improves listener pod scheduling. It also added experimental Helm charts. The experimental charts are available alongside the existing charts for early feedback. Version 0.14.0 also introduced stopping autoscaling for outdated runners: when a runner exits with exit code 7, the controller switches off autoscaling for that runner set.
So 0.14.0 added capabilities, and 0.15.0 mostly hardens them. Several repository items in 0.15.0 refine the outdated-runner lifecycle that 0.14.0 introduced, for example "Make the Outdated phase revision-aware" (#4644).
Practical upgrade checklist
None of this is an official GitHub procedure. It's a sensible way to handle a controller upgrade given what the release notes say and don't say:
- Read the full 0.15.0 changelog in the repository, not just the blog post. Look for anything touching flags you already set, especially the removed
--default-max-concurrent-reconcilesflag. - Diff your Helm values against the 0.15.0 charts to find the new termination grace period, listener QPS/burst and concurrency settings. Don't assume defaults the documentation doesn't state.
- Check your monitoring. If dashboards read runner counts from the status fields of
EphemeralRunnerSetorAutoscalingRunnerSet, move them to ARC's metrics. - Upgrade in staging first and watch API server request rates, runner cleanup times and listener restarts.
- Raise concurrency gradually. More concurrent reconciles can process work faster, but they also put more load on the API server.
Section summary: Check flags and dashboards, test in staging, then tune concurrency and rate limits.
The bottom line
ARC 0.15.0 is a maintenance release aimed at large self-hosted fleets. If your clusters are already putting pressure on the Kubernetes API server, or upgrades have been disruptive, it's worth testing. The announcement makes no measured performance claims, so test it in staging first, and check the concurrency flag change before you upgrade.
References
- Actions Runner Controller release 0.15.0 GitHub Changelog · 2026-10-01T13:01:31+00:00
- README.md github.com
- Actions Runner Controller - GitHub Docs docs.github.com