# Read-Only Mode

This guide explains how to **enable and use the read-only mode** in EventSourcingDB. In this mode, **all write operations are disabled**, while **reads and queries continue to work as usual**. This is useful for **maintenance**, **upgrades**, **migrations**, or any scenario where writing should be temporarily or permanently disallowed.

## Enabling Read-Only Mode

There are **two ways** to activate read-only mode:

- *(Changed in 1.3)* **Via API call**: Send a **`POST`** request to the **`/api/v1/put-into-read-only-mode`** endpoint:

    ```shell
    curl \
      -i \
      -X POST \
      -H "authorization: Bearer <API_TOKEN>" \
      http://localhost:3000/api/v1/put-into-read-only-mode
    ```

- **Via command-line flag**: Start EventSourcingDB with the **`--read-only` flag**:

    ```shell
    ./eventsourcingdb run [...] --read-only
    ```

Once enabled, the database will **reject all write attempts**. The mode **cannot be disabled dynamically**. To leave read-only mode, **restart EventSourcingDB and do not provide the `--read-only` flag**.

> **Read-Only Mode Ends With the Next Start**
>
> Read-only mode switched on via the API lasts **until EventSourcingDB is next started**, whether you restart it on purpose or not – for example when Kubernetes restarts its pod. Where writes must stay refused across restarts, **start EventSourcingDB with the `--read-only` flag** instead, for example in the manifest of its deployment.

## What Still Works

In read-only mode, the following operations remain **fully functional**:

- **Reading events** via the **[read API](/learn/tutorials/first-steps-with-eventsourcingdb/reading-events)**
- **Observing events** via the **[observe API](/learn/tutorials/first-steps-with-eventsourcingdb/observing-events)** (though no new events will arrive)
- **Running [EventQL queries](/docs/eventsourcingdb/v1.2/eventql)**

This allows you to continue processing projections, audits, and analyses without interruption.

## What Is Disabled

The following operations are **blocked** while read-only mode is active:

- **Writing** new events
- **Registering** new schemas
- Any other operation that **modifies stored data**

*(Changed in 1.3; Broken in 1.2, fixed in 1.3)* Clients attempting to write events will **receive `503 Service Unavailable`**, with the message `the current operation mode conflicts with the given request: writing is not permitted at this time`. The other operations are not refused this way: **registering an event schema** fails with `500 Internal Server Error`, and **restoring a backup** is not refused at all, but writes into the database anyway.

## Read-Only Mode While the Disk Is Almost Full *(Changed in 1.3)*

EventSourcingDB keeps a **reserve of 1 GiB** free on the file system that holds its data directory. Once less than that is free, it **refuses writes** and puts itself into read-only mode, and once at least 1 GiB is free again, it **accepts writes again by itself**, without a restart. It checks the free space **every 30 seconds**.

Clients whose writes are refused meanwhile receive **`503 Service Unavailable`**, as in read-only mode. The **[health endpoint](/docs/eventsourcingdb/v1.2/logging-and-monitoring)** reports this in its check **`system:diskRemaining`** with the status **`warn`**.

## Typical Use Cases

Read-only mode is helpful in a variety of operational contexts, including:

- **System maintenance**: Prevent accidental changes during backups or inspections.
- **Upgrades and migrations**: Freeze the system state to ensure consistency while transitioning to a new version.
- **Kiosk or analytics deployments**: Serve data without risk of mutation in dedicated read-only environments.

## Operating Safely in Read-Only Mode

Read-only mode provides a **simple but effective safeguard** when write access must be suspended. It helps **protect data integrity** while preserving access for consumers, dashboards, and downstream systems.

Use it to keep your system **transparent** and **stable** – even when changes are not allowed.
