NEW: The Edge Autonomy Gap report. AI is arriving at the edge — 500 practitioners say the infrastructure isn't ready.
All posts

A common community question is how to make a temporary copy of all messages in a JetStream stream, especially before deleting and recreating the original stream or its consumers.

There is not a single universal answer because “copy” can mean different things:

  • A backup that can restore the stream later
  • A second stream in the same account or cluster
  • A mirror or source that continuously tracks the original stream
  • A manual replay that republishes messages into another stream

Each approach has different behavior around stream names, consumer state, retention policy, sequence numbers, and operational risk.

Option 1: Use JetStream backup and restore

If your goal is to preserve a stream before replacing it, JetStream backup and restore is usually the first option to consider.

For example, the NATS CLI can back up a stream while excluding its consumer definitions. A real invocation also names the stream and a destination path for the backup:

Terminal window
nats stream backup <stream> <destination-path> --no-consumers

By default a backup includes consumer definitions and state. The --no-consumers flag excludes them, which is useful when you want to preserve stream messages but intentionally avoid restoring consumers, for example when you suspect a consumer configuration or state issue.

A typical high-level workflow is:

  1. Back up the stream.
  2. Validate the backup by restoring it in a safe environment first.
  3. Delete the original stream when you are ready.
  4. Restore the stream from backup.
  5. Recreate consumers manually if you did not include them in the backup.

The validation step matters. A backup is only operationally useful if you have already proven that restore works in an environment that is close enough to the one you care about.

One important detail: restore recreates the stream from the backup, so the target stream must not already exist when you restore. You cannot restore on top of a live stream with the same name, which is why the workflow deletes the original first. If you have already recreated the original stream and then want to load older messages back into it, backup and restore is not the right tool for that step. Use a source or a manual replay instead.

Can I restore a backup using a different stream name?

Do not assume that backup and restore can be used as a same-cluster “copy and rename” operation.

In practice, the NATS CLI restore path may reject changing the stream name during restore with an error like:

1
stream names may not be changed during restore

That means backup and restore is best treated as a way to restore the backed-up stream, not as a general mechanism to create mystream_backup from mystream in the same account.

If you need a temporary stream with a different name in the same environment, consider a mirror, a source, or a controlled republish workflow instead.

Be careful with interest-based retention

If the original stream uses interest-based retention, think carefully before restoring it without consumers.

With interest retention, messages are retained based on consumer interest. If you restore only the stream data and omit consumers, there may be no active interest to keep those messages. Depending on the exact stream configuration and server behavior, that can defeat the purpose of restoring messages into an interest-retained stream with no consumers.

Practical guidance:

  • Test the exact backup and restore workflow before using it on production data.
  • If you use --no-consumers, verify what happens to restored messages before deleting the original.
  • Consider whether a temporary copy should use a limits-based retention policy instead of interest retention.
  • Recreate the needed consumers before or immediately after restore if message retention depends on consumer interest.

The safest answer is not to rely on assumptions here. Test the lifecycle end to end: backup, restore, consumer recreation, message availability, and cleanup.

Option 2: Use a mirror or a source for a separate copy

JetStream can keep one stream populated from another. There are two related primitives, and the difference matters for this use case:

  • A mirror copies all messages from exactly one other stream and preserves that stream’s message sequence numbers. A mirror stream cannot declare its own subjects and does not accept direct publishes; it only ingests from the stream it mirrors.
  • A source copies messages from one or more other streams, but the sourcing stream assigns its own new sequence numbers to the copied messages. A sourcing stream can also declare its own subjects, so it can ingest copied messages and accept new direct writes at the same time.

For a read-only copy with a different name that stays close to a faithful duplicate, a mirror is the better fit because it preserves sequence numbers. For example, conceptually:

1
mystream -> original stream
2
mystream_backup -> mirror of mystream

A mirror catches up from existing messages and then continues tracking new messages from the original stream. This makes it useful for temporary backup-like workflows where a point-in-time CLI restore is not the right shape.

A typical approach is:

  1. Create a mirror stream, such as mystream_backup, that mirrors the original stream.
  2. Choose a retention policy on the copy that suits a backup, usually limits-based rather than interest-based, so messages are not dropped for lack of consumer interest.
  3. Wait until the mirror is caught up and confirm its message count.
  4. Perform the maintenance on the original stream and its consumers.
  5. Repopulate the rebuilt stream from the copy.
  6. Remove the temporary copy after the rebuilt stream is confirmed healthy.

Step 5 needs the most care. Because a mirror stream cannot also accept direct writes, you generally cannot simply convert the backup mirror into the new production stream. Mirror configuration is fixed when the stream is created and generally cannot be added or removed by updating an existing stream, though this can depend on your NATS version. Two cleaner patterns are:

  • Rebuild the original stream with its normal subjects plus a temporary source pointing at the backup copy. Once it has caught up, remove the source so the stream keeps only its direct subjects. Unlike a mirror, sources can be added and removed by updating a stream.
  • Or replay messages from the copy into the rebuilt stream using the manual approach in Option 3.

Test whichever pattern you choose, because the exact behavior depends on your stream configuration and NATS version.

Option 3: Manually read and republish messages

Another fallback is to read all messages from the source stream and publish them into a new stream yourself.

This can work, but it is not the same thing as a native stream copy. When you republish messages, the destination stream receives new messages with its own stream sequence and storage metadata. You should also consider:

  • Ordering guarantees in your replay code
  • Duplicate handling and idempotency
  • Message headers and subjects
  • Publish acknowledgements and error handling
  • Whether new writes are happening while the copy runs
  • Whether consumers might observe replayed data as new data

Manual republishing is often reasonable for controlled migrations, small recovery tasks, or custom transformations. It is riskier if you need an exact operational copy of the stream’s state.

Choosing the right approach

Use this decision table as a starting point:

GoalConsiderMain caution
Restore the same stream after deletionBackup and restoreValidate restore before deleting production data
Exclude consumer definitionsnats stream backup --no-consumersInterest retention may not retain messages without consumers
Create a separate copy with a different nameMirror or sourceA mirror preserves sequences but takes no direct writes; a source re-sequences messages but can also take writes
Copy into a custom stream layoutManual read and republishDestination messages are newly published messages
Debug suspected consumer issuesBackup without consumers, then recreate consumersMake sure stream retention will preserve messages

For production or important data, use a conservative process:

  1. Document the current stream and consumer configuration.
  2. Create a backup of the stream.
  3. If omitting consumers, explicitly test retention behavior.
  4. Restore or mirror in a non-production environment first.
  5. Confirm message count, subjects, and consumer behavior.
  6. Only then perform the delete/recreate operation on the original stream.
  7. Keep the backup or mirror until the rebuilt stream is verified.

The key point is that JetStream gives you multiple building blocks, but they are not interchangeable. Backup and restore is best for restoring the same stream under its original name. Mirrors and sources are better for maintaining a separate stream that continuously tracks another one. Manual republishing gives maximum control but creates new stream history.


Want help from the NATS experts? Meet with our architects to get help tailored to your use case and environment.

Get the NATS Newsletter

News and content from across the community


Cancel