Cortex Sandboxes limitations and FAQ¶
Feature availability¶
- Status: Private preview. Access is enabled per account by Snowflake.
- Compute: Sandboxes run on CPU.
- Access control: Enabled per account during private preview. To request access, contact your Snowflake account representative. See Cortex Sandboxes concepts and security for the access model.
Private preview limitations¶
The following are not supported in private preview:
- External base images. A base image must come from Snowflake: either a catalog image (a bare name such as
sandbox-base, orNAME:TAG) or an image in your own Snowflake image repository (a hostless/db/schema/repo/image:tagpath). Pulling a base image from Docker Hub, ECR, or any other external registry is not supported — a reference that names a registry host or carries a URL scheme is rejected. Adding layers on top of a base image is also temporarily unavailable and will return in a later release — install extra dependencies into the running sandbox instead, as shown in the FAQ below. - Non-Python SDK. The SDK is Python-only in private preview, and requires Python 3.11 or later.
- Non-Linux images. Only Linux images are supported.
- Formal SLA commitments. Private preview ships without an SLA.
- Automatic expiry. No sandbox expires on its own. There is no TTL and nothing deletes an unused sandbox for you.
Sandbox.create()has noexpires_afterortimeoutparameter, so passing either raises aTypeErrorbefore any request is sent; a raw REST caller that sets the underlying field gets a400. The platform suspends an idle sandbox (so it stops consuming compute) but does not remove it, so callsb.terminate()when you are done. To find sandboxes you no longer need, useSandbox.list(),snow sandbox list, or Snowsight under AI » Sandboxes. - Filesystem snapshots and image mounts.
snapshot_filesystem(),snapshot_directory(),mount_image(), andunmount_image()are surfaced on the SDK but have no backend, and raiseSandboxNotImplementedError. - Port forwarding and tunnels.
tunnels()andcreate_connect_token()raiseSandboxNotImplementedError, so there is no tunnel to a port inside a sandbox and no way to mint short-lived credentials for one. Reach a sandbox throughexecand the file and log APIs. - Server-side stage transfers.
stage_put()andstage_get()return501on every backend. Mount the stage withStageMountand read or write through the mount instead. - Caller-supplied egress host lists. Naming arbitrary hosts on
Egressis retired — hosts listed that way are not enforced and not reachable, so the SDK refuses them locally. Grant a host outside the platform baseline with an external access integration and name that instead.
The platform also enforces the following limits. Each is reported as an error on the request that exceeds it, except where noted.
- 100 live sandboxes per user, per account by default. A create past the cap is refused with a
429. The cap is a guardrail against a runaway create loop rather than an exact limit: under concurrent creates, the number of live sandboxes can briefly exceed 100. Only terminated and failed sandboxes stop counting — a suspended sandbox still occupies a slot, so suspending one to stop it consuming compute does not free capacity. The service response names the live count, the cap, and the fix, but the Python SDK does not currently surface it:Sandbox.create()raisesSandboxRateLimitError("rate-limited after N retries")withretry_afterunset, which is indistinguishable from transient throttling. If you get that error with noretry_after, suspect this cap: retrying cannot clear it, so list your sandboxes and terminate what you no longer need. - 1 hour per
exec. A largertimeoutis clamped to one hour rather than refused, and anexecthat reaches it raisesSandboxExecTimeoutError. An untimedexecgets the same one-hour budget. For longer work, use a detached run (Sandbox.create(command=...)) andwait(). - 25 MiB per file transfer. A client-side size check refuses an oversize transfer before any bytes move, so
upload_file(),upload_dir(),write_text(), andwrite_bytes()raiseSandboxFileTooLargeErrorup front, andread_text()/read_bytes()raise it mid-stream with the server’s413as a backstop.upload_dir()checks the whole tree first, so a tree never half-uploads;dry_run=Truereports offenders inplan.oversizedinstead of raising. Mount a stage for bulk data. - 4 MiB per request body on every other route, including
exec. - 16 brokered secrets per sandbox.
- 64 environment variables, 16 KiB total. Some keys cannot be injected. Reserved by prefix:
SNOWFLAKE_,SANDBOX_, andCNG_SECRET_, which the platform owns. Reserved by exact name:PATH,LD_PRELOAD,LD_LIBRARY_PATH,HTTP_PROXY,HTTPS_PROXY,ALL_PROXY,NO_PROXY,REQUESTS_CA_BUNDLE,SSL_CERT_FILE,SSL_CERT_DIR, andCURL_CA_BUNDLE. Those exist so an environment map cannot quietly disable a security control: the proxy and CA variables are what route and verify the sandbox’s egress, and the loader variables would let injected code preload a library into every process. - 32 stage mounts per sandbox. A mount path may not replace or shadow
/etc,/usr,/bin,/sbin,/lib,/lib64,/proc,/sys,/dev,/boot, or/snowflake. - 32 MCP servers per sandbox.
- 64 tags (
labels), 8 KiB total. Tags can only be set at create; there is no relabel endpoint. - 1024 command arguments, 128 KiB total.
- 256 bytes for a sandbox name. The reserved
cntr_<24 lowercase hex characters>sandbox-ID form is rejected.
FAQ¶
What is Cortex Sandboxes?¶
Cortex Sandboxes is a secure, isolated execution environment for running AI-generated Python code, built into Snowflake and governed by your existing Snowflake security policies. You get a sandboxed container your AI agent can run code in, without your data leaving your Snowflake account.
How is it different from an external sandbox provider?¶
External sandbox providers run your code on their infrastructure, which means your data has to leave Snowflake. Cortex Sandboxes runs inside your Snowflake account—your masking policies, row-level security, and audit logs apply automatically, and nothing is shared with a third party.
How does it compare to Snowpark Container Services (SPCS)?¶
Cortex Sandboxes is designed for short-lived, per-task isolated containers that start quickly—the “one sandbox per agent invocation” pattern. SPCS is designed for long-running services and batch jobs. For agent workloads where you need to spin up many isolated environments and tear them down after each task, Sandbox is the right primitive. For persistent services, SPCS remains the right choice.
How does idle suspension work?¶
You do not have to terminate a sandbox to stop it consuming compute. An idle sandbox is suspended automatically and resumes on next use. The platform default idle window is 10 minutes.
To choose a different window, pass idle_suspend= to Sandbox.create() as a datetime.timedelta or a duration string such as "30m" or "1h30m". The resolution is minutes, so one minute is the smallest value you can set: anything finer, such as "90s", raises rather than being rounded, as do zero and negative values. Omit the argument to take the 10 minute default. On the CLI, snow sandbox run --detach applies a 24 hour window unless you pass --idle-suspend, because a detached run with no inbound traffic would otherwise suspend while still working.
To stop the compute now rather than waiting out the idle window, call sb.suspend() (or snow sandbox suspend). That banks the filesystem and tears the container down immediately, which is the fastest way to stop a sandbox consuming compute without deleting it.
What suspension does not do is delete the sandbox or release quota: a suspended sandbox still occupies one of your 100 live slots. Call sb.terminate() when the work is finished, and shorten idle_suspend if you want an abandoned sandbox to stop consuming compute sooner than the default.
Can I use my own secrets (API keys, database passwords) inside a sandbox?¶
Yes, with Snowflake SECRET objects. You declare a secret by name when you create the sandbox. The secret’s value is not placed in the container or the SDK. For how this works, see Cortex Sandboxes concepts and security.
Does it integrate with LangChain, LangGraph, CrewAI, or AutoGen?¶
Yes. The SDK is a plain Python library, so it works with any Python agent framework. Install whatever your agent needs into the running sandbox rather than assuming it is present:
Public PyPI is in the platform egress baseline, so this needs no egress configuration and no external access integration. The packages are fetched from public PyPI itself — pypi.org and files.pythonhosted.org are on the always-on package-manager host set, which permits GET and HEAD only.
What happens if my sandbox crashes or hangs?¶
The SDK surfaces specific exceptions (SandboxExecError, SandboxExecTimeoutError) with the exit code, stdout, and stderr so your application can handle failures gracefully. You can call sb.logs() to inspect what the container was doing, and sb.terminate() to tear it down and start a fresh one.