The VM. What runs your branch, and its limits.
Each environment is one Firecracker micro-VM holding your files, your app, its own database (Postgres 16, MySQL 8.4 or SQLite) and, if you ask for it, Redis. This page says what is in it, what it can reach and where its limits are.
Size
| Resource | Per VM |
|---|---|
| CPU | 2 vCPU |
| Memory | 2 GB, shared by your app, its build steps, its database and Redis |
| App disk | 3 GB unless the host sets more. It holds the uploaded tree (/srv/app), $HOME, node_modules and every package cache |
A step that uses more memory than the VM has is killed, and the log says so: "killed: out of memory". Lower the build's parallelism (-j1, --workspace-concurrency=1) or its heap (NODE_OPTIONS=--max-old-space-size=1024). Large monorepo builds can still outgrow 2 GB.
Runtime images
runtime: | What it adds |
|---|---|
node22 (default), node24 | Node with npm |
python312, python314 | CPython with pip and uv. C extensions, and programs that embed Python such as uwsgi, build and load. |
go | Go, with GOTOOLCHAIN=local. cgo builds. |
ruby33 | Ruby 3.3 and Bundler. Run gem commands with bundle exec. |
php83 | PHP 8.3 CLI with pdo_pgsql, mbstring, intl, gd, zip, bcmath, xml and curl, and Composer. Serve with php -S 0.0.0.0:$PORT -t public or your app's own server. |
- Every image has Node (22, or 24 in
node24), npm and corepack'spnpmandyarn, so a Go, Python, Ruby or PHP app can build its JavaScript frontend in the sameinstall. - Every image has gcc and g++, make, git, pkg-config,
psql, and the headers of libpq, OpenSSL, zlib, libffi, libmagic, libjpeg, libpng, libwebp, libxml2, libxslt and libyaml. - There is no root and no package manager for the system: nothing can be added to an image. ImageMagick and libvips are not there.
- Postgres 16. Your app's database role owns its database but is not a superuser, and cannot create roles or databases. Trusted extensions such as
pgcrypto,hstore,citextanduuid-osspwork; listvector(pgvector 0.8.6) orpg_stat_statementsunderdatabase: extensions:inkarts.ymland Karts creates them. PostGIS is not installed. - With
database: mysql, MySQL 8.4 runs in the VM instead. Withdatabase: sqlite, the app gets its own SQLite file. See MySQL and SQLite.
Network
A VM has no internet access unless your project turns it on. The build steps (install, migrate, seed and service build) reach the public package registries through a Karts registry proxy on the host, and nothing else, even with internet access on. By default, your running app and karts exec reach nothing outside the VM, apart from linked environments. With fakes: or stubs:, the app's calls to outside services are answered inside the VM by test stand-ins.
With internet: in karts.yml, the running app and karts exec can also reach the hosts it allows: named presets, hosts you list, or every public host. Each connection leaves through an exit server that Karts runs. Ports 25 and 53, IP addresses, private addresses and other environments stay refused, and so do known production hosts unless a team owner approves them. Each environment and team has limits, and karts egress log shows every connection.
| Reachable during a build | Not reachable |
|---|---|
| registry.npmjs.org pypi.org and files.pythonhosted.org proxy.golang.org and sum.golang.org rubygems.org and Packagist (with its GitHub downloads) Prisma's engines, GitHub release and commit downloads, Cypress and browser downloads, through the proxy While packages install and services build: public github.com, Google Fonts and a few download hosts, through an HTTPS tunnel |
Every other host, including private registries, private or non-GitHub git repositories, git@ URLs and URLs in requirements.txt. They fail with a DNS error. |
Karts points the tools at the proxy with npm_config_registry, pnpm_config_registry, COREPACK_NPM_REGISTRY, YARN_NPM_REGISTRY_SERVER, PIP_INDEX_URL, UV_DEFAULT_INDEX, UV_INDEX_URL and GOPROXY. Do not unset them. These package managers work through it as written, with no extra flags:
| Tool | Notes |
|---|---|
| npm | npm ci and npm install. A package-lock.json whose URLs name registry.yarnpkg.com works too. |
| pnpm | Any version: pnpm, corepack pnpm, or pnpm called from a package script. |
| Yarn | Yarn 1, and Yarn 2 and later. Karts points a Yarn 1 yarn.lock at the proxy for the build and restores it before your app starts; the build log says so. |
| pip | pip install -r requirements.txt. pip's own config files are ignored. |
| uv | uv sync --locked and --frozen. Karts points uv.lock at the proxy for the build and restores it. |
| Go modules | go build and go mod download. |
- A download the app does not need at run time can often be skipped:
CYPRESS_INSTALL_BINARY=0,PUPPETEER_SKIP_DOWNLOAD=1. Otherwise the app cannot build on Karts yet. - Ruby and PHP apps: rubygems.org and Packagist are not reachable, so
bundle installandcomposer installwork only from vendored packages (vendor/cache, or a committedvendor/). - Each VM may hold 256 connections to the proxy at once. More wait, then get
503withRetry-After, which the tools retry. - Dependencies are installed from nothing on every build, except when
installis exactlynpm ci, every package comes from the registry with an integrity hash, and nothing has an install script. Then Karts installs once and reuses the result.
Upload limits
| Limit | Value |
|---|---|
| Files in one upload | 50,000 |
| Total size | 512 MiB |
| One file | 100 MiB |
karts up uploads tracked files and untracked files git does not ignore, and never .git/. Git submodules are uploaded as their checked-out files, so run git submodule update --init --recursive first; untracked nested repositories are refused. Git-ignore build output and large files the app does not need. Only files the server does not already have are sent.
Team limits
| Limit | Value |
|---|---|
| Projects per team | 2. karts project delete frees one. |
| Environments per team | 5 at once, including backends started by links |
| Builds per team | 2 at once; more wait |
| Templates per project | 2. When the default branch moves a third time while an environment on the oldest base still serves, karts up asks you to take that environment down or update it. |
Time limits
| What | Limit |
|---|---|
| Each build step | 10 minutes for each of install, migrate, seed and every service build |
| SQL migrations | 5 minutes for each file Karts applies; 15 minutes for all of them |
| A whole build | 30 minutes |
| Health check | 60 seconds to answer below 500 |
| Crashes | the app is restarted with a growing delay; after 5 restarts within 10 minutes the service is marked crashed |
| Idle | an environment is taken down after 30 minutes with no request, API call or open logs or exec stream |
| Age | every environment is taken down after 8 hours |
| Logs | 100 MiB per revision |