DevOps / GitHub Actions Interview Questions
What are jobs in GitHub Actions, and how do they run in parallel by default?
A job is a named collection of steps that runs on a single runner from start to finish. Every job gets a fresh, isolated virtual machine (or container), so jobs do not share filesystem state, environment variables, or processes with each other unless you explicitly pass data via artifacts or outputs.
When a workflow contains multiple jobs, GitHub schedules all of them simultaneously by default — there is no implicit ordering. GitHub's scheduler picks up each job as soon as a runner is available, so two jobs in the same workflow can and do run at the same time:
jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm run lint test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm test
In this example, lint and test start at the same time on two separate Ubuntu runners. This parallelism is a deliberate design choice: independent tasks like linting, unit testing, and security scanning should not wait for each other.
To make jobs run sequentially, use needs: to declare that one job depends on another. You can also use if: always() combined with needs: to run a cleanup job even if a dependency failed.
Each job also independently declares its own runs-on: label, meaning different jobs in the same workflow can target different runner types — one job on Ubuntu, another on macOS, another inside a custom self-hosted runner with GPU access.
More Related questions...