Time travel debugging in IntelliJ

Setup

If you’re replaying a recording, use the lr4j_replay tool.

Or if you’re debugging remotely, launch your application on the remote machine supplying the Undo for Java agents on the Java command-line.

Consider adding breakpoints and/or watchpoints before starting the debugger session since your application or recording will start running as soon as you press the Debug button.

Start the debugger session

Choose a Run/Debug configuration from the Run/Debug Configurations dialog and press the Debug button to start debugging.

_images/rundebug.png

Note

Refer to Replaying a recording or Live Debugging if you haven’t already created a Run/Debug configuration.

While your application is running, you can’t interact with it or examine application state. You can only Pause, Stop or Rerun your application. See IntelliJ tips for more info.

Once your application is suspended due to hitting a breakpoint or watchpoint, you can examine variables and the contents of the stack and evaluate arbitrary expressions. Refer to the IntelliJ documentation for details. You can’t alter variables while time-travel debugging, since doing so would likely change the future execution of the application and cause the timelines to diverge.

Time travel debug buttons

_images/replay.png

In addition to the familiar Resume, Step Over, Step Into, and Step Out buttons the plugin adds the following (from left to right in image):

  • Resume Back

  • Undo Last Navigation

  • Reverse Step Out

  • Reverse Step Into

  • Reverse Step Over

  • Log Jump

  • Step Across Back

  • Step Across

Forward and reverse execution

The plugin adds the Reverse Step Out, Reverse Step Into and Reverse Step Over buttons, which you can use to step the application backwards, and the Resume Back button to run your application backwards until it hits a breakpoint or watchpoint.

Other methods of navigation

Use the Undo Last Navigation button to undo the effects of the last button that changed the time in your application’s execution history.

Log Jump

Use the Log Jump panel to navigate to a time in your application’s execution history.

_images/logjump.png

Timestamp

Use the Timestamp field to navigate to a wallclock time in your application’s execution history. This is useful when you’ve identified a line of interest in a log file: in this case copy the timestamp from the log file and paste it into the Log Jump dialog to jump directly to the point in time in your application’s execution history where it emitted that log line. (The Log Viewer window is an alternative way of doing the same thing)

Timestamps should ideally have millisecond accuracy but even these are only approximate so you might find that the resulting stack is just somewhere in the code that emitted the log line.

Note

The Log Jump feature recognizes timestamps in many standard time formats produced by common logging frameworks including Log4j, Logback and java.util.logging. You can add other time formats under Settings › Tools › Undo for Java › Timestamp patterns. If the timezone is not specified in the timestamp it defaults to the local timezone.

Bbcount

A bbcount takes you to a precise point in the execution history. You may have made a note of a bbcount at some time or you may have obtained it through looking at the recording using udb

Trace id

If you have a Span ID generated by something like OpenTelemetry then you can enter that here to go directly to the method call associated with it. This is similar to doing the second half of Step Across. You may for instance have obtained a Span ID using Zipkin.

Object id

Entering an object address will result in a search backwards through the execution history to the place where that object was created. You must start from a point where that address is current. You can use this for instance if you have an OutOfMemory error resulting in a heap dump which you have examined using Eclipse Memory Analyzer. That tool will tell you the state of the heap where the OOM occurred, but you may wish to see what created one of the objects. For this to work the starting point should be where the OOM occurred (or sometime after is usually ok, e.g. the end of the recording if you stopped soon after the OOM).

Tip

You can right-click any object in the IntelliJ debugger Variables panel and choose Copy Object ID to copy the object’s address. Paste it into the Object ID field to jump to where that object was created.

Step Across

Use the Step Across and Step Across Back buttons to step between two of the services that comprise a microservice-based application. Step Across jumps to the point in time in another service’s execution history when it received the next API call made by this service. Step Across Back jumps to the point in time in another service’s execution history when it last made an API call to this service. Step Across works with HTTP/REST, reactive clients, and Java RMI calls. Refer to Microservices for more information.

Bookmarks

The plugin allows you to set bookmarks in a recording to which you can later return. They are displayed in the TimeTravelBookmarks tool window (View › Tool Windows › TimeTravelBookmarks) as shown below:

_images/bookmarks.png

Use the START and END bookmarks to jump to the beginning or end of your application’s execution history.

Use the Add Bookmark button to add a bookmark at the current point in time in your application’s execution history. You can return to this point in time by clicking on the bookmark.

Bookmarks are automatically ordered by their place in the execution history and display the location as well as the bbcount.

Bookmarks are not persistent and only exist for the lifetime of the session.

If you press the control key and then hover over the bbcount cell, the bbcount will be copied to the clipboard. This can be useful when examining the same recording using udb.

Log Viewer

As an alternative to the Log Jump window you can also open a log file in the LogViewer window (View › Tool Windows › LogViewer). If the log file contains a timestamp at the start of each line in one of the recognized formats, just clicking on that line will take you to the approximate location.

_images/logviewer.png

Recording properties

Added in version 10.1.

Recording Properties shows a summary of a recording: how the recorded program ended, the time and bbcount ranges the recording covers, its architecture and memory requirements, the system and Undo Engine version that made it, how its size breaks down, and the recorded Java version and JVM. Use it to check what a recording contains and which JDK it needs, for example before replaying it on another machine.

There are two ways to open it:

  • While a replay session is running, choose Tools › Recording Actions › Recording Properties… to see the recording loaded by the selected Undo debug session. This works whether the replay runs on this machine or on a remote host, and needs no Undo for Java installation on the machine running IntelliJ, but the replay tools must be from release 10.1 or later. It is not available while live debugging, which has no recording file.

  • Right-click a .undo file in the Project view and choose Recording Properties…. This reads the file without starting replay or checking out a license. It uses the Undo for Java installation set in Settings › Tools › Undo for Java › Replay tool directory, which you need to set on Windows and macOS as well as on Linux.

The summary opens in a dialog, where Copy All copies it to the clipboard. For example, for a recording made with the recording agent:

Program
  Recorded program            java
  Program termination reason  Program did not terminate
  Recorded time range (UTC)   2026-09-27 10:14:10.236946 -> 2026-09-27 10:14:54.378785
  Recorded time duration      0:00:44.141839
  Bbcount range               0 -> 2,001,386,832
  Architecture                x64
  Minimum memory requirement  216.99MB (15.77GB without overcommit)

Recording platform
  Created on system    Linux, example-host, 5.14.0-611.55.1.el9_7.x86_64, #1 SMP PREEMPT_DYNAMIC
                       Tue May 12 18:04:19 UTC 2026
  Undo Engine version  10.2.0 (recording format: 89)
  License UID          0123456789abcdef0123456789abcdef0123456789abcdef01234567

File size
                                 Size    Proportion
  Recording file              91.70MB
  Program state               49.61MB        54.10%
  Executable and debug files  33.59MB        36.63%
  Event data                   8.44MB         9.21%
  System information          48.86KB         0.05%

Snapshot sizes
                                Size    Proportion
  Initial snapshot + events  73.50MB        80.15%
  Supplementary snapshot 1    7.18MB         7.84%
  Supplementary snapshot 2    1.33MB         1.45%
  Supplementary snapshot 3    1.43MB         1.56%
  Supplementary snapshot 4    8.25MB         9.00%

Recorded Java
  Java version     17
  JRE version      17.0.19+10-LTS
  Recorded JVM     /usr/lib/jvm/java-17-openjdk/lib/server/libjvm.so
  Java executable  /usr/lib/jvm/java-17-openjdk/bin/java
  Recorded by      lr4j agent (javaVersion 17.0.19)

For a recording made with live-record, Recorded by reads live-record (no lr4j agent metadata). If Java version is unknown, the Java version could not be determined from the recording. One cause is that live-record recorded the script that launched the JVM instead of the JVM itself.

lr4j_recording_info prints the same summary from the command line.