Skip to content

Timeout & Limits

RunnerHub enforces timeout and concurrency limits to ensure fair resource allocation and cost control. Your plan determines the maximum allowed timeout and concurrent job limits.

Define the maximum allowed duration for your pipeline using the timeout field:

timeout: 30

The timeout is specified in minutes. If a job exceeds this duration, RunnerHub automatically terminates it and marks the job as TIMEOUT.

If you don’t specify a timeout, RunnerHub uses a default of 60 minutes. However, your plan may limit the effective maximum.

name: My Pipeline
platform: ios
environment:
xcode: "16.4"
triggers:
- push
steps:
- name: Build
run: fastlane build
# If timeout is not specified, defaults to 60 minutes
# But your plan may enforce a lower maximum

The maximum timeout you can configure depends on your RunnerHub plan:

PlanMax TimeoutUse Cases
Free30 minutesQuick CI for small projects
Pay-as-you-go (PAYG)60 minutesStandard builds with testing
Pro90 minutesComplex builds, integration tests
Business120 minutesLarge monorepos, extensive test suites

If you specify a timeout above your plan’s limit, RunnerHub will reject the job with an error message indicating the maximum allowed timeout for your plan.

Choose a timeout that covers your typical build time plus some buffer:

# Fast build: 15 minutes
timeout: 15
steps:
- name: Build
run: fastlane build
# Complex build with testing: 45 minutes
timeout: 45
steps:
- name: Install dependencies
run: bundle install && pod install
- name: Run tests
run: fastlane test
- name: Build
run: fastlane build
# Enterprise pipeline with full test suite: 90 minutes (Pro plan)
timeout: 90
steps:
- name: Full test suite
run: fastlane test full

When a job exceeds the timeout duration:

  1. Timeout Triggered — The agent detects the timeout threshold
  2. Job Terminated — The current step is killed
  3. Status Set — Job status is set to TIMEOUT
  4. Cleanup — The job directory is cleaned up (or VM destroyed in VM mode)
  5. Completed — Job marked as COMPLETED with final status TIMEOUT

The timeout applies to the entire pipeline execution, not individual steps. There is no per-step timeout—if one step takes too long, it affects your total time budget.

RUNNING → TIMEOUT → CLEANING → COMPLETED

The job moves through these states:

  • RUNNING — Job was executing
  • TIMEOUT — Execution exceeded the timeout duration
  • CLEANING — Job directory/VM being cleaned up
  • COMPLETED — Final status reported, job finished
## Concurrency Limits
The maximum number of jobs that can run simultaneously depends on your plan:
| Plan | Concurrent Jobs | Additional Slots | Total Notes |
|------|-----------------|------------------|------------|
| **Free** | 1 | — | Single job at a time |
| **Pay-as-you-go (PAYG)** | 1 | Purchasable | Can buy extra slots per overage |
| **Pro** | 2 | Available | Pre-allocated concurrent capacity |
| **Business** | 3 | Available | High-capacity for teams |
**Queue Priority:** Jobs are processed in queue order, with priority given to higher-tier plans:
- Business
- Pro
- PAYG
- Free
If all concurrent slots are full, new jobs wait in a queue until a slot becomes available.
## Example: Understanding Concurrency
**Scenario: Free plan (1 concurrent slot)**

Job A submitted at 1:00 PM → RUNNING │ └─ Job B submitted at 1:01 PM → PENDING (waiting for Job A to finish) │ └─ Job A completes at 1:15 PM │ └─ Job B starts (moves from PENDING to ASSIGNED)

**Scenario: Pro plan (2 concurrent slots)**

Job A submitted at 1:00 PM → RUNNING Job B submitted at 1:01 PM → RUNNING (second slot available) │ └─ Job C submitted at 1:02 PM → PENDING (both slots occupied) │ └─ Job A completes at 1:15 PM │ └─ Job C starts (moves from PENDING to ASSIGNED)

## Setting Timeout: Practical Examples
### Short, Quick Builds
```yaml
name: Swift Lint Check
platform: ios
environment:
xcode: "16.4"
timeout: 10
triggers:
- pull_request
steps:
- name: Lint Code
run: swiftlint lint
name: iOS Release Build
platform: ios
environment:
xcode: "16.4"
timeout: 30
triggers:
- push
- pull_request
steps:
- name: Install dependencies
run: bundle install && pod install
- name: Run tests
run: fastlane test
- name: Build
run: fastlane build
name: iOS Full Test Suite
platform: ios
environment:
xcode: "16.4"
timeout: 60
triggers:
- push
steps:
- name: Install dependencies
run: bundle install && pod install
- name: Unit tests
run: fastlane test unit
- name: Integration tests
run: fastlane test integration
- name: UI tests
run: fastlane test ui
- name: Build
run: fastlane build
name: Enterprise Monorepo Build
platform: ios
environment:
xcode: "16.4"
timeout: 90
triggers:
- push
- pull_request
steps:
- name: Install dependencies
run: bundle install && pod install
- name: Lint
run: swiftlint lint
- name: Unit tests
run: fastlane test unit
- name: Integration tests
run: fastlane test integration
- name: Full test suite
run: fastlane test full
- name: Build iOS
run: fastlane build ios
- name: Build macOS
run: fastlane build macos

To understand how close your builds are to the timeout:

  1. View Job Duration — Open a completed job in the dashboard
  2. Check Log Duration — Logs show the total execution time
  3. Adjust Timeout — If jobs are consistently hitting the limit, increase the timeout or optimize your pipeline

Identify Slow Steps Review job logs to find bottlenecks:

steps:
- name: Timestamp Before
run: date
- name: Slow Step
run: fastlane test
- name: Timestamp After
run: date

Cache Dependencies RunnerHub automatically caches CocoaPods, SPM, gems, npm, and yarn. Ensure lock files are committed:

steps:
- name: Install dependencies
run: pod install # Uses cache if Podfile.lock unchanged

Parallel Steps (Future) RunnerHub will support parallel steps in future releases. For now, steps run sequentially.

Upgrade Your Plan Higher plans allow longer timeouts:

  • Free → PAYG: unlock up to 60 minutes
  • PAYG → Pro: unlock up to 90 minutes
  • Pro → Business: unlock up to 120 minutes