FlatGeobuf: a binary encoding for large static vector datasets
A performant binary encoding for geographic data based on flatbuffers
At a glance
- What is it?
- A flatbuffers based format for Simple Features that skips the spatial index when you do not need it, so a file can be streamed or appended. The performance numbers in the README come from GDAL tests on Danish data.
- Who is it for?
- FlatGeobuf suits a team publishing large, mostly static vector layers, such as basemap extracts or cadastral data, that wants a smaller and faster file than GeoJSON or GML and a web client that can filter it over HTTP. It does not suit a workload that edits geometry in place, because random writes are not supported by design.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A format shaped by two deliberate omissions
FlatGeobuf is a binary encoding for geographic data built on flatbuffers, and it can hold a collection of Simple Features including circular interpolations as defined by SQL-MM Part 3. Two design decisions define it. First, random writes are deliberately not supported, for simplicity and so that the data can be clustered on a packed Hilbert R-tree. Second, that spatial index is optional, which exists so the format can be written efficiently as a stream, can support appending, and can be used where spatial filtering is not needed at all. The stated goals follow from those choices: suitability for large volumes of static data, speed against legacy formats with no size limits on contents or metainformation, and suitability for streaming and random access. It was inspired by geobuf and flatbush, and the project points at switchfromshapefile.org for a fuller account of what legacy formats get wrong.
The file layout is four parts, one of them optional
The specification is short enough to read in a minute, which is a deliberate choice for a format meant to be implemented in many languages. The layout is described as magic bytes, a header, an optional static packed Hilbert R-tree index, and the features themselves:
MB: Magic bytes (0x6667620366676201)
I (optional): Static packed Hilbert R-tree index (static size [custom buffer](https://github.com/flatgeobuf/flatgeobuf/blob/master/src/cpp/packedrtree.h))
DATA: Features (variable size [flatbuffer](https://github.com/flatgeobuf/flatgeobuf/blob/master/src/fbs/feature.fbs)s)Versioning rides on the magic bytes. The fourth byte indicates the major specification version and the last byte the patch level, and the rule is that patch level is backwards compatible, so an implementation for a major version should accept any patch level. Strings are assumed to be UTF-8. The header and the feature structures are flatbuffers schemas living in the repository, the index uses a custom buffer described in a C++ header, and there is an OWL ontology for the specification alongside a format changelog document.
The performance tables are the project's own GDAL measurements
The README publishes two sets of numbers and is careful about their limits. The first set used OSM road data for Denmark in Shapefile form, containing 906602 LineString features with attributes, and the measurements were taken through GDAL with FlatGeobuf implemented as a driver. Reads were timed with loops of ogrinfo and writes with ogr2ogr conversion using the SPATIAL_INDEX layer creation option switched off and on:
ogrinfo -qq -oo VERIFY_BUFFERS=NOIn that table, relative to Shapefile, FlatGeobuf reads the full dataset in 0.46 and writes it in 0.39, while GeoJSON reads take 15 and GML 8.9, and size lands at 0.77. The spatial filter test used a small bounding box yielding only 1204 features, chosen to test index search performance rather than throughput. A second set on Danish cadastral data with 2511772 polygons and heavy attributes gives a full read figure of 0.12 relative to Shapefile, versus 0.23 for GeoPackage. The caveat is stated in the README itself, that performance is highly data dependent, so these are numbers to reason with rather than a promise.
Range requests and the CDN preflight problem
Serving a FlatGeobuf file over HTTP has a specific trap, and the README documents it in more detail than most format projects do. Fetching a subset of a file uses Range requests, so when a page accesses the file from a different domain than the content delivery network, cross-origin policy applies and the required Range header induces an OPTIONS preflight request. CDNs such as Cloudfront support Range requests but do not cache those preflight OPTIONS requests by default, which means the authorization round trip can be much slower than necessary. The README suggests enabling OPTIONS request caching on the CDN. It also notes that when using the spatial filter to get a subset of features, multiple requests are made, and that round-trip latency rather than throughput is often the limiting factor, so a caching CDN helps in exactly that case.
Reference implementations in seven languages
The format is not tied to one runtime. The README lists reference implementations for JavaScript, TypeScript, C++, C#, Go, Java and R, and the badges point to package registries for each ecosystem, with npm, Maven Central, Nuget and Crates.io all publishing the library under the FlatGeobuf name. The repository itself is a TypeScript and Rust workspace, with a pnpm workspace file, a Vite based development server, rolldown for the production bundle, vitest for tests and typedoc for API documentation. The package.json exposes several entry points beyond the root, including generic, geojson and ol subpaths, plus the lib and dist directories for deep imports, and the module field points at an ESM build. Example code in the repository covers Leaflet, MapLibre, OpenLayers, a plain Node example and a viewer, and the project site hosts matching live examples.
A working specification without tagged releases
Maintenance looks healthy from the outside, with the repository not archived and the last push on 2026-10-21, but there are no GitHub releases, so there is no version tag to pin against and no release notes to read. The npm manifest carries version 4.6.0, which is the number a JavaScript consumer would see, while the specification version travels in the magic bytes of the files themselves. That split matters in practice: the file format is versioned independently of the library releases, and the compatibility rule that a major version implementation should accept any patch level means an old reader can usually read a new file, while a new reader may not read an old file whose major version it does not implement. The licence is BSD 2-Clause, which is permissive enough for commercial use and for embedding in closed source products.
Editorial conclusion
FlatGeobuf suits a team publishing large, mostly static vector layers, such as basemap extracts or cadastral data, that wants a smaller and faster file than GeoJSON or GML and a web client that can filter it over HTTP. It does not suit a workload that edits geometry in place, because random writes are not supported by design. Before adopting, run the format comparison on your own data, since the README states performance is highly data dependent, and decide whether the spatial index belongs in the file or whether streaming matters more.
Frequently asked questions
What is FlatGeobuf?
It is a binary encoding for geographic data based on flatbuffers that holds a collection of Simple Features, including circular interpolations as defined by SQL-MM Part 3.
Does FlatGeobuf support random writes?
No. The README states it deliberately does not support random writes, for simplicity and to be able to cluster the data on a packed Hilbert R-tree.
Is the spatial index required in a FlatGeobuf file?
No. It is optional, so the format can be written efficiently as a stream, can support appending, and works for use cases where spatial filtering is not needed.
Which languages have FlatGeobuf implementations?
The README lists reference implementations for JavaScript, TypeScript, C++, C#, Go, Java and R, with packages published on npm, Maven Central, Nuget and Crates.io.
What licence does FlatGeobuf use?
BSD 2-Clause, with the licence file in the repository root.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/flatgeobuf-flatgeobuf)Was this useful?