Skip to content

DuckDB Extension

Lindel

Linearize multi-dimensional numeric arrays with Hilbert and Morton (Z-order) space-filling curves.

Quick reference PDF 1 page · Printable
2,117,401
extension loads · last 90 days
On this page

Technical Overview

Multi-dimensional data, sorted on one integer

Organize rows across multiple dimensions

Hilbert and Morton

  • • Hilbert: Follows a curve with no long jumps between consecutive positions on its integer grid. A useful starting point for locality-oriented sorting; nearby input points are not guaranteed to become adjacent rows.
  • • Morton / Z-order: Interleaves the coordinate bits. The mapping is simpler than Hilbert but has jumps at quadrant boundaries.
  • • Supported inputs and output width: Accepts signed and unsigned 8-bit integers in 1–16 dimensions, 16-bit integers in 1–8, 32-bit integers or FLOAT in 1–4, and 64-bit integers or DOUBLE in 1–2. The output is the smallest unsigned type that holds all component bits, up to UHUGEINT. HUGEINT and UHUGEINT are not input element types.

Prepare and decode coordinates deliberately

  • • Shift and quantize for numeric locality: Signed and floating-point inputs are supported directly, but their bit patterns are not normalized for numeric distance. For valid latitude and longitude, round((lat + 90) * 1e6)::UINTEGER and round((lon + 180) * 1e6)::UINTEGER make negative coordinates safe to cast and retain six decimal places in degrees. This is angular precision, not uniform distance in meters.
  • • Choose consistent units and ranges: Set the scale of each dimension to reflect the precision and relative importance your queries need. Keep those transforms consistent across files and batches. Use explicit fixed-size ARRAY casts and handle NULL coordinates before encoding.
  • • Decode with the original shape and key type: The decoder needs the dimension count, return_float, and return_unsigned flags. For unsigned integers use false, true; for signed integers use false, false; for floats use true, false. Preserve the encoded key’s SQL type because its width determines the component width. Community build 6435106 rejects one-dimensional signed-integer decoding; v1.5 source commit a92ec61 (extension version 2026100701) fixes it. Older community binaries may still be affected.
  • • A write-time ordering: Apply ORDER BY inside COPY to persist the layout. Queries still filter the original columns, and updated files or new batches need their own sorting. Measure scanned rows or bytes and query time against your existing layout; Lindel does not create a runtime index or promise a fixed speedup.

Deep Dive

Technical Details

Install

INSTALL lindel FROM community;
LOAD lindel;

Quick Start

Encode a multi-dimensional point to one sortable integer

-- A fixed-size numeric ARRAY becomes one unsigned integer
SELECT hilbert_encode([10, 20]::UINTEGER[2]) AS hilbert;
-- 884

Order rows by the curve — this is the Parquet write-time sort key

-- Sort nonnegative coordinates by their Hilbert key.
-- Use this ORDER BY inside COPY to persist the layout.
SELECT x, y, hilbert_encode([x, y]::UINTEGER[2]) AS hilbert
FROM (VALUES (3, 5), (1, 1), (7, 0), (2, 6), (5, 3), (0, 4)) AS t(x, y)
ORDER BY hilbert;

Compare Morton (Z-order) on the same coordinates

SELECT x, y, morton_encode([x, y]::UINTEGER[2]) AS morton
FROM (VALUES (3, 5), (1, 1), (7, 0), (2, 6), (5, 3), (0, 4)) AS t(x, y)
ORDER BY morton;

Reference

Extension Contents

Quick reference to all available functions and settings organized by category.

Hilbert
hilbert_decode() Object type: Scalar function Recover component values from a Hilbert-encoded key.
hilbert_encode() Object type: Scalar function Encode a fixed-size numeric array into an unsigned integer using the Hilbert curve.
Morton (Z-order)
morton_decode() Object type: Scalar function Recover component values from a Morton-encoded key.
morton_encode() Object type: Scalar function Encode a fixed-size numeric array into an unsigned integer by interleaving its coordinate bits (Morton / Z-order).

API Reference

Function Reference

Practical Examples

Cookbook

Real-world recipes and patterns for common use cases.

Platform Support

Compatibility

Extension availability may vary by platform and DuckDB version. Check below to ensure this extension supports your environment before installation.

Quick Facts

Release status Stable
Software License MIT
Pricing Free
Written In C++
Source Available Yes
View on GitHub
Usage
2,117,401
loads · last 90 days

Platforms

  • Linux x86_64 aarch64
  • Linux (musl) Not available
  • macOS Intel Apple Silicon
  • Windows x86_64
  • WASM eh mvp threads
Compiled binary sizes
Platform Architecture Size
Linux x86_64 4.14 MB
Linux aarch64 3.76 MB
macOS Intel 2.22 MB
macOS Apple Silicon 1.92 MB
Windows x86_64 7.46 MB
WASM eh 78.9 KB
WASM mvp 82.0 KB
WASM threads 66.5 KB

Compressed download size from the Haybarn extension repository.

DuckDB & Haybarn

Release calendar