# How to run Go code in a sandbox Install Go in an isolated Linux microVM with apt or the official tarball, write `main.go`, and run it with `go run` under a timeout. **On Runtime, Go is one apt command away in every sandbox, or already there in an image you build once.** Each sandbox is a Firecracker microVM with its own kernel, with `sudo` and `gcc` ready. The code interpreter runs Go cells too: on 23 September 2026 its first Go cell in a sandbox installed Go from Ubuntu's archive in about 35 seconds, once ([code interpreter](/docs/javascript#code-interpreter)). A 2 vCPU, 4 GiB sandbox costs $0.08 an hour while it compiles and $0.03125 while it waits ([pricing](/docs/pricing)). ## Which Go to install | Source | Command | Go version on 25 September 2026 | | ---------------------------- | ---------------------------------------------------- | ------------------------------- | | Ubuntu 24.04 archive | `sudo apt-get install -y golang-go` | 1.22.2 (`golang-1.22-go`) | | Official tarball from go.dev | `tar -C /usr/local -xzf go1.27.1.linux-amd64.tar.gz` | 1.27.1 | The code interpreter installs Go from Ubuntu's archive as well. Take the tarball when your module's `go` line asks for a newer release. ## Install Go and run a program ```ts check import { Sandbox } from "withruntime"; const program = `package main import ( "fmt" "sort" ) func main() { xs := []int{42, 7, 19, 3} sort.Ints(xs) fmt.Println(xs) } `; await using sbx = await Sandbox.create({ timeoutSeconds: 600, onLeaseEnd: "stop" }); await sbx.exec("sudo apt-get update -q && sudo apt-get install -y -q golang-go", { check: true, timeoutMs: 300_000, }); await sbx.network.set({ internet: false }); // the program itself gets no network await sbx.files.write("/workspace/job/main.go", program); const run = await sbx.exec(["go", "run", "main.go"], { cwd: "/workspace/job", timeoutMs: 120_000 }); console.log(run.exitCode, run.stdout); // 0 [3 7 19 42] ``` ```python check from withruntime import Sandbox program = """package main import ( \t"fmt" \t"sort" ) func main() { \txs := []int{42, 7, 19, 3} \tsort.Ints(xs) \tfmt.Println(xs) } """ with Sandbox.create(timeout_seconds=600, on_lease_end="stop") as sbx: sbx.exec("sudo apt-get update -q && sudo apt-get install -y -q golang-go", check=True, timeout_ms=300_000) sbx.network.set(internet=False) # the program itself gets no network sbx.files.write("/workspace/job/main.go", program) run = sbx.exec(["go", "run", "main.go"], cwd="/workspace/job", timeout_ms=120_000) print(run.exit_code, run.stdout) # 0 [3 7 19 42] ``` - `files.write` makes the parent directories. - `go run` compiles before it runs, so give it more time than a script. A command that runs out of time comes back with `timedOut: true` and its output so far, rather than throwing. - The apt install needs the internet; the program does not, so the network goes off in between. ## The newest Go from go.dev The official Linux steps extract the tarball into `/usr/local` and add `/usr/local/go/bin` to `PATH` ([Go install](https://go.dev/doc/install)). Link the binaries into `/usr/local/bin`, which is already on the sandbox user's `PATH`: ```bash no-run curl -fsSL https://go.dev/dl/go1.27.1.linux-amd64.tar.gz | sudo tar -C /usr/local -xz sudo ln -sf /usr/local/go/bin/go /usr/local/go/bin/gofmt /usr/local/bin/ go version ``` ## Modules with dependencies Upload the module, download its dependencies with the internet on, then cut it off and run the tests. Nothing the tests do can reach the network. ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ image: "go", timeoutSeconds: 1800, onLeaseEnd: "stop" }); await sbx.files.upload("./service", "/workspace/service"); await sbx.exec("go mod download", { cwd: "/workspace/service", check: true, timeoutMs: 300_000 }); await sbx.network.set({ internet: false }); const test = await sbx.exec(["go", "test", "./..."], { cwd: "/workspace/service", timeoutMs: 900_000, onStdout: (text) => process.stdout.write(text), }); console.log("exit", test.exitCode); ``` This uses the `go` image built below. ## A Go notebook: the code interpreter Runtime's code interpreter keeps a Go context's functions, types and imports between cells and runs each cell as a program, so values do not carry over but declarations do: ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create(); await sbx.interpreter.run( "func fib(n int) int {\n\tif n < 2 {\n\t\treturn n\n\t}\n\treturn fib(n-1) + fib(n-2)\n}", { language: "go", }, ); const cell = await sbx.interpreter.run('import "fmt"\nfmt.Println(fib(20))', { language: "go" }); console.log(cell.stdout); // 6765 ``` ```python check from withruntime import Sandbox with Sandbox.create() as sbx: sbx.interpreter.run("func fib(n int) int {\n\tif n < 2 {\n\t\treturn n\n\t}\n\treturn fib(n-1) + fib(n-2)\n}", language="go") cell = sbx.interpreter.run('import "fmt"\nfmt.Println(fib(20))', language="go") print(cell["stdout"]) # 6765 ``` The first Go cell installs Go from Ubuntu's archive, so that sandbox needs the internet for it. An image with Go skips both the wait and the network. ## Go in every sandbox ```ts check import { Runtime } from "withruntime"; const runtime = new Runtime(); await runtime.images.build({ name: "go", recipe: { apt: ["golang-go"] } }); // Or the newest release, from the official tarball: await runtime.images.build({ name: "go-latest", recipe: { commands: [ "curl -fsSL https://go.dev/dl/go1.27.1.linux-amd64.tar.gz | tar -C /usr/local -xz", "ln -sf /usr/local/go/bin/go /usr/local/go/bin/gofmt /usr/local/bin/", ], }, }); ``` ```python check from withruntime import Runtime runtime = Runtime() runtime.images.build(name="go", recipe={"apt": ["golang-go"]}) runtime.images.build(name="go-latest", recipe={"commands": [ "curl -fsSL https://go.dev/dl/go1.27.1.linux-amd64.tar.gz | tar -C /usr/local -xz", "ln -sf /usr/local/go/bin/go /usr/local/go/bin/gofmt /usr/local/bin/", ]}) ``` Recipe commands run as root. Building is free; a stored image is charged on its size ([custom images](/docs/images)). ## Related - [Run Rust code in a sandbox](/languages/rust) - [Run Java code in a sandbox](/languages/java) - [Grade student code](/use-cases/grade-student-code) - [Agent evals and SWE-bench](/use-cases/agent-evals-and-swe-bench) - [Run Docker in a sandbox](/how-to/run-docker-in-a-sandbox) New accounts get 50 free sandbox hours, no card: ```bash no-run npx withruntime sandbox run --trial -- bash -c 'sudo apt-get update -q && sudo apt-get install -y -q golang-go && go version' ``` ## Sources - Ubuntu 24.04 package indexes for noble, noble-updates and noble-security (`golang-go` 2:1.22~2build1, `golang-1.22-go` 1.22.2-2ubuntu0.4): http://archive.ubuntu.com/ubuntu/dists/noble-updates/main/binary-amd64/ (read 25 September 2026) - Go downloads, current release go1.27.1: https://go.dev/dl/ (read 25 September 2026) - Go installation steps: https://go.dev/doc/install (read 25 September 2026) Facts on this page were checked on 25 September 2026.