A self-hosted executor for cloud tasks is an option for those whose network and data requirements do not allow using a managed service. Pools, individual machines and container orchestration are officially supported, the queue of pending requests is visible through the programmatic interface, and the state of the fleet both there and in the dashboard. For most teams the recommendation is the opposite - start with the managed cloud and move to your own only for a specific, written-down requirement.
That recommendation is not marketing and deserves to be taken seriously. Your own runtime transfers to you everything the provider used to do: image updates, capacity, observability, isolating runs from one another, incident response and cleanup. None of those duties looks heavy on its own, and together they add up to continuous work. An unpatched privileged executor inside your network is more dangerous than a managed machine with a narrow network policy, and that is not a paradox but ordinary operational arithmetic: security is measured by the weak link, not by the place of hosting.
It helps to lay the options out in a table with an operational-cost column once. Below is that map: the managed cloud, your own pool, private connectivity through a cloud provider's network service, and a tunnel. The value is in the right column: it names not advantages but the duties that arrive with the choice. It is worth reading as a list of future on-call shifts rather than a list of capabilities.
| Choice | Strength | Operational cost |
|---|---|---|
| The managed cloud | Ready isolation, capacity and artifacts | Data and egress pass through the configured boundary |
| Your own pool | Execution inside your infrastructure | Updates, capacity, observability, isolation and incidents are yours |
| Provider private connectivity | Private traffic to repositories and registries | Load balancers, endpoints, DNS, regions |
| A tunnel | Outbound-only connection without inbound rules | Token lifecycle and operating the tunnel client |
Private connectivity is needed when repositories and package registries are unreachable from the internet. Two main paths are supported, and both have hard requirements: a secured connection on the standard port, a publicly trusted certificate and proven domain ownership. Self-signed certificates, unencrypted connections, access over the remote shell protocol, non-standard ports and endpoints reachable only over the newer version of the network protocol are not supported in these scenarios.
Those limits are useful to know before designing rather than after. A typical internal-network setup is built exactly on self-signed certificates and non-standard ports: inside the perimeter that is simpler, and for years nobody complains. And that is precisely what will not fit. So connecting an internal repository will require not only network work but also bringing it up to requirements: a proper certificate, a proper port, a proper name, proven domain ownership. That work is better planned in advance than discovered on the day of rollout.
Options are worth comparing as whole systems rather than by one property. Isolation, image provenance, secret storage, outbound traffic, updates, logs, cleanup and on-call duty - that is what real security is made of. The words self-hosted by themselves improve none of those items; they merely move responsibility for them onto your team. The managed cloud does not remove any of them either - it closes them on your behalf, and that is exactly the service you are paying for.
Operational cost sounds abstract until it is broken down into concrete duties. Who updates the base images and how often. Who makes sure runs cannot see one another. Who cleans up after finished tasks - containers, artifacts, temporary directories. Who keeps the logs and for how long. Who answers at night when executors stop picking up work. The last item has a visible sign: the queue of pending requests starts growing while tasks stand still. In the managed cloud that is someone else's capacity problem; on your own it is yours, and it has to be solved at the moment the team is waiting for a result.
The decision itself is worth making against a written requirement rather than a feeling. If the requirement reads as data of a certain class does not leave our perimeter, or the build must run in a network unreachable from outside, then a self-hosted executor belongs. If it reads as we would like more control, that is a preference rather than a requirement, and it will cost more than it appears. It is also worth remembering that two decisions are independent: where the executor lives, and how it reaches closed resources. The managed cloud together with private connectivity to an internal repository covers many of the cases for which teams set out to stand up an entire runtime of their own.
The engineering conclusion is simple: choose your own runtime when you have someone to operate it. If the answer to who patches the images and who is on call for incidents sounds uncertain, the managed cloud with a narrow policy will be both safer and cheaper. And private connectivity is deployed for a specific requirement rather than just in case: it has its own price too, in network plumbing, names and token lifecycles.
The typical failures are predictable. Believing a self-hosted executor is safer by definition. Designing private access on self-signed certificates and non-standard ports. Deploying a pool without an owner, monitoring and an upgrade plan. Not noticing that the queue is growing while the team waits. And moving into your own infrastructure what lived perfectly well in a managed environment, for the sake of a feeling of control.