Skip to content
Runtime

How to run a Gradio demo in a sandbox instead of a share link

Build Gradio and your app into an image whose start command runs it on port 7860, create a sandbox from it, and share 7860 as a preview.

On Runtime the demo's address lasts as long as you keep the sandbox, and it can be private. A Gradio share link expires after a week, and anyone with the link can open it. A Runtime preview refuses requests without its token unless you make it public. It stays up for as long as you keep the sandbox. On a paid account, it can be served from your own domain. Gradio 6.30.0 was current on 25 October 2026.

Question share=True Runtime preview
Where the app runs Your machine, or wherever launch() runs A Firecracker microVM of its own
How long the link lasts Expires after 1 week For as long as the sandbox and its preview exist
Who can open it Anyone with the link Token holders by default, or anyone when public
Traffic goes through Gradio's share servers, as a proxy Runtime's preview edge

Build the demo into an image

An image sets the command a sandbox runs at start and the check that marks it ready. With readyPort: 7860, the create call returns once Gradio is listening, so the link works as soon as you have it:

dockerfileFROM runtimeENV GRADIO_ANALYTICS_ENABLED=FalseRUN pip install --no-cache-dir gradio==6.30.0COPY app.py /workspace/app.pyRUN chown 1000:1000 /workspace/app.py
TypeScriptimport { readFile } from "node:fs/promises";import { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build(  {    name: "shout-demo",    dockerfile: await readFile("demo/Dockerfile", "utf8"),    contextDir: "demo",    start: { command: "python3 /workspace/app.py", readyPort: 7860, readyTimeoutSeconds: 120 },  },  { onLog: (line) => console.log(line.text) },);const sbx = await runtime.sandboxes.create({ image: "shout-demo", timeoutSeconds: 3600 });console.log(sbx.info.start); // { state: "ready", ... } once Gradio listensconst preview = await sbx.previews.create(7860);console.log(preview.urlWithToken);
Pythonfrom withruntime import Runtimeruntime = Runtime()with open("demo/Dockerfile") as handle:    runtime.images.build(        name="shout-demo",        dockerfile=handle.read(),        context_dir="demo",        start={"command": "python3 /workspace/app.py", "ready_port": 7860, "ready_timeout_seconds": 120},    )sbx = runtime.sandboxes.create(image="shout-demo", timeout_seconds=3600)print(sbx.info["start"])print(sbx.previews.create(7860)["urlWithToken"])

The app is plain Gradio. It calls launch() without share:

Pythonimport gradio as grdef shout(text: str) -> str:    return text.upper()demo = gr.Interface(fn=shout, inputs="text", outputs="text")demo.launch()

By default, Gradio listens on 127.0.0.1:7860. A preview reaches that address from inside the sandbox. Set GRADIO_SERVER_PORT to change the port. With GRADIO_ANALYTICS_ENABLED=False in the image, Gradio turns off its analytics.

Call the demo from code

Every Gradio app serves an HTTP API as well as its page. A private preview takes the token in a header, so a test or an agent can call the demo directly. The endpoint is named after the function. Here it is shout.

TypeScriptimport { Sandbox } from "withruntime";const sbx = await Sandbox.connect(process.env.SANDBOX_ID ?? "");const preview = await sbx.previews.create(7860);const headers = { "x-runtime-preview-token": preview.token!, "content-type": "application/json" };const queued = await fetch(new URL("gradio_api/call/shout", preview.url), {  method: "POST",  headers,  body: JSON.stringify({ data: ["hello"] }),});const { event_id } = (await queued.json()) as { event_id: string };const result = await fetch(new URL(`gradio_api/call/shout/${event_id}`, preview.url), { headers });console.log(await result.text()); // event: complete / data: ["HELLO"]

The first call queues the request and returns an event_id. The second call streams the result as server-sent events. In a test on 25 October 2026, Gradio 6.30.0 returned data: ["HI"] for the input hi.

Make it public, or keep it to reviewers

Want Do
Only you Open urlWithToken once in your browser
A reviewer Send them a fresh urlWithToken
Anyone, on a paid sandbox previews.create(7860, { visibility: "public" })
Cut off every link handed out so far previews.rotate(7860)
A login inside the app as well demo.launch(auth=("admin", password))
Your own hostname A custom domain on a paid account (networking)

Models and memory

A demo that loads a model at start needs memory for the model and disk for its files. Request both when you create the sandbox, with memoryMiB and diskMiB. Set the image's ready check time with readyTimeoutSeconds, up to 300. For Hugging Face models on CPU, see Transformers in a sandbox.

A sandbox runs while people use the app. It pauses itself when nobody has visited for idlePauseSeconds, and the app stays in memory. A visit to the preview wakes a paused sandbox and shows a short "Waking up" page.

Sources

Checked 25 October 2026.

  • Sharing your app: share links expire after 1 week, the share servers act as a proxy, and auth=
  • Gradio environment variables: GRADIO_SERVER_PORT (7860), GRADIO_SERVER_NAME (127.0.0.1), GRADIO_ANALYTICS_ENABLED
  • gradio on PyPI: version 6.30.0, Python 3.10 or later
  • A local test of Gradio 6.30.0 on 25 October 2026: POST /gradio_api/call/shout returned an event_id, and GET /gradio_api/call/shout/<event_id> returned event: complete with data: ["HI"]

Facts on this page were checked on 25 October 2026.

100 free hoursin your first 30 days.

of a 1 GB machine

  • No credit card
  • Four sandboxes at once, 2 vCPU and 4 GiB each
  • Then prepaid credit from $10, no plan fee
Start free, no card
Start free, no card