[Best practices for writing Dockerfiles](/manuals/build/building/best-practices.md)
and [use multi-stage builds](/manuals/build/building/multi-stage.md)
sections to learn how to optimize your Dockerfiles for efficient images.
The layers are stacked on top of each other. When you create a new container,
you add a new writable layer on top of the underlying layers. This layer is often
called the "container layer". All changes made to the running container, such as
writing new files, modifying existing files, and deleting files, are written to
this thin writable container layer. The diagram below shows a container based
on an `ubuntu:15.04` image.

A storage driver handles the details about the way these layers interact with
each other. Different storage drivers are available, which have advantages
and disadvantages in different situations.
## Container and layers
The major difference between a container and an image is the top writable layer.
All writes to the container that add new or modify existing data are stored in
this writable layer. When the container is deleted, the writable layer is also
deleted. The underlying image remains unchanged.
Because each container has its own writable container layer, and all changes are
stored in this container layer, multiple containers can share access to the same
underlying image and yet have their own data state. The diagram below shows
multiple containers sharing the same Ubuntu 15.04 image.

Docker uses storage drivers to manage the contents of the image layers and the
writable container layer. Each storage driver handles the implementation
differently, but all drivers use stackable image layers and the copy-on-write
(CoW) strategy.
> [!NOTE]
>
> Use Docker volumes if you need multiple containers to have shared access to
> the exact same data. Refer to the [volumes section](../volumes.md) to learn
> about volumes.
## Container size on disk
To view the approximate size of a running container, you can use the `docker ps -s`
command. Two different columns relate to size.
- `size`: the amount of data (on disk) that's used for the writable layer of
each container.
- `virtual size`: the amount of data used for the read-only image data
used by the container plus the container's writable layer `size`.
Multiple containers may share some or all read-only
image data. Two containers started from the same image share 100% of the
read-only data, while two containers with different images which have layers
in common share those common layers. Therefore, you can't just total the
virtual sizes. This over-estimates the total disk usage by a potentially
non-trivial amount.
The total disk space used by all of the running containers on disk is some
combination of each container's `size` and the `virtual size` values. If
multiple containers started from the same exact image, the total size on disk for
these containers would be SUM (`size` of containers) plus one image size
(`virtual size` - `size`).
This also doesn't count the following additional ways a container can take up
disk space:
- Disk space used for log files stored by the [logging-driver](/manuals/engine/logging/_index.md).
This can be non-trivial if your container generates a large amount of logging
data and log rotation isn't configured.
- Volumes and bind mounts used by the container.
- Disk space used for the container's configuration files, which are typically
small.
- Memory written to disk (if swapping is enabled).
- Checkpoints, if you're using the experimental checkpoint/restore feature.
## The copy-on-write (CoW) strategy
Copy-on-write is a strategy of sharing and copying files for maximum efficiency.