WKB Format Explained, Byte by Byte
WKB (Well-Known Binary) looks like an inscrutable wall of hex — but it has a simple, strict structure. Paste any WKB or EWKB hex below and this tool walks it one field at a time: the byte-order flag, the geometry-type integer, an optional SRID, the ring and point counts, and every coordinate double — each colour-coded, with its decoded value beside it and the geometry drawn on a map. It all runs in your browser; nothing you paste is uploaded.
What WKB actually is
WKB is the binary serialization of the OGC Simple Features geometry model —
the same conceptual geometry as WKT (POINT, LINESTRING,
POLYGON, and their MULTI* forms), but written as raw bytes instead
of text. Databases and geometry libraries prefer it because bytes are faster to read and more
compact than parsing a text grammar: PostGIS, GEOS, JTS, Shapely, and most spatial stores
speak WKB internally and hand it to you as a hex string.
Every WKB geometry follows the same three-part opening, then a body that depends on the type:
- 1 byte Byte order
00= big-endian,01= little-endian - 4 bytes Geometry type uint32:
1Point,2LineString,3Polygon,4–6Multi* - 4 bytes SRID (EWKB only) present when the type’s
0x20000000flag bit is set - 4 bytes each Counts ring count, then a point count per ring (Polygon); point count (LineString)
- 8 bytes each Coordinates IEEE-754 doubles, X (lon) then Y (lat), repeated per vertex
A bare 2D point is the smallest complete example: 01 (little-endian) +
01000000 (type 1 = Point) + eight bytes of longitude + eight bytes of latitude.
That is exactly the default example loaded above — POINT(-73.9857 40.7484), the
Empire State Building.
Endianness: why the first byte matters
The opening byte is not part of the geometry — it is an instruction for reading everything
after it. Little-endian (01, “NDR”) stores each multi-byte
number least-significant byte first, which is what Intel and ARM CPUs and virtually every
database use. Big-endian (00, “XDR”) stores most-significant
byte first, the classic network byte order.
The practical consequence: the same coordinate has two different byte strings. The
longitude -73.9857 is b3ea73b5157f52c0 little-endian and
c0527f15b573eab3 big-endian — the exact reverse, byte for byte. Read a
little-endian value as big-endian and you get garbage coordinates in the middle of the ocean.
Because each nested geometry inside a MULTI* or GEOMETRYCOLLECTION
carries its own flag byte, one WKB value can legally mix both orders; well-behaved encoders
never do, but a robust reader must honour each byte.
WKB vs EWKB vs TWKB
Three encodings share the “WKB” name; they solve different problems.
OGC WKB
The standard. Byte order, type, geometry — no coordinate reference system is carried, and
higher dimensions are signalled by adding to the type code (1001 = PointZ,
2001 = PointM, 3001 = PointZM). This is what
ST_AsBinary() produces and what the OGC spec defines.
EWKB (Extended WKB)
PostGIS’s superset. Instead of the thousands-digit convention, EWKB steals the high bits of
the 32-bit type field as flags: 0x20000000 means a 4-byte
SRID follows the type, 0x80000000 means the coordinates carry a
Z, and 0x40000000 means they carry an M. So an
EWKB point in WGS84 encodes its type as 0x20000001 and inserts the SRID
(0x000010E6 = 4326) before the coordinates. Paste the “EWKB + SRID” example above
to watch the annotator surface that extra field. ST_AsEWKB() emits this form.
TWKB (Tiny WKB)
A transport-optimised cousin. TWKB throws out fixed 8-byte doubles in favour of delta-encoded, quantized integers packed as variable-length varints, with a configurable number of decimals. Geometries shrink several-fold, at the cost of some precision and all human-readability. Use WKB/EWKB for storage and exact round-trips; use TWKB when you are moving many geometries over the wire.
The hex tax
WKB is binary, but binary rarely survives a SQL console, a JSON payload, or a web page — so it is almost always handed to you as hexadecimal, where every byte becomes two characters. That is a flat 2× size penalty before you have encoded a single coordinate, and each 2D vertex already costs 16 bytes (two doubles) → 32 hex characters. It is why a modest polygon’s WKB hex runs to hundreds of characters.
If size is what brought you here, the geometry format size comparison guide measures WKB hex against WKT, GeoJSON, and TWKB on real geometries — including how much the hex envelope and the fixed-width doubles cost you versus TWKB’s varints.
PostGIS snippets
The functions you need to move between WKB, EWKB, and the human formats:
-- Geometry → WKB (OGC, hex) and → EWKB (PostGIS, hex)
SELECT ST_AsBinary(geom) AS wkb_hex FROM features; -- no SRID
SELECT ST_AsEWKB(geom) AS ewkb_hex FROM features; -- SRID embedded
-- WKB/EWKB → geometry
SELECT ST_GeomFromWKB(decode('0101000000b3ea73b5157f52c0c7293a92cb5f4440', 'hex'), 4326);
SELECT ST_GeomFromEWKB(decode('0101000020e6100000b3ea73b5157f52c0c7293a92cb5f4440', 'hex'));
-- Inspect without decoding by hand
SELECT ST_GeometryType(geom), ST_SRID(geom), ST_AsText(geom) FROM features;
Casting a geometry to bytea in psql already shows you the EWKB hex — the
\x-prefixed string you see in a raw SELECT geom is EWKB. Paste that
(with or without the 0x) straight into the decoder above.
Decoding WKB in code
Every mainstream geometry stack ships a WKB reader, so you should almost never hand-roll one:
- Python (Shapely):
shapely.wkb.loads(bytes)/shapely.wkb.dumps(geom, hex=True) - JavaScript: the
wkxpackage —wkx.Geometry.parse(Buffer.from(hex, 'hex'))(the same reader this site uses) - Java (JTS):
new WKBReader().read(bytes) - PostGIS:
ST_GeomFromWKB/ST_GeomFromEWKBas above
The annotator on this page hand-walks the bytes only to explain them; for the actual geometry and the map it uses the same engine as the universal geometry inspector, so what you see rendered is a real parse, not a best guess.
Sources and further reading
The byte layout and database examples above are checked against the standards publisher and current PostGIS reference documentation.
- OGC Simple Feature Access — Common Architecture — the standards family that defines WKB geometry encoding
- PostGIS ST_AsBinary — OGC/ISO WKB, endianness and SRID behavior
- PostGIS ST_AsEWKB — Extended WKB with embedded SRID metadata
- PostGIS ST_AsTWKB — Tiny WKB precision and size controls