SQL DATA LENS 4.02 shipped on September 4, 2026. Among its changes there is one that I want to single out, because it is something I have wanted for years and never found anywhere else: SQL DATA LENS now opens a .gof file — an InterSystems %GOF global export in block format — directly in the Global Browser, so you can browse an export the moment you receive it, before importing it anywhere.
It is a brand-new feature, and the block format was designed as an internal transport format between IRIS instances, never as something a third-party tool would read — so we learned it by studying what IRIS writes rather than from a specification. That is exactly why I am writing this post: I would like you to try it on your exports and tell us what you see. Below is what the feature does, why I think it is useful, where its limits are today, and what kind of feedback would help most.
The problem: a .gof file can only be looked at after importing it
If you work with IRIS or Caché long enough, .gof files start to pile up. The Management Portal writes them (System Explorer ▸ Globals ▸ Export, “block format”), ^%GOF writes them, ##class(%Library.Global).Export(...) with OutputFormat 7 writes them. They are how a colleague sends you “the configuration global from the test system”, how a customer attaches “the data that reproduces the problem” to a support ticket, and how many teams archive reference data.
And then you want to know what is in one of them. The honest answer so far has been: import it. Find a namespace you do not mind polluting, run ^%GI or the portal import, wait, open the Global Browser or a terminal, look around, and afterwards remember to clean up. For a file from a customer that may be several gigabytes, that means a spare namespace with several gigabytes of headroom. For a file you merely want to check — is this really the global I asked for, is it complete, does it hold the node I care about — that is a lot of ceremony for a two-minute question.
A .gof file is binary, block oriented and carries $LIST-encoded values and typed subscripts, so a text editor or hex viewer does not get you far either. Until now there was no way to just look.
What “File ▸ Open .gof File…” shows you
Choose File ▸ Open .gof File… and pick a file. SQL DATA LENS indexes it once — a few seconds per gigabyte, with a progress indicator that lets you cancel — and opens a tab named after the file.
The header tells you what you are holding before you open anything: format version, endianness and block size, the export timestamp, the namespace or database the export came from, the description record, and the totals — globals, nodes with a value, long strings, data blocks, bytes. This alone answers the “did they export the right thing?” question.
The globals table on the left lists every global in the file with its node, data-node, long-string, block and byte counts. A filter field above it narrows the list as you type, with * and ? wildcards.
The subscript tree on the right is the same three-column view as the live Global Browser — Node Structure, Node, Value — plus a Nodes column that shows how many nodes each subtree holds. It expands level by level and reads only the blocks that hold the level you open, so an export with tens of millions of nodes stays navigable. Max nodes limits a single expansion exactly as it does on a live connection.
Everything is read-only. The file is never modified.
The value panel: text, hex and $LIST
The part I use most is the value panel below the tree. Select a node and its value is shown in one of three modes:
| Mode | What you see |
|---|---|
| Text | The value as text; $LIST values as $lb(...), doubles as $double(...) — the same notation ZWRITE prints on the server |
| Hex | A hex dump of the stored bytes, with the type byte explained for typed values |
| $LIST | One line per list element with its type, nested lists indented |
A valid $LIST switches to the $LIST mode automatically, which makes the storage global of a persistent class — the ^Package.ClassD global with one $LIST per object — readable field by field. If a value is not a valid $LIST, the panel says so and names the rule and the position where the decoding failed. Nothing is guessed: a value the reader cannot decode is announced as such, and its raw bytes are always one click away in Hex.
Finding things and getting them out
- Go to takes a global reference like
^Data("ACC",42)and expands the tree straight down to that node. If a level cannot be reached — usually because it has more children than Max nodes allows — the tree stops as deep as it can and the status line names the node where it stopped. - Export selection as ZWRITE text writes one line per node in the form
^A(1,"x")="value", exactly whatZWRITEwould print on the server, so you can diff two exports with any text tool. - Export selection as CSV writes
global,sub1,...,subN,valuewith RFC 4180 quoting, UTF-8 — the quickest route from “a global in a file” to a spreadsheet or another database. - Copy node reference and Copy selection as ZWRITE text put the same thing on the clipboard for a ticket or a chat message.
Select several nodes with Ctrl/Shift; pointer nodes without a value are skipped in both exports.
Built for large files
An export you receive from a production system is rarely small, so this was tested against real ones. Two files from our test corpus, on an ordinary laptop, with the heap deliberately capped at 256 MB:
| File | Size | Globals | Open (index) | Heap after open | Expand one level |
|---|---|---|---|---|---|
| Export A | 1.97 GB | 1 | 1.1 s | 30 MB | 4 ms |
| Export B | 3.73 GB | 19 | 2.9 s (5.5 s cold) | 84 MB | 21 ms (2,909 children) |
The index is the only thing that grows with the file — roughly 1.2 % of its size — and everything else is constant per action.
And it has been tested thoroughly: against several hundred exports generated in IRIS to cover the corners of the format, and against 7 GB of real-world exports with about 100 million nodes — what the viewer shows matches what ZWRITE prints on the server.
Why this is more than a viewer
A few situations where the offline reader has already changed how I work:
- Support cases. A customer sends a
.goffile. Open it, jump to the node from the error report, copy theZWRITEline into the ticket. No import, no namespace, no cleanup. - Checking an export before you rely on it. Header, node counts and byte totals show at a glance whether the export is complete and holds the globals you expected — before you ship it to someone, and before someone imports it into a system that matters.
- Comparing two states. Export the same global from two systems, open both files, export the relevant subtrees as
ZWRITEtext and diff them. - Reading storage without a running server. On a train, on a machine without IRIS, from an archive folder of exports from a system that no longer exists.
- Learning. If you have ever wondered what a
%GOFexport actually contains, the Hex mode with its explained type bytes is the friendliest way I know to find out.
What it does not do (yet)
I would rather you knew this before you try it:
- Supported are exports of 8 KB databases in little-endian block format, format version 3 — what current IRIS and Caché 2017.1 and later write. Exports of 2 KB databases and big-endian files are refused with a message that names what was found, because we have no sample files to verify them against (see below).
- A multi-volume export is refused the same way, and for the same reason. The writer splits such an export at a volume-end record that none of our sample files contains, so the reader has no verified rule for it and says so instead of guessing. Re-export as a single file, or send us one — this is high on the list below.
- In 4.02, subscripts that contain several wide (non-Latin-1) characters and compact Unicode values are shown in their raw form rather than as text. Those encodings are now understood, and decoding them is planned for the next release — along with
$DOUBLEvalues printed with the same digits ObjectScript prints and very long Unicode values that 4.02 still refuses to open. - The reader is deliberately heuristic-free: every byte is read by exactly one rule from our format description. When a file does not fit, it is refused with the rule and the byte offset of the problem rather than displayed with a guess. That makes error messages very precise — and it makes your unusual files valuable to us.
This is where you come in
The block format is IRIS’s own transport format, and quite rightly there is no public specification for a third-party tool to follow. What SQL DATA LENS reads today, it learned from a large number of exports that we generated ourselves and verified against ZWRITE output. That means the reader is only as good as the variety of files we have seen. Yours are almost certainly different from ours.
So please: install 4.02, export a global or two in block format, open the file, and tell us what happens. In particular I would like to hear about
- files that are refused — the message names a rule ID and a byte offset; that pair alone is usually enough for us to understand what we have not seen before;
- exports from older Caché versions, from 2 KB-block databases, from big-endian platforms or multi-volume exports;
- globals with non-standard collations, Unicode-heavy data (Japanese, Chinese, Cyrillic, Arabic, emoji…), very long strings,
$DOUBLEvalues, deeply nested$LISTstructures; - anything where the tree or a value does not match
ZWRITEon the server the file came from; - and, just as useful, what you would want the viewer to do next.
You do not have to send us your data. Most reports need nothing more than the error message, or a description of the node that looks wrong. If you can share a file, a small synthetic global exported with ^%GOF that reproduces the case is ideal.
Write to support@sqldatalens.com.
Also in 4.02
Since this post is about one feature, here are the other 4.02 changes IRIS and Caché users will notice, in one breath: the class view shows methods, properties and parameters with their signatures and descriptions; the table browser’s Data filter remembers what you typed on that table; a search box above the Server Navigator finds a connection as you type; the SQL editor has an AI Assistant that generates SQL from a description and explains statements and execution plans; a result row against IRIS/Caché can jump straight to its storage global; and a long list of operations that used to freeze the window now run in the background. The complete 4.02 changelog has all 29 changes.
Try it
SQL DATA LENS runs on Windows and ships with its own Java runtime — download, unzip, start. The .gof viewer is included in the free trial, so you can open your first export a few minutes from now without buying anything. Once the trial is over, the feature stays available in the Named User, Team and Enterprise editions.
Already used up your trial period some time ago? Just drop me a line at support@sqldatalens.com and I will gladly extend it — I would much rather have your files tested than have the trial clock get in the way.
- Download: sqldatalens.com/download
- Documentation: the Global Browser page here, and the section “Opening a .gof export file (offline)” in the Global Browser chapter of the user guide that ships with the product
- Changelog: What’s new in 4.02
I am looking forward to your files, your findings and your ideas. Happy browsing!