Why Bitbucket Pipelines self-hosted runner fees are prompting a move
Teams that already build on their own machines now face a new bill for the same hardware. Atlassian charges $15 per month per concurrent build slot for premium Bitbucket Pipelines runners from runner version 5, and older runners stop receiving scheduled work. The fee applies per concurrent slot, not per machine or per repository, so the cost rises with how many builds can run at the same time. Woodpecker CI or Jenkins can run those builds on machines your team already controls, and your repositories can stay in Bitbucket.
Before choosing an alternative, measure the parts of the bill separately. Count the peak number of concurrent builds your pipelines reach, not the average, because that peak sets the slot count. Then list each recurring component: Bitbucket user seats, build minutes on Atlassian-hosted runners, the self-hosted runner slots, and the staff time to keep runners patched. On the alternative side, the costs are the build servers or cloud capacity, the platform's maintenance and upgrades, support, and engineering time. This page compares those components and does not total them, because the totals depend on your own usage and contract terms. Confirm current slot pricing and any included allowances with Atlassian before you rely on them.
What the constraint requires from a replacement
Four requirements follow from the constraint. Each answers a specific Bitbucket behavior: a fee that grows with concurrent slots, runners that stop receiving work once they fall behind, secrets that cannot be read back, and artifacts that expire quickly. A replacement has to meet all four before the current fee schedule is switched off.
Cost that stops scaling with slots
Atlassian charges $15 per month per concurrent build slot for premium self-hosted runners from runner version 5, so the bill rises with every parallel job a team adds. A replacement should price by the machines and staff it runs, not by parallelism. When you compare options, ask what one more concurrent build adds to the monthly total, and list who pays for build hosts, the controller or server, upgrades and on-call time. Separate the costs that recur from the one-time setup work.
Runners on a supported version
Bitbucket stops scheduling work on older self-hosted runners, so a runner that falls behind can go quiet without any failed build to alert you. The replacement needs a written upgrade path for every build agent, including the operating system and container image it runs on, and a named owner who watches the job queue. Woodpecker agents connect to the server over gRPC, so confirm which server and agent versions must match during each upgrade and how long older releases stay supported.
Deployment secrets you control
Secured Bitbucket variables cannot be read back, only replaced or deleted, so a team that switches platforms has no export path for them. Hosted CI also holds secrets for every connected project, and CircleCI's January 4, 2023 incident report told customers to rotate secrets after an attacker took environment variables, tokens and keys. Keep credentials in a secrets store your own team operates, with an inventory listing each secret, its owner and its rotation date, and rotate them during cutover.
Artifacts and logs on your schedule
Bitbucket Pipelines keeps artifacts for at most 14 days, which is shorter than many audit and release retention policies. A self-hosted replacement stores artifacts and logs in your own storage, so the retention period is whatever your policy sets. Decide which artifacts, test reports and console logs must survive, where they are archived and who can read them. Export existing build history before cutover, because the 14-day window keeps closing on older builds.
What the per-slot fee changes in a team's build budget
The per-slot fee is one line in a larger budget. Atlassian licenses premium v5 self-hosted runners at $15 per month per concurrent build slot, according to the Atlassian announcement of v5 self-hosted runners. That licence is the only cost the change adds on the Atlassian side, but it sits beside build minutes billed on hosted runners and the cost of the machines and people a team takes on when it builds on its own hardware. A team should price all three separately: the slot licence Atlassian charges, the hosted minutes it still consumes for any work left on Atlassian's runners, and the servers, patching and staff time for its own build agents.
Illustrative calculation: if a team kept 4 concurrent slots on premium runners, the slot licence alone would be 4 times $15, or $60 per month, before any hosted minutes or staff time. Doubling peak concurrency to 8 slots doubles that line. The number of slots, the peak concurrency during release windows and the hours of engineering time spent on runner upkeep drive the total far more than the list price does. Teams should measure their real peak concurrent jobs from existing pipeline history before choosing a slot count, and confirm with Atlassian how concurrency is counted on their plan.
One-time work includes translating bitbucket-pipelines.yml into the new engine's format, rebuilding secured variables that cannot be exported, and running migration tests against real branches. Recurring costs include slot licences if the team stays on Atlassian runners, server hosting for Woodpecker CI or Jenkins agents, operating system and engine patching, storage for build caches and artifacts, and support time from the engineers who maintain the agents. Ask any vendor or partner to split its quote into these one-time and recurring lines, and ask who holds the on-call duty for build infrastructure, since that person's hours are usually the largest unpriced item.
Which open-source engines remove the per-slot meter
This table compares Woodpecker CI, Jenkins and GitLab CI/CD on how each runs builds on machines you control, whether repositories can stay on Bitbucket, and where each needs more work. Read it as a shortlist: the forge column decides whether repositories must move, and the trade-offs column shows the effort each engine adds.
| Engine | Where builds run and forge fit | Trade-offs and what to confirm |
|---|---|---|
| Woodpecker CI | Agents you run on Docker, Kubernetes or the local machine. Supports Bitbucket and Bitbucket Datacenter, so repositories can stay on Bitbucket. | Licensed under Apache-2.0. Pipeline YAML needs translation, and plugins may need adjustment. Confirm Bitbucket Cloud webhook and status behavior in a test repository. |
| Jenkins | Controller plus build agents on machines you provision. Jenkinsfile pipelines run on agents you manage, so the Bitbucket connection depends on plugins. | MIT-licensed with more than 2,300 plugins. Needs a plan for plugin versions, controller backups in $JENKINS_HOME, and LTS upgrades. Confirm the Bitbucket plugins you need. |
| GitLab CI/CD | GitLab Runner executors on machines you control, tied to a GitLab instance you run. | Repositories and issues must move off Bitbucket. Requires running GitLab itself, so plan for that platform's operation in addition to the runners. |
| Per-slot cost after migration | Removed for self-run agents. Your costs become the machines, storage, and staff time to run the engine. | Ask any quote to separate hardware, hosting, support and staff effort so you can compare the engines on the same basis. |
| Repository location | Woodpecker and Jenkins can leave repositories on Bitbucket. GitLab CI/CD requires a repository move. | Confirm your team's Bitbucket permissions, branch protections and pull request checks before choosing the engine. |
| Secrets and artifacts | Secrets and artifacts must be recreated or exported. Secured Bitbucket variables cannot be read back. | Plan secret replacement for each engine's store and confirm artifact retention on your own storage. |
Choosing Woodpecker CI or Jenkins by team situation
A team whose builds already run in containers and that operates only a few build machines usually fits Woodpecker CI well. Each Woodpecker step runs its commands inside a container image you specify, and workflows are plain YAML, which maps closely to the step-and-image pattern of Bitbucket Pipelines. Woodpecker can also keep the repositories where they are, since it connects to Bitbucket and Bitbucket Datacenter as forges.
- Database choice: Woodpecker uses SQLite by default. Check whether the expected build volume justifies PostgreSQL or MariaDB, which the administration documentation recommends for larger instances.
- Agent count: Confirm how many agents you need for concurrent builds and where they run, on Docker, Kubernetes or the local machine.
- Plugin fit: Test each Bitbucket pipe you rely on as a Woodpecker plugin, since the docs say Drone plugins generally work but may need adjustments.
- Forge scope: If you connect more than one forge to a single server, note that the documentation still labels multi-forge setups as experimental.
Before committing, run one representative pipeline end to end on a test server and confirm that webhooks, status reporting and secrets behave as expected.
A team with many existing Jenkins-style plugins, shared libraries or scripted deployment logic usually fits Jenkins better. Jenkins defines builds as code in a Jenkinsfile, with Declarative or Scripted syntax, and it reaches a large plugin catalog, which the Jenkins homepage describes as more than 2,300 community-contributed plugins. Jenkins is MIT-licensed, so there is no license fee for the engine itself.
- Controller and agents: The scaling guide recommends dedicated build agents so the controller only handles HTTP requests and manages the build environment.
- Configuration backup: All configuration, plugins and secrets live in
$JENKINS_HOMEon the controller, so include that path in your backup plan. - Configuration as Code: The Configuration as Code plugin reads YAML from
CASC_JENKINS_CONFIG, but it does not install plugins, so plan a separate method for plugin installation. - Bundled plugins: Jenkins LTS 2.580.1 stopped bundling several plugins, including the SSH server and JUnit plugins, so install any you depend on through the plugin manager.
- Java and LTS cadence: Confirm your Java runtime against the support policy and plan upgrades around the LTS release line.
Inventory every plugin and shared library the current pipelines call, then map each one to an installed Jenkins plugin before choosing the engine.
A team that must run builds inside Kubernetes should compare both engines against its cluster policies before choosing. Woodpecker's Kubernetes backend runs each step in a standalone pod and creates a temporary persistent volume claim for the pipeline to share files between steps. Jenkins has a Kubernetes plugin that provisions agents as pods. Both options are open source, so the decision rests on storage and operations rather than licensing.
- Storage class: Woodpecker's temporary claim defaults to 10G with ReadWriteMany access, so confirm that your storage class supports that access mode and size.
- Pod security: Review the service account and pod permissions that each step needs, since every step runs as its own pod.
- Controller placement: For Jenkins, decide where the controller runs and how a primary and backup controller will sit behind a proxy such as HAProxy or F5 if the primary fails.
- Install path: Woodpecker publishes a Helm chart, and Jenkins documents a Kubernetes installation, so compare both with your existing deployment tooling.
- Cluster ownership: Confirm which team operates the cluster and its upgrades, because CI nodes will depend on it.
Run a test build on a non-production cluster that matches your storage and network policies before deciding.
How to deploy self-hosted runners without the per-slot meter
This sequence moves builds onto runners you operate inside your own network, so the cost is set by your infrastructure and staff time rather than by concurrent Bitbucket slots, and each step ends with a check you can verify.
Confirm the forge connection to Bitbucket
The platform or DevOps lead confirms which forge the Woodpecker server will connect to: Bitbucket Cloud or Bitbucket Datacenter. Woodpecker lists both among its supported forges, with push, tag and pull request events. Check the forge documentation for your Woodpecker version and confirm that OAuth or access settings for your Bitbucket type are approved by the workspace owner. Done when a test repository sends a webhook that the server receives and lists as an active repository. Note that connecting several forges to one server is still marked experimental, so plan a single-forge server unless you have confirmed otherwise.
Install the Woodpecker server with a database
An infrastructure engineer installs the Woodpecker server in your own environment, using the Helm chart or your standard container tooling. The server provides the UI and API, receives forge webhooks and parses pipeline YAML. Woodpecker uses SQLite by default, but its documentation recommends PostgreSQL or MariaDB for larger instances, so provision one of those from the start and back it up. Done when the UI loads over your internal address, the database connection is confirmed in the server logs, and a database backup has been restored successfully in a test environment.
Attach agents on your chosen backend
The platform team registers one or more Woodpecker agents that connect to the server over gRPC. Choose the execution backend that matches your existing estate: Docker, Kubernetes or the local machine. On Kubernetes, each step runs in its own pod with a temporary persistent volume claim shared across the pipeline, so confirm your cluster's storage class supports ReadWriteMany. Agent labels are enforced by the server in the current release line, so label agents by purpose, such as a hardened pool for deployments. Done when each agent appears as connected in the server and a trivial pipeline runs on it.
Place agents inside the team's network
The network or security engineer places the agents in the same network segment as the systems they build and deploy to, such as private artifact registries and staging environments. Agents initiate connections to the server, so review outbound rules, certificates and the gRPC endpoint rather than opening inbound ports. Restrict the secrets each agent can see to the workflows that need them. If you run an autoscaler to create cloud VMs for pending builds, document its ceiling so cost stays predictable. Done when a build reaches the internal registry and a deployment target from the agent and the network team has signed off the rule set.
Translate bitbucket-pipelines.yml into Woodpecker workflows
A developer or pipeline engineer converts each bitbucket-pipelines.yml file into Woodpecker workflow YAML, either as a single .woodpecker.yaml or as several files in a .woodpecker/ directory. Each step runs its commands inside a specified container image, so map Bitbucket images and caches first. Replace Bitbucket pipes with the matching Woodpecker plugins from the plugin index, and review any Drone-derived plugin, since the documentation notes that some may need adjustment. Move secured variables by re-entering them in Woodpecker, because Bitbucket secured values cannot be read back. Done when every pipeline has a reviewed workflow file and a list of secrets re-entered and checked by their owners.
Run a parallel pilot on one repository
The team lead chooses one low-risk repository and runs Woodpecker alongside the existing Bitbucket Pipelines pipeline for the same commits. Compare test results, artifacts and build durations, and note every difference in environment, cache behavior or secrets. Keep deployments to non-production targets during the pilot. Bitbucket artifacts expire after at most 14 days, so export any build history you need before the pilot ends. Done when two or more pipelines produce matching results across normal branch, tag and pull request events, and the differences found have been fixed or accepted in writing.
Verify build status reporting before retiring runners
The engineering manager confirms that build status returns to Bitbucket pull requests from the Woodpecker server, and that required checks and branch restrictions block merges when a build fails. Confirm this on passing, failing and cancelled builds, including pull requests from forks if your policy allows them. Only after this check passes should the team roll the remaining repositories over and disable the hosted pipeline and the v5 self-hosted runner entries. Done when the status checks behave as your branch policy requires on every migrated repository and the runner inventory shows no active per-slot subscription.
Back up Jenkins controllers and agents
If you choose Jenkins instead, the platform team builds a controller that only handles HTTP requests and manages the build environment, and attaches dedicated build agents so builds run outside the controller. Treat $JENKINS_HOME on the controller as the single backup point, since the scaling guide states that configuration, plugins and secrets live there. Consider Configuration as Code to keep controller settings in YAML, noting that it does not install plugins. For resilience, a primary and backup controller can sit behind a proxy such as HAProxy or F5. Done when a restore of $JENKINS_HOME onto a test controller brings back jobs, credentials and plugins, and each agent reconnects to it.
Evidence to keep when you move build capacity in-house
Moving builds onto your own machines changes what a security or compliance reviewer will ask to see. The four records below connect the runner fee change to the controls around secrets, pipeline history and access. DeployOpen prepares this evidence, but auditors and certification bodies issue any assessment outcome.
Runner and slot inventory
Record every self-hosted runner, its version, the host it runs on and the number of concurrent build slots it offers, both before and after the change. Atlassian charges per concurrent build slot for premium runners from runner version 5 onward, so the slot count is the figure that drives the fee. Ask the team to confirm which runners are still on older versions, since those stop receiving scheduled work. Keep dated snapshots so the reviewer can see how capacity moved.
Secrets rotation and ownership record
For every connected project, list each secret, the person or team that owns it, the systems that depend on it and the date it was last rotated. Secured Bitbucket variables can only be replaced or deleted, so their values cannot be carried into a new platform. Plan rotation for all of them as part of the move, and record when each one was replaced. A January 2023 incident at CircleCI led that vendor to ask all customers to rotate secrets, which is why reviewers now ask for this record.
Pipeline and build history exports
Export the bitbucket-pipelines.yml file from each repository at a known commit, along with build logs and artifacts. Bitbucket Pipelines keeps artifacts for at most 14 days, so exports must happen before the platform is switched off, and the window is short. Keep a record of what was exported, when, by whom and where it is stored. Confirm with the team which build history must be retained under internal policy, because the export only covers what the team chooses to keep.
Agent and database access records
Document who can register agents, change pipeline definitions and read the CI database, and keep logs of those actions. Self-hosted Woodpecker CI can use SQLite by default, while PostgreSQL or MariaDB is recommended for larger instances, so the database choice changes what must be protected and logged. Jenkins keeps its configuration, plugins and secrets in the controller's home directory, which needs the same control. Ask the team to confirm how agents authenticate to the server and who holds the credentials that do so.
What does not move automatically: secrets and artifacts
Secured Bitbucket variables cannot be exported, so every secret the pipelines use must be re-entered from its source system. Bitbucket's documentation says secured variables can only be replaced or deleted, which means the value has to come from wherever it was originally issued: a cloud account, a deployment target, a registry or a signing key. Before the move, list every secured variable per repository and workspace, record which system owns each value, and confirm who on the team can retrieve it. Where the owner cannot be identified, treat the credential as unknown and plan to issue a new one rather than trying to recover it.
Because the old values cannot be read back, the migration is also a good point to rotate. The January 4, 2023 incident report from CircleCI is the reason to take this seriously: CircleCI told customers to rotate secrets after an attacker exfiltrated environment variables, tokens and keys from its platform, along with the encryption keys needed to read them. Hosted CI services hold deployment credentials for every connected project, so rotate them and narrow their scope during the move, giving each self-hosted runner only the credentials for the jobs it executes. Confirm with your own secrets store whether it supports per-environment scoping, audit logging of secret reads and automatic rotation, and whether runners can fetch secrets at job time instead of storing them on disk.
Artifacts expire in at most 14 days, so exports must happen before that window closes. Bitbucket Pipelines keeps artifacts for at most 14 days, according to Atlassian's documentation on using artifacts in steps, so anything you need for audit, release traceability or rollback must be copied out earlier. Decide which artifacts and logs your change and compliance process requires, export them to storage you control, and record the mapping between build numbers and deployed versions. Then confirm the retention rules in your own environment, including any legal hold or records policy that sets a longer period than the platform does.
Questions buyers ask before they hire help with the move
What drives the cost of moving self-hosted runners in-house?
The fee comparison depends on how many builds run at once, how many minutes they take and who operates the machines afterward. Atlassian charges $15 per month per concurrent build slot for premium Bitbucket Pipelines runners from runner version 5, according to the Atlassian announcement, so a team's concurrency figure is the first input. On the other side, the costs are the build servers, their storage and network, the engine license (Woodpecker CI and Jenkins are both open source, so the software itself carries no license fee), and the staff time to install, patch, monitor and support the pipelines. Ask for each of these as a separate line so the comparison stays honest.
Can our team move the runners and pipelines without outside help?
Often yes, if engineers already run Docker or Kubernetes and have owned a CI system before. The work is well defined: install a Woodpecker server and agents or a Jenkins controller and agents, connect them to the forge, translate pipeline definitions, and replace secured variables. The harder parts are secrets, which cannot be exported from Bitbucket and must be re-entered by their owners, and the operational habits that a hosted service used to handle, such as backups, upgrades and build history retention. Be honest with your team about who will hold the pager for the new system before deciding.
How much staff time does the move need, and what makes it grow?
Staff time depends mainly on the number of pipelines, how much each one depends on Bitbucket-specific features such as pipes, deployment environments and artifacts, and how many secrets must be re-created. Each secured variable needs an owner to supply the value again, so a large number of projects adds coordination work as well as technical work. Ask any provider to estimate effort per pipeline type and to list the assumptions behind the estimate. The duration of each phase should appear in the written plan rather than in a general promise.
What do we need to provide before the work starts?
Plan for four groups of people and access. Repository administrators must grant access to the Bitbucket workspaces and projects in scope. Network and security teams must approve traffic between the new build agents, the forge and any deployment targets. Secrets owners must be named for each deployment credential, because those values cannot be read back and must be supplied again. Pipeline owners must confirm which builds matter, which can retire, and who signs off on the cutover. Agree on these names early, since delays here usually set the schedule.
How long does a pilot take, and why does the pipeline count matter?
A pilot length depends on how many pipelines it covers and how varied they are. A pilot that moves one simple build differs greatly from one that moves a set of deployment pipelines with approvals and environment-specific secrets. Start with a small, representative set of pipelines, run them in parallel with the hosted builds, and compare results before retiring anything. Ask the provider for the pilot's exit criteria and the number of pipelines it covers, and treat any unsupported timeline without that scope as incomplete.
Is Woodpecker CI or Jenkins the better fit for our team?
Woodpecker CI suits teams that want container-native YAML pipelines close to the way Bitbucket Pipelines already works, and it connects to Bitbucket and Bitbucket Datacenter as forges, so repositories can stay where they are. Woodpecker's forge documentation also states that connecting multiple forges to one server is still experimental. Jenkins suits teams that need a large plugin ecosystem, complex scripted logic or several controllers for different groups. Jenkins is MIT-licensed and needs more care in controller backups, plugin management and upgrades. Test both against two or three of your real pipelines before choosing.
What should a written, fixed-scope quote include?
Ask for the scope in writing before work starts: which repositories and pipelines are included, which forge and CI engine are targeted, what is delivered for each phase, and which items are excluded, such as application code changes or deployment target work. The quote should list one-time costs (design, migration, pilot, cutover, documentation) separately from recurring costs (hosting, upgrades, support and monitoring) and state the client responsibilities from the earlier question. Ask how acceptance is decided and what happens to scope changes. DeployOpen plans fixed-scope engagements with agreed deliverables and timelines, and a quote follows from that written scope.
How DeployOpen works on this
DeployOpen plans, implements, integrates, hardens, documents and supports self-hosted open-source CI inside your own infrastructure, so build machines and deployment secrets stay under your control. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
How we scope
- Inventory which Bitbucket Pipelines runners, build minutes and concurrent slots each team actually uses today
- Confirm which repositories stay on Bitbucket and which move to Woodpecker CI or Jenkins
- Record every secured variable, deployment credential and artifact that must be replaced or exported
How we build
- Set up Woodpecker agents or Jenkins controllers and agents on infrastructure you own, with the backend you choose
- Translate bitbucket-pipelines.yml steps into Woodpecker YAML or Jenkinsfile stages and test them against sample branches
- Store runner credentials and replacement secrets in your chosen store, and verify builds report status back to Bitbucket
How we hand over
- Document the architecture, runner sizing, backup scope and upgrade steps written for your platform team
- Hand over runbooks for rotating secrets, exporting remaining artifacts and retiring old runners
- Walk your engineers through a test release and record the results in the agreed deliverables
How we support
- Offer ongoing support, upgrades and continuous testing as a retainer after handover
- Track upstream releases, such as Woodpecker and Jenkins LTS lines, and plan upgrades in your change windows
- Confirm with your team which support level and response terms apply before the retainer starts

