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.3Via API call: Send a
POSTrequest to/api/v2/management/enable-read-only-mode, which takes no body:curl \ -i \ -X POST \ -H "Authorization: Bearer <API_TOKEN>" \ http://localhost:3000/api/v2/management/enable-read-only-mode -
Via command-line flag: Start EventSourcingDB with the
--read-onlyflag:./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.
Added in 1.3The API call answers with an event of the type io.eventsourcingdb.api.read-only-mode-enabled. If read-only mode is on already, whether through the API or the flag, it answers with read-only-mode-already-enabled instead, and nothing changes. A client that only wants the database to be read-only can take that error as success.
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
- Observing events via the observe API (though no new events will arrive)
- Running EventQL queries
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.3Clients attempting these operations will receive store-read-only, an error item at status 200.
Read-Only Mode After a Storage FailureAdded in 1.3#
If EventSourcingDB fails to store a write, for example because the disk is full or failing, it puts itself into read-only mode and stays in it until it is restarted. Reads go on and see everything that was stored before the failure. The same happens if EventSourcingDB keeps failing to move stored writes into its data files – which it does in the background, retrying while it fails – until the writes waiting for that take up as much memory as it allows.
The health endpoint reports this in its check store:operationMode as read-only with the status fail, so it answers with a 503, and the log names the cause. Writes are refused with store-failed meanwhile. Fix the cause, then restart EventSourcingDB.
The client whose write failed receives 500 Internal Server Error, or, once its stream has begun, a stream that breaks off without its end item, and cannot tell from it whether the write was stored. After the restart, read the events to find out.
Read-Only Mode While the Disk Is Almost FullChanged in 1.3#
EventSourcingDB keeps a reserve of 1 GiB free on the file system that holds its data directory, so that a write never runs out of space halfway. Once less than that is free, it refuses writes and puts itself into read-only mode, and once at least 1 GiB has been free again for 10 seconds, it accepts writes again by itself, without a restart. It checks the free space when it starts, before it accepts the first write, and every second after that. The 10 seconds keep it from switching back and forth while the free space moves around the reserve, and they start anew whenever less than 1 GiB is free in between, or the free space cannot be measured.
Clients whose writes are refused meanwhile receive disk-full, an error item at status 200. The health endpoint reports this in its check store:operationMode as read-only with the status warn, and in its check system:diskRemaining with the status fail, so the health endpoint answers with a 503, unless you ask it for OpenMetrics, which it always answers with a 200. That check warns beforehand, once 80 % of the space above the reserve is used, but not before less than 100 GiB are left above it: on a disk of 100 GiB, that is at about 21 GiB free, and on a disk of 10 TiB, at about 101 GiB free.
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.