Skip to main content

Kubernetes Ephemeral Volumes: A Practical Guide to emptyDir Volumes

tip

Use the manifest templates to create your own Kubernetes resources which can be used in the examples below.

In the world of Kubernetes storage, not every solution needs to be a complex, persistent, network-attached disk. Sometimes, all your application needs is a simple, temporary place to store files. This is where the fundamental emptyDir volume shines.

This guide will walk you through what emptyDir is, its key characteristics, and practical, hands-on examples to get you started.

What is an emptyDir Volume?

An emptyDir volume is a temporary directory that is created for a Pod when it is scheduled on a worker node. As its name suggests, it starts empty. All containers within the same Pod can read from and write to the same emptyDir volume, making it an excellent mechanism for sharing data between them.

The crucial thing to remember about emptyDir is its ephemeral nature. Its lifecycle is tied directly to the lifecycle of the Pod itself.

Key Characteristics

  1. Tied to Pod Lifetime: When a Pod is created, the emptyDir is created. When the Pod is deleted (for any reason), the data in the emptyDir is permanently lost.
  2. Shared Within a Pod: All containers in a Pod can share the same emptyDir volume. They just need to mount it at the same or different paths.
  3. Survives Container Restarts: If a container crashes and restarts, the data in the emptyDir volume persists. This is a key feature that makes it more useful than just writing to a container's own filesystem, which is lost on restart.
  4. Node-Local: The physical storage for an emptyDir is located on the specific worker node where the Pod is running. This means a Pod cannot be moved to another node and retain its emptyDir data.
  5. Disk or Memory-Backed: By default, emptyDir volumes are backed by the node's primary storage (the disk that holds the kubelet's files). You can also configure it to be backed by RAM for higher performance.

Hands-On Examples

Let's dive into some practical use cases to see emptyDir in action.

Use Case 1: Simple Scratch Space

This is the most common use case: an application needs a temporary directory to store files during its execution, like for processing data or caching assets.

Step 1: Create the Pod Manifest

Create a file named pod-emptydir.yaml. This Pod has a single container that writes the current date to a file every 5 seconds.

# pod-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: scratch-space-pod
spec:
containers:
- name: main-app
image: busybox
# This command writes the date to a log file in the cache directory every 5 seconds
command: ["/bin/sh", "-c", "while true; do date >> /cache/log.txt; sleep 5; done"]
volumeMounts:
- name: cache-volume # This name must match the volume name below
mountPath: /cache # The path where the volume will be mounted inside the container
volumes:
- name: cache-volume # A unique name for the volume within this Pod
emptyDir: {} # The type of volume is emptyDir

Step 2: Deploy and Verify

  1. Deploy the Pod:

    kubectl apply -f pod-emptydir.yaml
  2. Check the data: Wait a few moments, then exec into the Pod to see the contents of the file.

    # Get a shell inside the running container
    kubectl exec -it scratch-space-pod -- /bin/sh

    # Inside the container, view the log file
    / # cat /cache/log.txt
    Sun Jun 8 15:15:05 UTC 2025
    Sun Jun 8 15:15:10 UTC 2025
    Sun Jun 8 15:15:15 UTC 2025

    # Exit the container
    / # exit
  3. Clean up: Now, delete the Pod and see what happens.

    kubectl delete pod scratch-space-pod

    The Pod is gone, and the /cache/log.txt file, along with the entire emptyDir volume, has been permanently deleted from the worker node.

Use Case 2: Sharing Data Between Containers

This example demonstrates how two containers in the same Pod can communicate using a shared emptyDir volume. One container will act as a "producer," writing data, and the other will be a "consumer," reading that data.

Step 1: Create the Pod Manifest

Create a file named pod-shared.yaml.

# pod-shared.yaml
apiVersion: v1
kind: Pod
metadata:
name: shared-data-pod
spec:
# This container writes "Hello from the producer!" into index.html
containers:
- name: producer
image: busybox
command: ["/bin/sh", "-c", "echo 'Hello from the producer!' > /workdir/index.html && sleep 3600"]
volumeMounts:
- name: shared-workdir
mountPath: /workdir

# This container acts like a web server, serving the file written by the producer
- name: consumer
image: nginx:alpine
volumeMounts:
- name: shared-workdir
mountPath: /usr/share/nginx/html # Mount the shared volume into nginx's web root
readOnly: true # Good practice: the consumer only needs to read

volumes:
- name: shared-workdir
emptyDir: {}

Step 2: Deploy and Verify

  1. Deploy the Pod:

    kubectl apply -f pod-shared.yaml
  2. Verify the consumer can see the data: We can exec into the consumer container (the NGINX server) and use curl to request the file that the producer created.

    # Get a shell inside the 'consumer' container
    kubectl exec -it shared-data-pod -c consumer -- /bin/sh

    # Inside the container, use curl to access the web server locally
    / # curl http://localhost/index.html
    Hello from the producer!

    # Exit the container
    / # exit

This works perfectly! The producer wrote a file into the shared emptyDir, and the consumer was able to immediately read and serve it, demonstrating seamless data sharing within the Pod.


Advanced: Using Memory as a Backend

For performance-sensitive applications, like a high-speed cache, writing to disk can be a bottleneck. You can instruct Kubernetes to create the emptyDir as a tmpfs volume, which is backed by the node's RAM instead of its disk.

Warning: Using memory for your emptyDir counts against your container's memory limit. If you fill up the tmpfs volume, you risk the container being OOMKilled (Out Of Memory).

Example Manifest with medium: Memory

# pod-memory.yaml
apiVersion: v1
kind: Pod
metadata:
name: memory-backed-pod
spec:
containers:
- name: fast-cache-app
image: busybox
command: ["/bin/sh", "-c", "sleep 3600"]
volumeMounts:
- name: cache-in-ram
mountPath: /fast-cache
volumes:
- name: cache-in-ram
emptyDir:
medium: Memory # This is the key change
sizeLimit: 256Mi # It's wise to set a size limit

When you deploy this Pod, the /fast-cache directory will be a RAM-backed filesystem, offering significantly higher I/O performance than the default disk-backed option.

When to Use emptyDir (and When Not To)

Use emptyDir for:

  • Temporary scratch space for data processing.
  • Caching frequently accessed data.
  • Sharing files and configuration between containers in a single Pod.
  • A holding area for long-running computations that can survive a container restart.

Do NOT use emptyDir for:

  • Storing persistent application data like databases or user uploads.
  • Sharing data between different Pods.
  • Any data that you cannot afford to lose when a Pod is rescheduled to a different node.

For those use cases, you should use PersistentVolumes. But for simple, ephemeral storage needs, emptyDir is a powerful, efficient, and easy-to-use tool in your Kubernetes arsenal.