Configure NATS JetStream File Storage With Retention Limits
How to set max_age and max_bytes on a NATS JetStream file store to bound disk usage and control message retention.
06 Jan 2026, 18:17 UTC

Problem: JetStream disk growth or data loss when retention is unspecified
NATS JetStream stores messages on disk by default when file storage is enabled. Without explicit retention limits, a stream can grow until it fills the partition, causing outages. Conversely, omitting --storage file forces memory store, which loses every message on server restart. This article shows how to configure a file‑based JetStream stream with bounded retention and how to verify it works.
Useful takeaway
Create a stream with nats stream add ORDERS --storage file --max_age 24h --max_bytes 1GB and consume with a durable subscriber that explicitly acknowledges messages. Old segments auto‑clean, and disk usage stays within the configured bounds.
Configure file storage in the server config
JetStream file storage is activated by adding a jetstream block to the NATS server configuration file and setting store_dir:
jetstream {
store_dir = "/var/nats/store"
}
Start the server with the config file:
nats-server -c nats.conf
On first start, server logs will confirm JetStream is enabled with file storage at the configured path. Check the logs for a line indicating JetStream active status.
Create a stream with retention limits
Use the NATS CLI to define a stream that uses file storage and enforces two retention boundaries. The --storage file flag tells JetStream to persist messages on disk. The --max_age flag limits how long messages are retained, and --max_bytes caps the total disk usage for the stream.
nats stream add ORDERS --storage file --max_age 48h --max_bytes 500MB
Required permissions: operator or admin role on the NATS server. Run the command on any machine reachable the NATS endpoint (typically localhost if nats-server is local).
After creation, verify the stream limits:
nats stream info ORDERS
The output will display Storage: File and fields reflecting the Max Age and Max Bytes values you set. If those fields are missing, the stream may be using a different storage mode.
Publish and consume with explicit acknowledgment
JetStream retains unacked messages on disk. To test retention, publish a burst of messages and consume them with a durable subscriber that acknowledges each message. This demonstrates how retention limits interact with consumer behavior.
# Publish 100 messages
for i in $(seq 1 100); do nats pub ORDERS \"order-$i\"; done
# Subscribe with a durable consumer and manual acknowledgment
nats sub ORDERS --durable myConsumer --manual-ack
# Fetch and acknowledge messages
nats fetch ORDERS 10
nats ack ORDERS <msg-id>
After acknowledgment, run nats consumer info ORDERS myConsumer to see the number of pending messages drop. Disk usage under store_dir should also decrease, confirming that retention limits and explicit ack work together.
Limits and common mistakes
- Omitting
max_bytesormax_age: Without either limit, the stream can grow indefinitely, exhausting disk space. Always set at least one boundary. - Using memory store unintentionally: If
--storage fileis omitted, NATS defaults to memory store, and all messages disappear on restart. ConfirmStorage: Fileinnats stream info. - Failing to acknowledge messages: Unacked messages persist until explicitly acked, leading to repeated redelivery and inflated disk usage. Use durable consumers with explicit ack or configure
max_deliverto limit redelivers.
Practical verification checklist
- Start NATS server with JetStream enabled and a defined
store_dir; confirm server logs indicate JetStream is active with file storage. - Create a stream with
--storage file,--max_age, and--max_bytes; runnats stream infoand confirmStorage: Fileand the limit values. - Publish a burst of messages; check disk usage under
store_dirgrows proportionally. - Restart the server and run
nats consumer infoto see pending messages persist across restarts (expected for file store). - Consume messages with explicit acknowledgment; observe acknowledged messages removed and disk usage drops, confirming retention and ack behavior.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.