Skip to main content

Containerized / Isolated execution

Your code runs safely with our containerized approach.

Written by Jamie Gaynor

Everything Tines 3B runs, whether it's a workflow step, a quick experiment in chat, or a connection test, runs inside its own container. That container is a sealed, throwaway environment created just for that one piece of work and destroyed right after. This model is what lets Tines 3B run real code safely, give each step exactly the tools it needs, and keep one execution from ever touching another.

Every step runs in its own container

A step in Tines 3B is more than a snippet of code. It's a small container image, defined by a Dockerfile alongside your code in a language like TypeScript, Python, or shell. The Dockerfile always starts from Tines 3B's own base image, and from there a step can install packages, add files, and set itself up however it needs. When the step runs, Tines 3B builds that image and executes your command inside a fresh container.

Because each step brings its own environment, steps don't have to share one big runtime or agree on which libraries are installed. One step can run Python with a data library, the next can run a shell script, and neither interferes with the other.

Build once, then run fast

Execution happens in two phases:

  • First is the build, where Tines 3B turns your Dockerfile into a runnable image, one layer at a time.

  • Second is the run, where your command actually executes.

Splitting them matters because builds are cached: Tines 3B reuses layers that haven't changed, so the slow setup work happens once and later runs skip straight to executing. A step you run over and over stays quick, even though it's a full container underneath.

Isolated and single-use

The container each execution runs in is strongly isolated from the host machine and from every other execution. Tines 3B runs your code inside a gVisor sandbox, an extra layer between the code and the real kernel, with the filesystem read only except for the scratch space a step is given, and with privileges stripped down as far as they'll go.

Crucially, these sandboxes are single-use. After your code finishes, Tines 3B destroys the sandbox entirely and starts the next execution in a brand new one restored from a clean checkpoint. Nothing left behind by one run, whether a stray file, a lingering process, or leftover memory, can ever carry into another. To keep this fast, Tines 3B keeps a warm pool of ready sandboxes so there's always a clean one waiting.

Controlled network access

Code in a sandbox can't reach the network directly. Every outbound request passes through Tines 3B's egress proxy, which is where a lot of Tines 3B's safety and convenience come from:

  • Credentials are injected here. When a step calls a connector's API, it makes a plain, unauthenticated request and the proxy adds the right authentication on the way out, so secrets never live in your code.

  • Dangerous destinations are blocked. The proxy refuses connections to private and internal addresses, which stops a step from being tricked into reaching somewhere it shouldn't.

  • Networks are applied here. If a space routes traffic through a network, the proxy is what enforces that routing.

The result is that a step gets exactly the access it's supposed to have, decided outside the sandbox where your code can't override it.

Guardrails on every run

Since executions run real, arbitrary code, Tines 3B puts firm limits around them.

  • Each run has a time budget and is stopped if it overruns.

  • Memory is capped, and a step that exceeds it is killed rather than allowed to starve the machine.

  • Network throughput is shaped so no single step can saturate the pipe.

These guardrails run at the platform level, so they apply no matter what a step's code tries to do.

What lasts and what doesn't

Because containers are thrown away after each run, most of what a step writes is temporary. Its working directory and scratch space vanish when the run ends. The exception is storage: files a step writes into a /storage volume are durable and persist across runs, because they live outside the container in Tines 3B's storage layer. A step's normal output, its stdout, is captured and saved as the step's result, and its stderr becomes the step's log, streamed live as it runs.

Did this answer your question?