Deploy Autoscaled Github Actions Runner
Autoscale ephemeral GitHub Actions runners on Railway.
github-autoscaler
Just deployed
github-runner
Just deployed
Deploy and Host Autoscaled Github Actions Runner on Railway
Autoscaled Github Actions Runner is a self-hosted CI runner solution that automatically scales GitHub Actions runner replicas on Railway in response to job demand — adding replicas as jobs queue and resetting back to one once all runners go inactive.
About Hosting Autoscaled Github Actions Runner
Self-hosted GitHub Actions runners on Railway come with a difficult tradeoff. Non-ephemeral runners stay registered and ready for jobs, but remain alive between runs — consuming significant memory on Railway even when idle. Ephemeral runners (--ephemeral) solve the memory problem by exiting cleanly after each job, but they deregister from GitHub on exit, leaving replicas inactive with no way to pick up the next job without a manual redeploy.
This autoscaler solves both problems. It listens for GitHub workflow_job webhook events and calls the Railway GraphQL API to automatically redeploy the runner when a new job arrives, scale up replicas for concurrent workloads, and reset back to one replica once all jobs complete and runners go inactive.
Important: Scaling down is intentionally limited. Railway's API can only set a desired replica count — it cannot target a specific replica for removal. Terminating a random replica risks canceling an in-flight job on another runner. To avoid this, the autoscaler only resets replicas once all jobs are complete and runners are already inactive. This template is not suitable for projects where runners are consistently active. If your runners are always busy, use non-ephemeral runners instead, which stay registered between jobs without needing to be restarted.
Common Use Cases
- Teams that want self-hosted GitHub Actions runners without managing their own infrastructure
- Projects with bursty CI workloads that need parallel runners on demand
- Teams currently running non-ephemeral runners on Railway who are paying for idle memory between jobs — this autoscaler enables ephemeral runners that go inactive when not in use, significantly reducing memory costs
- Teams using ephemeral runners who are frustrated by manual redeployments every time a runner deregisters after a job — this autoscaler detects new jobs via webhook and redeploys the runner automatically
Dependencies for Autoscaled Github Actions Runner Hosting
- A Railway API token with permission to manage services
- A GitHub Personal Access Token with self-hosted runner permissions (repo Administration or org Self-hosted runners, Read and Write)
Deployment Dependencies
Implementation Details
The autoscaler exposes three endpoints:
POST /webhook— receives GitHubworkflow_jobevents, validates HMAC-SHA256 signature, and triggers scalingGET /sync— reconciles the in-memory replica counter against the actual Railway replica count (useful after restarts)GET /health— health check used by Railway's healthcheck probe
Scaling logic:
- First job queued → redeploys the base replica to wake it from inactive state
- Concurrent jobs queued → calls
serviceInstanceUpdate(numReplicas: N)to add parallel runners - Job completed → does nothing mid-batch to avoid canceling in-flight jobs on other replicas
- All jobs complete → resets to 1 replica via
serviceInstanceUpdate(numReplicas: 1)
Why Deploy Autoscaled Github Actions Runner on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Autoscaled Github Actions Runner on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
Template Content
github-autoscaler
shaezzy/railway-github-runner-autoscalerMAX_RUNNERS
Maximum number of concurrent runner replicas.
RAILWAY_API_TOKEN
Railway API token used to scale runner replicas. Generate one at railway.app/account/tokens.
github-runner
myoung34/github-runner:latestACCESS_TOKEN
A fine-grained PAT giving the runner access to register itself. Setup -> https://github.com/settings/personal-access-tokens
