# What a container gets

Every service runs as a container: your image, started on one of the servers, at the size you
choose: its memory and the cores that come with it. Disk speed isn't limited or charged: a container
reads and writes as fast as the server's disk does.

## What it gets

Its size, from xs (a quarter of a core and 256 MB) to 5xl (32 cores and 64 GB); an app gets s (half
a core and 512 MB) unless it says. Its server keeps that much for it, and it's billed for it each
hour it's awake ([sizes and prices](/docs/usage#sizes)). Under **Scaling** you choose another, and
it's given to the running containers at once: nothing restarts.

The two limits behave differently when you reach them, and the difference matters when something
is slow:

- **Memory** is a wall. Over it, the container is stopped and started again. It can't be slowed
  down there instead (nothing could free the memory but swap, which would slow its neighbours), so
  you're told before it happens: when it stays above 90% of its memory, its **Overview** says so
  and your notification channels hear "nearly out of memory", and they hear it too if it was
  restarted for running out. The fix is a bigger size under **Scaling**.
- **CPU** is a ceiling. At it, the container runs slower — it is never killed for being busy. The
  CPU chart draws the limit beside the reading, so you can see the difference between busy and
  throttled.

If your work needs more CPU — a build, a transcode, anything that computes more than it remembers —
give it a bigger size: each one has twice the cores of the one before (up to 32).

## Its own filesystem

A container can write anywhere inside itself, but what it writes there doesn't survive a deploy and
doesn't go on the server's disk: it comes out of the container's memory. So a service that writes a
few hundred megabytes of scratch files needs the memory to hold them.

Anything you want to keep goes in a [volume](/docs/volumes).

## Volumes have a size that is really enforced

A volume is given a filesystem of its own, with the size you choose. Writing past the end fails
the way a full disk always has — the program gets "no space left on device" — and nothing else on
the server notices. Your database stays up and readable instead of being stopped, which is the
whole reason it works this way.

Its size is set aside on its server's disk, and it's billed by it, full or not. It can be made
bigger or smaller (down to what it holds) as it runs, or told to grow by itself as it fills, up to a
limit you choose.

## What a container can't do

Every container runs in a virtual machine of its own, [Kata Containers](https://katacontainers.io),
with its own Linux kernel and the processor's hardware virtualization between it and the machine:
your apps', your databases', your computers', the terminals you open in them, and every step of a
build. A bug in a kernel is then not a way out of the container, which is what makes it safe to run
different organizations' code on one machine. There are no exceptions, and a server that can't do
it runs nothing at all. If you'd rather have machines to yourself anyway,
[private servers](/docs/servers#private-servers) are the answer.

Because it's a real kernel, programs run as they would on the machine itself: a database's
commits, a build's steps, anything that leans on the kernel. What the VM costs is a little memory
for its own kernel, which comes on top of the container's size rather than out of it, and a moment
more when it starts from cold. A container asleep is a paused VM, so waking it is quick.

Beyond that, a container is created without the powers nothing ordinary needs:

- **No raw sockets.** This is the one that matters most: raw sockets would let a container forge
  ARP and DNS replies to its neighbours on the same server, and that needs no clever exploit at
  all, just a socket.
- **No device nodes, no chroot, no writing to the host's audit log**, and no way to hand itself
  further powers later.
- **A cap on processes and threads**, by size, so a runaway can't exhaust the server's process
  table. It's generous — thousands — because a database with many connections and a runtime with a
  thread pool are both perfectly normal.

What's kept is what ordinary images need: a container can still start as root and drop to its own
user, own its files, and bind to low ports. Postgres, nginx, Redis and the rest run unchanged.

## What's shared and what isn't

Each project has its own private network. Services in it reach each other by name; nothing else
can, whether it belongs to you or to anyone else, on the same server or across servers.

On a shared server, containers from different organizations run on one machine, each with its own
memory, CPU, filesystem and network. What they share is the machine itself — and
everything above is about making that sharing uneventful.
