Introduction¶
If you have run long sessions with DSH, you have likely encountered this issue: opening an old session causes a noticeable delay. The problem lies in the storage layer. DSH’s JSONL session backend compresses each batch of writes into a separate zstd frame before appending it to the file. A long session can easily accumulate tens of thousands of frames. During reading, every frame must be decompressed individually. Since the backend lacks seek-style reading for suffixes, retrieving data—whether just the tail or the entire file—requires decoding the whole file.
The number of frames is fixed by historical writes and cannot be reduced post-hoc. kkishapppy/dsh-session-repacker addresses this issue: it repacks scattered thousands of frame logs into the official native format. Actual tests show the maximum session opening time dropping from approximately 661ms to approximately 126ms.
What is it¶
dsh-session-repacker is a DSH plugin (MIT license, version 0.1.0) maintained by kkishapppy. It repacks the thousands of independent zstd frames generated by DSH’s JSONL session backend batch writes into the official native two-frame format: the header frame contains exactly one line of header, while the rest of the plaintext is concatenated and recompressed into a single event frame.
Two key points:
- The plaintext after repacking remains byte-for-byte unchanged. The DSH read path is fully compatible; the read-side
assertZstdHeaderFrameonly requires the first frame to be exactly one line of header, which the repacked result satisfies. - The plugin only handles maintenance and does not alter any read APIs or data semantics. It covers all paths for reading old sessions from disk: GUI opening, new conversation continuation/branching, and sub-session inheritance.
Results¶
Actual test results provided by the author:
| Item | Before Repacking | After Repacking |
|---|---|---|
| Max single session | 14,467 frames / 5.49MB / ~661ms | 2 frames / 2.09MB / ~126ms (~6x) |
| All 24 old sessions | 39,911 frames / 20.08MB | 48 frames / 10.67MB |
In addition to opening speed, the compressed volume is also reduced by approximately half—the compression ratio of a single large frame is far superior to that of thousands of independent small frames.
Installation and Usage¶
Install as a DSH plugin (recommended):
dsh plugin --profile web add dsh-session-repacker
You can also clone it to the plugins/ directory and link it into your profile. If you wish to build it yourself, execute the following in the repository directory:
npm i
npx -y tsdown@0.22.2 --config ./tsdown.config.ts
The output artifact is lib/index.mjs.
To enable it, configure the plugin and parameters in profiles/<profile>/cordis.patch.yml:
- id: session-repacker
config:
root: 'E:\DeepSeekHarness\sessions' # Session root directory (required)
minFrames: 200 # Skip processing if frames are below this value (default 200)
minAgeMs: 600000 # Skip processing if mtime is less than this many ms ago (default 10 minutes)
intervalMs: 3600000 # Periodic maintenance interval in milliseconds (default 1 hour)
It takes effect after restarting the server: the plugin performs a full scan upon startup and then performs periodic maintenance based on intervalMs. root is the only required field; the other three have default values, so it can run without configuration.
Standalone CLI¶
If you don’t want to run background tasks by attaching a plugin, the repository provides a standalone CLI that does not require the DSH service:
node tools/repack.mjs <root> # Scan and repack
node tools/repack.mjs <root> --dry-run # Only show statistics, don't write to disk
node tools/repack.mjs <root> --file <path> # Process only specified files (can be multiple times)
node tools/repack.mjs <root> --min-frames 64 --min-age-ms 60000
It is recommended to run --dry-run first to view statistics, confirm the scope and expected benefits, and then execute the actual operation. --file can be passed multiple times, making it suitable for processing only a few specific sessions; --min-frames and --min-age-ms are used to customize thresholds.
Security Design¶
Repacking replaces the session file on disk, making security the plugin’s primary focus. Measures include:
- Only process
.jsonl.zstdfiles, skipping files whose modification time (mtime) is less thanminAgeMsago to avoid active writes. - Skip the current live session.
- Perform a byte-level equivalence check before replacement: the plaintext extracted from the new file must be identical to the original plaintext.
- Perform another
statcomparison of size andmtimebefore replacement; if the file was appended to concurrently during this period, abort the operation. - Torn tails (incomplete frames) are skipped directly, leaving them to be handled by DSH’s own repair path.
- Writing uses a temporary file +
fsync+ atomic rename, which is isomorphic with the official backend on Windows.
Additionally, the server is tested to be compatible with appending new frames (e.g., session/end-seed) to repacked files, and appended files can be repacked again; the operation is idempotent.
Applicability and Notes¶
Suitable scenarios: deployments with long session history, slow opening, and where the frame count of old sessions has already solidified and cannot be reduced on its own. With background periodic maintenance, this can be automated.
Points to note:
- Once the frame count of an old file has solidified, it cannot be retrospectively compressed; it can only be repacked using this plugin or the CLI. If you want future logs to generate fewer frames, you can increase
writeBatchMaxDelayMs(default 200ms); this is a trade-off regarding durability. - The plugin runs with the permissions of the current DSH process and will directly replace session files. Before installing, it is recommended to review the source code and license, and verify it using
--dry-runin a test environment first.
Conclusion¶
dsh-session-repacker solves a specific problem: the tens of thousands of zstd logs left behind by DSH’s batch writing slow down the reading of old sessions. It does not alter data semantics but restores the files to the official native two-frame format, achieving approximately 6x faster opening speeds and about half the volume, while providing a complete set of security protections. Under DSH’s philosophy of “everything is a plugin,” this is a typical storage-layer maintenance plugin.
- Directory: https://www.skillhub.cn/plugins/kkishapppy/dsh-session-repacker
- GitHub: https://github.com/kkishapppy/dsh-session-repacker