Read MessagePack Files With SQL, No Code
MessagePack is what a lot of APIs, message queues and mobile apps send instead of JSON: the same nested objects and arrays, packed into fewer bytes, with no text to read. A cache dump, a queued job, a logged webhook payload — all show up as a .msgpack or .mpk file that nothing renders without a decoder. This is how to query one directly.
Why It Looks Opaque
Open a .msgpack file in a text editor and it is mostly unprintable bytes: every string is prefixed with a length instead of being quoted, and numbers are packed to the byte rather than written as digits. That compactness is the point — it is faster to parse and smaller on the wire than JSON — but it means a person can no longer just look.
Doing It in the Browser
OmniSelect FileSQL decodes MessagePack with the reference @msgpack/msgpack library, inside your browser tab. Nothing is uploaded.
- Open the app.
- Drop the file onto the File Select panel.
telemetry.msgpackbecomes a table namedT, shown in the Alias column. - Look at it.
SELECT * FROM T LIMIT 100
| event_id | device_id | kind | recorded_at | metrics_temp_c | metrics_humidity | tags |
|---|---|---|---|---|---|---|
| 1 | 9007199254740993 | reading | 2026-02-01 06:00:00 | 18.4 | 41 | line-1,ok |
| 2 | 9007199254740993 | reading | 2026-02-01 07:00:00 | 19.1 | 40 | line-1,ok |
| 3 | 4823009184620001 | alert | 2026-02-01 07:05:00 | 31.6 | 22 | line-2,over-temp |
| 4 | 4823009184620001 | reading | 2026-02-01 08:00:00 | 20.2 | 39 | line-2,ok |
| 5 | 9007199254740993 | reading | 2026-02-01 08:00:00 | 18.9 | 42 | line-1,ok |
Look closely at device_id: both values are encoded the same way, as MessagePack's 64-bit integer type, but they don't come back the same way.
9007199254740993is one more than JavaScript's largest safe integer. A plain number can't hold it exactly, so it arrives as text — every digit intact — rather than silently rounding to...992or...994.4823009184620001fits within the safe range, so it stays a plain number, sortable and usable in arithmetic like any other.
Two more things happened without being asked: the nested metrics object flattened into metrics_temp_c and metrics_humidity, and recorded_at — MessagePack's own timestamp extension type, not a string — arrived as a real timestamp.
Filtering and Joining
Ordinary SQL from here. Just the alerts:
SELECT * FROM T WHERE kind = 'alert'
A second file, lines.msgpack (table L), maps each device to a plant. Because both files kept the big id as the same text, it joins correctly — a plain SUM or an equality join on a large 64-bit id is exactly the case a lossy converter would quietly break:
SELECT L.plant, COUNT(*) AS readings, ROUND(AVG(T.metrics_temp_c), 1) AS avg_temp_c FROM T JOIN L ON T.device_id = L.device_id GROUP BY L.plant ORDER BY avg_temp_c DESC
| plant | readings | avg_temp_c |
|---|---|---|
| Bristol | 2 | 25.9 |
| Leeds | 3 | 18.7 |
Drop a .msgpack file in and see inside it.
Open the app →Either Shape MessagePack Comes In
A .msgpack file is read one of two ways, and both are handled without you choosing:
- One array, many records — the whole file is a single MessagePack value that happens to be an array of objects, the shape
telemetry.msgpackabove uses. - Records one after another — several MessagePack values written back to back with nothing joining them, the way a log of packed messages is often appended to disk.
lines.msgpackis written this way.
Nested objects and arrays flatten the same way as JSON — see one query across seven file formats for how a deeper structure turns into columns.
What's Not Supported
- No write-back. Export the result as CSV, JSON, Excel or Parquet — not another .msgpack.
- Custom extension types outside the built-in timestamp extension arrive as their raw bytes, not a value your application would recognise, since decoding them correctly means knowing your own application's convention.
- Size. Up to 50 MB and 1,000,000 rows, the same limit as every other format here.
Reasonable Questions
What about a .mpk extension?
Same format, same reader — .msgpack and .mpk are both accepted.
Why not just convert it to JSON first?
You can, but converting loses exactly the thing this guide is about: a 64-bit id or timestamp that MessagePack stores precisely can get rounded the moment a converter turns it into a JSON number. Reading the .msgpack directly keeps it exact.
Does anything leave my machine?
No. The MessagePack reader runs in the tab, and after the page has loaded it makes no network requests — here is how to check.