Read CBOR Files With SQL, No Library
CBOR turns up wherever a compact, self-describing binary format is needed and JSON is too verbose: IoT telemetry, COSE envelopes, CBOR Web Tokens (CWTs), constrained-device protocols. A .cbor file is not readable text, and most of what makes it worth using — tagged dates, exact big integers — is exactly what a naive viewer gets wrong. This is how to query one correctly.
What Makes CBOR Different From Plain Binary JSON
Underneath, CBOR is a lot like MessagePack: compact, self-describing, no schema file needed. What sets it apart is tags — a number attached to a value that says what it really is. Tag 1 says “this integer is actually a Unix timestamp”; tag 2 says “this byte string is actually a big integer.” A reader that ignores tags gets a plain number back and quietly loses that meaning.
Doing It in the Browser
OmniSelect FileSQL decodes CBOR with cborg, understanding the standard date tags (0 and 1) and big-integer tags (2 and 3), inside your browser tab. Nothing is uploaded.
- Open the app.
- Drop the file onto the File Select panel.
readings.cborbecomes a table namedR, shown in the Alias column. - Look at it.
SELECT * FROM R
| site | reading | taken_at | sensor_id | lifetime_reads |
|---|---|---|---|---|
| Leeds | 18.4 | 2026-02-01 07:40:00 | S-100 | 9223372036854775807 |
| Leeds | 19.0 | 2026-02-01 08:40:00 | S-100 | 9223372036854775808 |
| Bristol | 31.6 | 2026-02-01 08:45:00 | S-200 | 1834 |
| Bristol | 20.2 | 2026-02-01 09:45:00 | S-200 | 1835 |
Two tags did real work here:
taken_atwas stored as tag 1: a plain integer count of seconds since 1970, tagged as a date. It arrives as a normal timestamp, queryable with the usual date comparisons — not a number you'd have to convert yourself.lifetime_readswas stored as tag 2: a big integer encoded as raw bytes, because it can run past what CBOR's ordinary integer types hold. The first two sensors' totals — one of them9223372036854775807, the largest signed 64-bit integer — arrive as exact text; the smaller ones on the other two rows arrive as plain numbers, usable in arithmetic.
A Sequence, Not an Array
readings.cbor is written as a CBOR sequence: four separate top-level values, one after another, with nothing wrapping them — the natural shape for appending a new reading to a file without rewriting an outer array. It reads exactly the same as a file with one array value holding all four; you do not need to know which shape a file uses before opening it.
Joining and Aggregating
A second file, sites.cbor (table S) — this one a single CBOR value holding an array of records — maps each site to its region:
SELECT S.region, R.site, COUNT(*) AS readings, ROUND(AVG(R.reading), 1) AS avg_reading FROM R JOIN S ON R.site = S.site GROUP BY S.region, R.site ORDER BY avg_reading DESC
| region | site | readings | avg_reading |
|---|---|---|---|
| South West | Bristol | 2 | 25.9 |
| North | Leeds | 2 | 18.7 |
Drop a .cbor file in and see inside it.
Open the app →What's Not Supported
- Only tags 0, 1, 2 and 3. The standard date and big-integer tags decode as above. Any other tag — including the ones COSE and CWT wrap their own signed data in — arrives as the plain value underneath, without the tag's extra meaning applied.
- No write-back. Export the result as CSV, JSON, Excel or Parquet — not another .cbor.
- Size. Up to 50 MB and 1,000,000 rows, the same limit as every other format here.
Nested objects and arrays flatten the same way as JSON regardless of tags — see one query across seven file formats for how a deeper structure turns into columns.
Reasonable Questions
Is this the same reader as MessagePack?
No — different libraries, different formats. See reading MessagePack files with SQL if that's what you have; the two are easy to confuse since both are compact binary alternatives to JSON.
What about a CBOR Web Token or a COSE message?
The CBOR underneath opens and flattens like any other file, but the signature that makes a CWT or COSE message trustworthy is not checked here — this reads data, it does not verify tokens.
Does anything leave my machine?
No. The CBOR reader runs in the tab, and after the page has loaded it makes no network requests — here is how to check.