chronozarr compared with other formats
As of 2026-09-30. Statements about other projects come from their documentation and source and can go stale; check the project if a decision depends on one. Statements about chronozarr are measured or read from spec/CHRONOZARR.md and the tests in this repository.
The question each format answers is different, so the table ends with the case for choosing the other tool.
| Tool | What it stores and serves | Time axis | Values | CRS and serving | Choose it instead when |
|---|---|---|---|---|---|
| chronozarr | A Zarr v3 pyramid of (time, band, y, x) arrays, one group per level, one object per chunk by default (sharding is an option); optional star-delta temporal encoding | Native: any timestep of any level is at most two chunk reads | Exact stored values in uint8, uint16, int16 or float32; lossless; per-band scale and offset | Native projected CRS per store (UTM), never resampled to Web Mercator for storage; static bucket with byte ranges and CORS, no server | (reference row) |
| PMTiles | One archive of z/x/y tiles (vector or image) addressed by byte range | None. A time series is one archive per timestep | Whatever the tile image encodes: rendered 8-bit pixels, or values packed into color channels at the packing's precision | Web Mercator tile scheme in practice; static bucket with byte ranges, no server | You want finished map tiles (basemaps, vector layers, rendered imagery) for one moment, and broad client support across MapLibre, Leaflet and OpenLayers. You do not need raw values or a time scrubber. |
| Mapbox raster-array | Multi-band numeric raster tiles in the MRT format, produced by the Mapbox Tiling Service; bands can carry time steps or variables | As bands | Numeric values, decoded in the client | Web Mercator tiles. The format is tied to Mapbox's tiling service and renderer. The decoder code is published in mapbox-gl-js (src/data/mrt), so the dependency is on that service and renderer, not on a hidden decoder. | You already build on Mapbox GL JS and the Mapbox Tiling Service, want managed tiling and hosting, and can accept data resampled to Web Mercator. |
| ndpyramid + zarr-layer | Zarr pyramids written by ndpyramid (reprojected to a tile grid, or coarsened in place) and rendered by CarbonPlan's zarr-layer in MapLibre or Mapbox GL | Through zarr-layer selectors on a time dimension; each timestep is normally its own chunk, so there is no compression across time | Any Zarr dtype, typically float32 | zarr-layer reads proj: and spatial: attributes and supports arbitrary CRS through proj4 reprojection (its README lists the WGS84 UTM zones as built in). Static Zarr over HTTP. | You want the established MapLibre Zarr layer, float data, selectors over arbitrary dimensions; or your data already comes out of ndpyramid. A chronozarr store with encoding: none written after pixels_per_tile was dropped from multiscales (spec section 13) opens in zarr-layer unmodified (verified on the Ucayali store at level 1, point values equal to a direct Zarr read); a store written earlier opens with zarr-layer's crs and bounds constructor options. A star-delta store needs an adapter that reconstructs the residuals; stock zarr-layer does not do it. |
| COG + TiTiler | Single-timestep Cloud Optimized GeoTIFFs with internal tiles and overviews, rendered to image tiles by a tile server | One file per timestep, or STAC mosaics selected server-side | Exact values in any GDAL dtype, lossless compression available; point queries and band math run on the server | Any CRS; the server reprojects to a tile matrix. Needs a running service (container, serverless function) in front of the files. | Your data are already COGs or in a STAC catalog; you need server-side band math, many clients that read COG directly (GDAL, QGIS, rasterio), or single-date imagery; a server is acceptable. |
| GeoZarr | A set of conventions for geospatial Zarr (CRS, affine transform, multiscales), not a product; the multiscale layout is still a proposal | Whatever the dataset's dimensions are; no temporal encoding | Whatever the array holds | Any CRS the conventions can describe; static Zarr | You are publishing general-purpose geospatial arrays for analysis tools and want the community convention as it settles. chronozarr follows the same proj and spatial attributes and adds the temporal profile, band objects, mask, coverage and a browser reader on top. |
What chronozarr costs
- Modest temporal gain. Star-delta reduced compressed size by about 25% on arid scenes and about 6% on vegetated ones, which is why the writer keeps it only when a sample of cells compresses to 0.85 of the plain size or better. The encoding's measured effect is on size; the scrub-latency gains in the README come from worker-pool decoding and time-window prefetch (before and after table), which a plain store also gets.
- Large downloads for wide views. Values are lossless and unquantized. A 9-cell overview of the 117-month Ucayali store is about 11.7 MB per timestep; a cold loop over it is bound by the link.
- One reader implementation. The viewer is the only consumer that reconstructs star-delta and that uses the time-window prefetch. Any Zarr v3 client reads a
nonestore; other tools see residuals in a star-delta store. - GDAL support depends on the version. GDAL 3.12.4 opens an unsharded store (the writer default) as a raster of time-major bands with the geotransform, and fails on a sharded one (
Unsupported codec: sharding_indexed, tested here). The Zarr driver documents sharding support from GDAL 3.13 (GDAL Zarr driver); that version is not tested here. The writer emits the_CRSarray attribute GDAL reads, so GDAL assigns the CRS of an EPSG store (in a 3.12.4 test an added_CRSwas picked up whileproj:codealone was not; GDAL's documentation calls_CRSthe only CRS convention supported before 3.13). In a star-delta store GDAL sees residuals for non-anchor timesteps.chronozarr export-cogwrites true-value Cloud Optimized GeoTIFFs from any store for any GDAL or QGIS version. - Not a tile server. Products (true color, NDVI, water) are band math in the client's fragment shader. Anything that needs server-side rendering, mosaicking of many sources or arbitrary expressions belongs with COG + TiTiler.
What the others cost that chronozarr avoids
- A server to run and scale (TiTiler).
- Resampling every timestep to Web Mercator before storage (PMTiles, Mapbox raster-array, ndpyramid's reprojected pyramids), which biases block statistics and discards native pixels.
- A fresh chunk fetch per timestep with no shared state between timesteps (stores with one timestep per chunk, the common zarr-layer layout); the time-window prefetch and the optional temporal encoding address that cost.
- A dependency on one vendor's tiling service and renderer (Mapbox raster-array).