Config Diff & History
TeamsEnterpriseCompare device configurations between snapshots, view change history timelines, and diff running configs against template-rendered intended configs.
Overview
Config diff lets you compare two device configurations side by side to see exactly what changed. Whether you are reviewing changes after a maintenance window, auditing configuration drift, or comparing a running config against an intended template, the diff view highlights additions, deletions, and modifications in a clear, readable format.
NetStacks provides three types of configuration comparison:
- Snapshot diff — Compare two config backups of the same device captured at different times to see what changed between snapshots.
- Running vs. intended diff — Compare the current running configuration against a template-rendered intended configuration to identify drift from the desired state.
- Change history — View the timeline of all configuration changes for a device, with hash-based change markers showing exactly when each modification occurred.
Config diffs are computed on demand from stored backup data. NetStacks does not store diffs separately — it compares the full config text each time you request a diff, ensuring results are always based on the actual stored configurations.
How It Works
Diff Algorithm
NetStacks computes diffs using a unified diff algorithm that produces output similar to diff -u on Unix systems. The diff identifies:
- Added lines (prefixed with
+) — Lines present in the new config but not in the old. - Removed lines (prefixed with
-) — Lines present in the old config but not in the new. - Context lines (no prefix) — Unchanged lines surrounding changes for readability.
Structured Diff Mode
In addition to the standard unified diff text, the API supports a structured diff mode that returns changes as a JSON object with sections, line numbers, and change types. This is useful for programmatic analysis of configuration changes — for example, detecting whether an ACL was modified or an interface was shut down.
Snapshot-to-Snapshot Comparison
When you diff two backups, NetStacks retrieves both config texts from PostgreSQL, runs the diff algorithm, and returns the result. Both backups must belong to the same device. The API endpoint is GET /api/devices/{deviceId}/backups/diff?old_backup_id=...&new_backup_id=...
Compare Against Latest
The "compare to latest" feature lets you paste or submit a configuration text and compare it against the device's most recent backup. This is useful for verifying proposed changes before applying them — paste the intended config and see the diff against what is currently running.
Change History Timeline
The change history view shows all backups for a device sorted by date, with visual indicators where the config hash changed. Consecutive backups with identical hashes are grouped as "no change" periods, while hash changes are highlighted with the diff available on click. This gives you a timeline of every configuration modification.
Step-by-Step Guide
Compare Two Snapshots of the Same Device
- Navigate to the device detail page and click the Backups tab.
- Select two backups by clicking their checkboxes (use Cmd/Ctrl+click for multi-select).
- Click Compare Selected.
- The diff view shows changes in unified format with added lines highlighted in green and removed lines in red.
- Toggle between Side-by-Side and Unified views using the view controls.
View Change History Timeline
- Navigate to the device detail page and click the Backups tab.
- The backup list shows a hash indicator next to each entry. Entries where the hash differs from the previous backup are marked with a change icon.
- Click a change marker to see the diff between that backup and the previous one.
- Use the date filter to narrow the timeline to a specific period (e.g., last 7 days, last 30 days, custom range).
Compare Running Config vs. Intended Template
- Navigate to the device detail page.
- Click Actions → Compare to Template (or use the compare to latest API).
- Paste or select the intended configuration text — this could be the output of a rendered template from the Templates feature.
- Click Compare. The diff shows lines present in the intended config but missing from the running config (drift), and lines in the running config that are not in the template (manual additions).
After a maintenance window, compare the pre-maintenance snapshot against a post-maintenance capture. The diff should show only the changes you intended. Any unexpected additions or deletions indicate unplanned modifications that need investigation.
Export Diff Results
- After generating a diff in the UI, click Copy to Clipboard to copy the unified diff text.
- Alternatively, use the API to fetch the diff programmatically and save it to a file or send it to a ticketing system.
Code Examples
Diff Two Backups via API
# Compare two config backups for the same device
curl -s "http://localhost:3000/api/devices/${DEVICE_ID}/backups/diff?\
old_backup_id=${OLD_BACKUP_ID}&\
new_backup_id=${NEW_BACKUP_ID}" \
-H "Authorization: Bearer ${TOKEN}" | jq '.diff'Structured Diff (JSON Output)
# Get structured diff for programmatic analysis
curl -s "http://localhost:3000/api/devices/${DEVICE_ID}/backups/diff?\
old_backup_id=${OLD_BACKUP_ID}&\
new_backup_id=${NEW_BACKUP_ID}&\
structured=true" \
-H "Authorization: Bearer ${TOKEN}" | jq '.'Compare Text Against Latest Backup
# Compare a proposed config against the device's latest backup
curl -X POST http://localhost:3000/api/devices/${DEVICE_ID}/backups/compare \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"config_text": "hostname core-rtr-01\n!\ninterface GigabitEthernet0/0/0\n description NEW-Uplink to spine-sw-01\n ip address 10.1.0.1 255.255.255.252\n no shutdown\n!",
"structured": false
}'Example Unified Diff Output
This diff shows changes made during a maintenance window on a Cisco IOS router — an ACL update and a new VLAN interface:
--- core-rtr-01 (2026-03-09 22:00:00 UTC)
+++ core-rtr-01 (2026-03-10 06:00:00 UTC)
@@ -45,8 +45,10 @@
ip access-list extended MGMT-ACCESS
permit tcp 10.0.0.0 0.0.0.255 any eq 22
permit tcp 10.0.0.0 0.0.0.255 any eq 443
+ permit tcp 10.0.1.0 0.0.0.255 any eq 22
+ permit tcp 10.0.1.0 0.0.0.255 any eq 443
deny ip any any log
!
+interface Vlan200
+ description Server-VLAN-200
+ ip address 10.1.200.1 255.255.255.0
+ ip helper-address 10.0.0.53
+ no shutdown
+!
line con 0
logging synchronous
line vty 0 4Query Backup History for Change Detection
# Get backup history and identify changes by comparing hashes
curl -s "http://localhost:3000/api/devices/${DEVICE_ID}/backups?limit=20" \
-H "Authorization: Bearer ${TOKEN}" | \
jq '[.backups[] | {backed_up_at, config_hash}] |
to_entries |
map(select(.key > 0 and .value.config_hash != (.[.key-1].value.config_hash))) |
map(.value)'
# Returns only backups where the config hash changed from the previous captureQuestions & Answers
- Q: How do I compare two device configurations?
- A: Navigate to the device's Backups tab, select two backups, and click Compare Selected. Alternatively, use the API:
GET /api/devices/{deviceId}/backups/diff?old_backup_id=...&new_backup_id=.... The result is a unified diff showing added lines (prefixed with+) and removed lines (prefixed with-). - Q: Can I diff a running config against a template?
- A: Yes. Use the "compare to latest" feature by posting the template-rendered config text to
POST /api/devices/{deviceId}/backups/compare. The response shows the diff between the submitted text and the device's most recent backup. This is useful for detecting configuration drift from intended state. - Q: How far back does change history go?
- A: Change history goes as far back as your stored backups. Config backups are retained indefinitely by default, so the history covers every backup ever captured. The hash-based change markers let you quickly identify when changes occurred without reading through every backup.
- Q: Can I search for when a specific config line changed?
- A: You can grep through individual backup contents in the UI using the search feature on the backup detail page. For programmatic analysis, fetch backup texts via the API and search for the target line across multiple backups. The structured diff mode also identifies specific changed lines in JSON format for automated processing.
- Q: What diff format is used?
- A: NetStacks uses the unified diff format (similar to
diff -uorgit diff). Added lines are prefixed with+, removed lines with-, and unchanged context lines have no prefix. Section headers show the line number ranges for each change hunk. A structured JSON format is also available via thestructured=truequery parameter. - Q: Can I compare configs between different devices?
- A: The built-in diff API compares backups belonging to the same device. To compare configs between two different devices, retrieve the backup text for each device via the API and use an external diff tool. Cross-device comparison is useful for verifying that redundant devices have matching configurations.
Troubleshooting
Diff shows no changes when changes were expected
Some differences may not appear in the diff due to whitespace normalization or timestamp filtering. Common causes:
- Timestamps in config — Lines like
! Last configuration change at ...change every capture but may be filtered by the diff engine to reduce noise. - Trailing whitespace — Some devices add or remove trailing spaces between captures. The diff engine normalizes whitespace by default.
- Wrong backups selected — Verify you selected the correct pre and post backups by checking their timestamps.
Large diffs timing out
Devices with very large configurations (10,000+ lines) may produce large diffs that take time to render. If the UI times out, use the API directly and pipe the output to a file:
curl -s "http://localhost:3000/api/devices/${DEVICE_ID}/backups/diff?\
old_backup_id=${OLD}&new_backup_id=${NEW}" \
-H "Authorization: Bearer ${TOKEN}" > diff-output.jsonTemplate diff does not match expected output
When comparing running config against a template, differences may appear due to:
- Ordering differences — The device may reorder config sections (e.g., ACL entries) differently from the template output.
- Default values — The running config may include default values that the template omits, or vice versa.
- Generated lines — Lines like
! Last configuration change at...or crypto key blocks appear in running config but not in templates.
Related Features
Config diff works with snapshot and template features to provide complete configuration lifecycle management:
- Config Snapshots — Capture the configs that diffs compare
- Templates & Rendering — Generate intended configs for drift detection comparison
- Adding Devices — Devices must exist in the inventory before configs can be captured and compared
- Scheduled Tasks — Automate periodic config captures that feed the change history