Kafka point-in-time recovery, down to the millisecond
A bad deploy started writing corrupt records at 14:02:37. Replication copied the corruption everywhere. PITR restores your topics exactly as they were the moment before.
How Kafka point-in-time recovery works
Kafka point-in-time recovery uses the timestamp every Kafka record already carries. At restore time you set a time window in Unix milliseconds, and the restore engine replays only the records inside it. Everything after the incident stays out of the target topic.
No special backup mode is required. Any backup taken with the tool supports a time-windowed restore, because the filter is applied when records are read back — not when they are written.
- restore-pitr.yaml
- Rehearse, then run
- Side-topic variant
mode: restore
backup_id: "prod-backup-20241201"
target:
bootstrap_servers:
- broker-1.kafka.svc:9092
storage:
backend: s3
bucket: company-kafka-backups
region: us-west-2
prefix: production/prod-cluster
restore:
create_topics: true
# Point-in-time window (Unix milliseconds)
# Dec 1, 2024 10:00:00 UTC -> 14:00:00 UTC
time_window_start: 1701424800000
time_window_end: 1701439200000
# Reposition consumer groups inside the restored window
consumer_group_strategy: header-based
reset_consumer_offsets: true
consumer_groups:
- order-processor
- analytics-service
# Check the backup is complete and readable
kafka-backup validate \
--path s3://company-kafka-backups/production/prod-cluster \
--backup-id "prod-backup-20241201" \
--deep
# Rehearse: dry_run: true validates the plan without producing
kafka-backup restore --config restore-pitr.yaml
# Then set dry_run: false and run the real restore
kafka-backup restore --config restore-pitr.yaml
mode: restore
backup_id: "prod-backup-20241201"
target:
bootstrap_servers:
- broker-1.kafka.svc:9092
storage:
backend: s3
bucket: company-kafka-backups
region: us-west-2
prefix: production/prod-cluster
restore:
create_topics: true
time_window_start: 1701424800000
time_window_end: 1701439200000
# Keep production untouched; inspect the window in a copy
topic_mapping:
orders: orders_restored
# Leave consumer groups alone for an inspection copy
consumer_group_strategy: skip
Pick the right restore target
The time window answers what comes back. The second decision is where it lands. Three patterns cover most incidents, and they differ only in a few config keys.
| Restore target | Config | When to use it |
|---|---|---|
| Same topic, same cluster | time_window_end just before the incident | Corruption or bad deploy — rebuild the topic to a clean state |
Side topic via topic_mapping | orders: orders_restored, strategy skip | Inspect or reprocess a window without touching production |
| DR or staging cluster | Point target.bootstrap_servers elsewhere | Fire drills, forensic analysis, compliance extracts |
Set dry_run: true on the first pass. The engine validates the plan — window,
topics, mappings — without producing a single record, so a typo in a timestamp
costs seconds instead of a second incident.
Millisecond boundaries matter because incidents rarely align to the hour. If
the bad deploy landed at 14:02:37.412, you set time_window_end to that
moment and keep every good record written at 14:02:37.411. Replication
tools have no equivalent — they follow the log, corruption included. For the
step-by-step workflow around a restore, read the
topic backup and restore guide on the blog.
Frequently asked questions
How precise is Kafka point-in-time recovery?
Millisecond precision. The restore window is defined by time_window_start and time_window_end in Unix milliseconds, and records are filtered by the timestamp each Kafka record already carries. You can end a window at the exact millisecond before a bad deploy started writing.
Do I need a special backup mode to use PITR?
No. Time-window filtering happens at restore time, when records are read back from storage. Any backup taken with the tool supports point-in-time recovery, including incremental backups.
Can I restore a time window without overwriting the live topic?
Yes. Add a topic_mapping entry such as orders: orders_restored and the windowed records land in a separate topic on the same cluster. Production stays untouched while you inspect or reprocess the copy.
What happens to consumer groups after a point-in-time restore?
You choose per restore. Set consumer_group_strategy: header-based with reset_consumer_offsets: true to reposition listed groups at their equivalent offsets inside the restored window. Use skip for inspection copies so no group is moved.
Why not use replication for point-in-time recovery?
Replication copies the log as it happens, so corrupt or deleted records propagate to every replica within seconds. It has no concept of restoring to an earlier moment. PITR needs an immutable copy of the data plus timestamp filtering, which is what backups provide.
Ready to protect your Kafka data?
Take your first backup in minutes with the open source CLI, or talk to us about Enterprise features like encryption, RBAC, and audit logging.