DataMind Oda keeps every chat's lasting record as session log files on your computer: a log that grows as the chat works. This page shows where the files live, how Oda names and keeps them, what a log records, and how to open, back up or inspect them. For the messages Oda shows when a log has a problem, see Session log problems.
Where session logs live
All of your session logs sit under a single folder on the computer; this page calls it the log folder.
The log folder has no default: it is set for your installation, and every chat is saved under it. If you are not sure which folder was chosen, ask your DataMind OS administrator.
Oda creates the log folder when it first needs it. Where the system supports it, the folders and log files are created so that only your user account can use them.
Inside it, chats are grouped by the folder they work in. The group's folder name is wrapped in --, and a chat with no working folder sits in a group named _no-cwd.
Every chat has a folder of its own. Its name is made from the chat's id, changed only as much as needed so the id stays safe as a folder name; nothing in an id can point outside the log folder.
A chat with more than one generation of its log, compression on, looks like this:
A chat with compression off keeps the same names without .zstd.
How log files are named and kept
The oldest format's file keeps the plain name session.jsonl, with no version in it.
Later formats put their version into the name, as in session.v1.jsonl. Current Oda writes version 4, so a log it saves is named session.v4.jsonl, with .zstd added when compression is on.
Oda reads only files with these exact names. A renamed copy, such as session.v1.backup.jsonl, session.v01.jsonl or session.V1.jsonl, is not treated as a log.
When Oda saves a chat whose log was written by an older format, it adds the current file beside the old one, and the old file stays exactly as it was. One chat can have several generations side by side, and the newest file is the chat's current state.
Oda never renames, replaces, moves or deletes a generation it has already saved.
A log's first line identifies the chat: the format version, the chat's id and creation time, the folder it works in, and how it started, including any history inherited from another chat. Oda checks this line before trusting the rest, and a file whose first line breaks these rules, for example a folder that is not an absolute path, is refused rather than guessed at.
Values inside a log are stored exactly as they were written. Oda refuses to save a value it cannot keep exactly, instead of storing a changed version.
Opening a chat written by a different version of Oda is covered in Opening older chats.
When a chat first reaches disk
A new chat writes nothing at all until it first has content to save. A chat you never used leaves no files, even if Oda stops suddenly.
The first save writes the file's first line, which identifies the chat, and the first events. Every later save adds to the end of the file.
A chat becomes visible to other copies of Oda only after its first save has reached the disk.
A save counts once it has completed: everything it stored is kept, even if a stop comes later. Oda never rewrites it, and a later read never shows an older state than an earlier one.
If Oda stops in the middle of a save, the unfinished piece at the end is left aside and cleared on the next save; see Chat recovery after a crash.
What a log records
A log holds one event per line, each line a JSON object, after the first line that identifies the chat. Every event carries the same small envelope:
Part
What it carries
type
What the event records
seq
The event's position in the log
time
When the event happened
data
The event's payload
ignorable (optional)
Marks the event as safe to skip when a reader does not know its type
surfaceOp, sourceEventSeqs (conditional)
For a surface event: the history change it applies and the recorded events it is built from
An event is either a surface event, which produces the history a model reads when the chat continues, or a log-only event, which is kept for the record but never enters that history.
Oda refuses to interpret a log that holds an event type it does not know, unless that event carries the ignorable marker: skipping a record silently could rebuild the chat wrongly.
A turn is recorded as it happens: the prompt is admitted and the chat reads as running; the turn starts, the system prompt is assembled and the first step begins; the request, your message, the answer, and every tool call and result are recorded; the step and the turn end, and the chat reads as idle again.
Every successful model call is recorded, even one that returned no content or stopped at the output limit. An empty answer stays out of the history later derived for the model.
A stored message carries its source: you, the model, a tool, the system prompt, a checkpoint saved when a chat is shortened, a generated chat title, the tool registry, runtime context, a plugin, an automatic review, or a compaction output. A source kind a reader does not know is preserved, not dropped.
Programs that replay a chat read the session event stream. Coordination while work runs, such as queue and status, steering a turn, and errors, travels on a separate live surface.
The full format of a log, and what its records hold, is covered in Chat log format.
Compressed and plain logs
Compression is on by default. A compressed log is stored as a series of Zstandard frames with checksums, and its name ends in .zstd; read these logs through Oda.
With compression off, a log is plain text: one JSON object per line, which you can open in a text editor.
A log folder keeps one form: all compressed or all plain. Oda refuses a log stored in the other form instead of reading it wrongly, and a folder cannot be switched between forms; use a separate folder for each form.
One writer at a time
Oda allows one writer per chat at a time, and the rule holds across every copy of Oda running on the computer. While the first writer is alive, a second is refused with session "<id>" is already owned by an active write handle.
Reading a chat is never blocked by the writer.
A copy of Oda that is still alive keeps the lock until it stops; there is no timeout that takes it away.
A lock ends with its process: after a crash or a normal close, the next writer can take the chat over at once.
On some systems, a small file named session.lock sits in a chat's folder while the chat is being written, and it can stay after the writer releases it. If a chat stays locked because the process holding it cannot continue, deleting this file frees the chat for the next writer. Do this only when you are sure that process will not write the chat again.
Nothing is deleted automatically
Oda never removes or trims log files, older generations included. There is no cleanup, no retention limit and no delete-all action, so files stay until someone removes them.
Listing the logs a folder holds takes longer as the folder stores more chats.
Keep a copy of your chats
Copy the whole log folder to a safe place. Every chat folder is complete on its own, older generations included, so the copy holds whole chats.
The newest file in a chat's folder is that chat's current state.
To use a copy, keep the folder shape and the saved form: a log stays in its chat's folder under its group, and a folder keeps one form. Oda refuses a log in the wrong place or the wrong form rather than read it wrongly, and the message says which file it found.
If the same chat appears under more than one group, Oda refuses to choose between the copies. Keep the one you need, and remove the other with care.
Do not edit a log file in another program. Oda checks the log files it opens and refuses one that changed outside Oda rather than guess.
To copy a single chat, download it from the chat's menu; see Download a chat log.
Reading part of a log
Oda reads a log in windows, not all at once. A window asks for a starting position and a length.
The position is the sequence number of the first event to return; the default is the start of the log. The default length is the rest of the log.
A position at or past the end returns nothing; that is not an error.
Both values must be whole numbers of zero or more. Anything else is refused with read offset must be a non-negative safe integer, got <v> or read length must be a non-negative safe integer, got <v>, depending on the value.
Reading never changes a log, and a later read never shows an older state than an earlier one.
Values Oda keeps to reopen a chat quickly
Besides the log, Oda keeps small current values built from it, so it can show a chat's state, for example in the chat list, without reading every event again.
A set of these values carries a position: the place in the log that every value in the set accounts for. For a chat with no events yet, the position is -1.
Some of these values stay inside Oda and are never shared with other programs.
Oda saves checkpoints of these values when a chat is created, at the end of each turn and when the chat closes, with steady updates in between. Details served from a checkpoint are marked as cached.
A checkpoint that no longer fits the log, for example one from a different version or after the log changed, is not served as current: Oda builds the values again from the start.
A value taken from a checkpoint can trail the log, so it counts as a hint until its version is checked; it is never wrong. The log always leads: if a checkpoint write fails, the cache stays behind until the next save catches it up, and after a crash the cache can be behind, never ahead.
The cache binds a chat's details to its identity: its id, when it was created, the folder it works in, and whether it continues another chat. A chat that no longer matches its cached record has its details rebuilt from the log.
If a cache file cannot be read, Oda sets it aside and rebuilds the values from the log; your chat is not affected.
Upgrade a whole log folder at once
Opening an older chat in Oda converts it as you use it. For a whole log folder at once, maintainers use a one-time command, pnpm run migrate:sessions-to-v4.
The command refuses to run unless the build it ships in writes the current log format (this one-time command requires a V4 Session writer).
It finds each chat's generations by the expected folder shape, without following symbolic links, and skips a file that does not sit in that shape.
Each log is converted and its successor published beside the untouched original, or reported as already current; a log already in the current format is opened read-only.
A log that changed while the run was working is deferred and retried once after the first pass.
A failure on one chat does not stop the rest. The run ends with a summary of what it converted, found current, failed and skipped, and exits with a failure code when anything failed.
The run uses no model and no API key, and its text log and final summary are written privately in a temporary folder.
By default it converts as many logs at once as the machine has processors, never more than 16. --jobs N sets the number and --sessions-dir points the run at another folder. A --jobs value that is not a positive whole number is refused with --jobs must be a positive safe integer.
Questions, answered
Where are my session logs kept on this computer?
All of a chat's logs live under one log folder on the computer. Inside it, chats are grouped by the folder they work in, and every chat has a folder of its own. The log folder has no default: it is set for the installation, so if you are not sure which folder was chosen, ask your DataMind OS administrator.
Why is there no file for a chat I just created?
A chat writes its first file only after it first has content to save. Until then nothing exists for it, and a chat you never used leaves no files even if Oda stops suddenly. The first save writes the file's first line and the first events; later saves add to the end.
Which file is my chat's current state, and what are the others?
A chat can have several generations of its log side by side: session.jsonl from the oldest format, and session.v<N>.jsonl files from later ones, with .zstd added when compression is on. The newest file is the chat's current state, and the older ones stay exactly as they were; Oda never renames, replaces, moves or deletes them.
Can two copies of Oda work on the same chat?
Only one can write to it at a time. While the copy that holds a chat is alive, a second writer is refused with session "<id>" is already owned by an active write handle. Reading the chat is never blocked, and the lock ends with its program, so closing the copy that holds the chat frees it for writing.
What is the session.lock file?
On some systems, Oda keeps a small file named session.lock in a chat's folder while the chat is being written, to keep one writer at a time. It can stay there after the writer releases it. If a chat stays locked because the process holding it cannot continue, deleting this file frees the chat for the next writer; do this only when you are sure that process will not write the chat again.
Does Oda ever delete or trim old log files?
No. Oda keeps every generation, and there is no cleanup, no retention limit and no delete-all action. Log files stay until someone removes them, so remove what you no longer need yourself and keep copies of what matters.
How do I keep a safe copy of my chats?
Copy the whole log folder to a safe place. Every chat folder is complete on its own, older generations included, so the copy holds whole chats. To use the copy, restore it keeping the folder shape and the same form; Oda refuses a log kept in the wrong place or the wrong form rather than reading it wrongly.
Can I open or edit a log file in a text editor?
You can read it when compression is off: the log is plain text, one JSON object per line. With the default compression, read the chat in Oda, because the compressed form is built to be read by Oda. Do not edit a log file by hand: Oda checks the log files it opens and refuses one that changed outside Oda rather than guess, so a hand edit can leave a chat that will not open.
I renamed or moved a log file and Oda does not see it. Why?
Oda reads a log only under its exact generation name and inside its chat's folder, in the shape and form it saved. A renamed copy, such as session.v1.backup.jsonl, is not treated as a log, and a file moved out of place is refused. If the same chat appears in two places, Oda refuses to choose between them. Restore the original name and place from your backup, or keep the file for support.
How does Oda reopen a long chat without reading its whole log?
Oda keeps small current values built from the log and saves checkpoints of them, so opening a chat, or showing it in the chat list, does not work through every event again. Details served from a checkpoint are marked as cached. A checkpoint that no longer fits the log is not served as current; Oda builds the values again from the start. A cached value can trail the log, but it is never wrong.
I moved my chat files. Why did the chat's details rebuild?
The cache binds a chat's details to its identity: its id, when it was created, the folder it works in, and whether it continues another chat. When a chat no longer matches its cached record, for example after its working folder changed, Oda rebuilds the details from the chat's log. Nothing in the chat itself is lost.
Does everything in my chat's log reach the model?
No. The model's history is built from your messages, Oda's answers, and its tool calls and results. Records kept for the file only never enter it, such as approval decisions, your feedback, permission and plan choices, the changed-files list, file-restore notes, scheduled-run markers and hook records.