Cloud Optimized GeoTIFF (COG) — Cloud Raster OGC Standard: HTTP Range, Overviews, and OSM Export
Cloud Optimized GeoTIFF, or COG for short, is a regular GeoTIFF with two strict internal constraints: data must sit in internal tiles (default 512×512 pixels), and there must be an overview pyramid on top (downsampled versions for zoom-outs). These two conventions alone let a client use HTTP range requests to read only the needed slice of a 50 GB satellite image without downloading the file. The format traveled from the informal cogeo.org community spec (2017) to a full-fledged OGC 21-026 standard (July 2023), becoming the standard for NASA Earth Data, Planet Labs, Maxar, Microsoft Planetary Computer, USGS 3DEP. On osm2cdr.ru cog_exporter.py first renders a GeoTIFF through QGIS layout export, then runs gdal_translate -of COG -co TILING_SCHEME=GoogleMapsCompatible, baking a CloudFlare R2 / AWS S3 hosting-ready file with internal Google Maps tile scheme and an overview pyramid.

History: from vsicurl 2016 to OGC standard 2023
COG's story starts not with a spec but with a GDAL feature. In 2016 Even Rouault (chief GDAL maintainer) added the vsicurl driver — a virtual filesystem layer that reads files over HTTP with range request support. That made it possible to "open" a GeoTIFF sitting on S3 as a local file — but only if the GeoTIFF was structured so that range reads hit the right bytes.
In early 2017 Chris Holmes (Planet Labs, cloud-native geo evangelist) and Even Rouault jointly published an informal spec on cogeo.org: "how a GeoTIFF must be organized to work well over HTTP range". Core principles: 1. Internal tiling — data inside the file is organized in tiles (typically 512×512), not strips. 2. Overview pyramid — downsampled copies for every zoom-out level (0.5x, 0.25x, 0.125x, ...). 3. Header front-loaded — the IFD (Image File Directory) with metadata sits at the file start so a first ~16 KB range read gives the client a full structural picture.
By 2019 STAC (SpatioTemporal Asset Catalog) — a JSON standard for cataloging raster datasets — included COG as the primary asset format. NASA, Planet Labs, Microsoft Planetary Computer, AWS Open Data all standardized on COG + STAC.
In July 2023 OGC formally ratified the Cloud-Optimized GeoTIFF Specification as standard 21-026 version 1.0. That cemented COG's status as an international standard equivalent to GeoTIFF 1.1 and GeoPackage 1.3. After that COG became a requirement in open government tenders for satellite imagery and NASA/ESA RFPs.
Inside the file: tiles + overviews
GeoTIFF (parent format) is TIFF with extra tags 33550/33922/34735/34736/34737 (ModelPixelScaleTag, ModelTiepointTag, GeoKeyDirectoryTag, GeoDoubleParamsTag, GeoAsciiParamsTag) describing the coordinate system. COG adds on top:
Internal tiling. Raster data is stored in square tiles, not strips — typically 512×512 pixels. That means fetching pixels from an arbitrary rectangle requires reading 1–4 entire tiles, not millions of strip rows. Tile size is configured via -co BLOCKXSIZE=512 -co BLOCKYSIZE=512 in gdal_translate.
Overview pyramid. On top of the main pixel layer (level 0, full resolution) sit downsampled versions — level 1 (50% size), level 2 (25%), level 3 (12.5%), and so on down to a single-tile thumbnail. That lets the client at zoom-out levels read the matching downsampled layer instead of reading full resolution and downsampling on the fly.
Front-loaded structure. TIFF metadata (IFDs) sits in the first bytes of the file, not the end. The client gets full schema from a first 16 KB HTTP request, understands tile positions, overview sizes, CRS — then makes targeted reads.
HTTP-friendly compression. Inside tiles, compression is LZW / DEFLATE / Zstd (lossless) or JPEG / WEBP (lossy). Each tile compresses independently so a range read can pull only the wanted tiles and decompress them without touching neighbors.

Cloud-native trio: COG + GeoParquet + STAC
COG belongs to the 2020s cloud-native geo stack that fully removes the need for a server-side GIS. Three pieces:
- COG — for raster data (satellite imagery, DEM, ortho-photo, derived rasters).
- GeoParquet — for tabular vector data (POIs, buildings, roads in columnar format).
- STAC (SpatioTemporal Asset Catalog) — a JSON catalog for indexing datasets: a list of COG / GeoParquet files with bbox, time, metadata.
All three are hosted on S3-compatible object storage (AWS S3, CloudFlare R2, Backblaze B2, MinIO) with no database or application server. The client (QGIS, DuckDB, rio-tiler) talks directly over HTTP. This delivers zero-server pricing for open data publishing — NASA Earthdata, USGS 3DEP, Microsoft Planetary Computer work exactly this way.
Strengths and weaknesses
Strengths. Backward-compatible with regular GeoTIFF — any program reading GeoTIFF reads COG (overviews are ignored, internal tiling is invisible). HTTP range requests — read only the needed slice without full download. Single file on static hosting (S3/R2/GitHub Pages) — no server. Efficient overview storage in the same file — no loss of coordinate metadata. Supports every GeoTIFF feature: CRS, multi-band, BigTIFF (>4 GB), any compression. Since July 2023 — formal OGC standard.
Weaknesses. File size 15–30% larger than plain GeoTIFF due to the overview pyramid (a streaming tradeoff). Not optimized for editing — each change requires overview regeneration. Not for small files (<10 MB — overview overhead beats the savings). Needs GDAL 3.1+ for full COG features. Not directly browser-viewable without libraries (needs TiTiler / rio-tiler / Cesium ion for tile serving).
COG vs PMTiles vs Zarr vs MBTiles
Cloud-native matrix: - COG — raster geodata (satellite, DEM, ortho). Single-file HTTP streaming. - PMTiles — vector tiles (MVT) in a single file. Same idea as COG but for vector basemaps. - Zarr — multidimensional scientific arrays (4D timeseries climate data, for example). For atmospheric, oceanographic data. - MBTiles — SQLite-based local tile storage. Not optimized for cloud (no range-read pattern). Standard for offline apps.
For static raster datasets in the cloud — COG. For vector tiles — PMTiles. For climate/ocean 4D — Zarr. For offline — MBTiles.
Use cases
Cloud analyst in Jupyter. Through rasterio or rio-tiler opens a 5 GB district ortho-photo directly from S3, reads only the bbox of interest, runs analysis in xarray / numpy. No local downloads.
Web cartographer with TiTiler. TiTiler (open-source FastAPI service by DevSeed) takes a COG URL as input and serves it as XYZ tiles for MapLibre/Leaflet. One TiTiler instance serves any number of COGs without preprocessing.
Government open data publisher. USGS publishes 3DEP 1-meter DEM as COG on AWS Public Datasets — users download only the wanted region via QGIS or stream through rasterio. Infrastructure cost — zero (S3 Requester Pays).
Satellite imagery analyst. Planet Labs / Maxar / Sentinel Hub publish daily scenes as COG in S3. The analyst, through pystac-client + rio-tiler, gets only the wanted scene and bbox without downloading the full dataset.
OSM cartographer with custom rendering. Export an OSM area as COG via osm2cdr → upload to CloudFlare R2 → integrate into a custom web app through a model-viewer-like component. Hosting cost is almost zero.
Software for COG
QGIS. Free, cross-platform. Since 3.16+ natively supports COG via GDAL. You can open a COG straight from URL: Layer → Add Layer → Add Raster Layer → Protocol HTTP/HTTPS/FTP → URL starting with /vsicurl/https://.... Works over range requests without full download.
GDAL / rasterio. Free. gdal_translate -of COG input.tif output.tif -co TILING_SCHEME=GoogleMapsCompatible -co COMPRESS=DEFLATE -co OVERVIEWS=AUTO is the canonical command for COG creation. rio cogeo create input.tif output.tif — the rasterio CLI alternative.
TiTiler. Free (open-source) FastAPI service. Takes a COG URL and serves XYZ tiles. Deploys to AWS Lambda / Cloud Run / Docker in minutes.
rio-tiler. Python library for tile serving from COG. Used inside TiTiler.
Cesium ion. Paid hosting service for COG / 3D Tiles from Cesium. Simple integration with CesiumJS on the frontend.
Microsoft Planetary Computer. Free scientific hosting for NASA / Sentinel / Landsat COG datasets. Browseable STAC catalog + Python SDK.
Google Earth Engine. Doesn't open arbitrary COGs (closed platform), but exports data to COG for downstream use.
Pipeline in OSM2CDR
Our cog_exporter.py is a two-step pipeline:
Step 1: Render GeoTIFF. QGIS layout exporter turns vector OSM layers into a raster image with proper georeferencing. DPI is configurable (72/150/300/600), bbox set by the user, CRS picked from 165 supported.
Step 2: Convert to COG. gdal_translate -of COG -co TILING_SCHEME=GoogleMapsCompatible -co COMPRESS=DEFLATE -co OVERVIEWS=AUTO converts a regular GeoTIFF into COG with:
- Internal tiles 256×256 (GoogleMapsCompatible scheme by convention) or 512×512 (default COG)
- DEFLATE compression (lossless, good balance)
- Overview pyramid automatic (4 overview levels for medium files)
- BigTIFF=YES for files > 4 GB
- Front-loaded IFD for efficient range reads
The GoogleMapsCompatible tiling scheme is the key differentiator: tiles align with the Google Maps / OpenStreetMap web-mercator tile pyramid. That means the COG file can be served by TiTiler as XYZ tiles directly without on-the-fly reprojection. For scientific datasets (where another projection is needed) use the default tiling without scheme.
Validate output through rio cogeo validate output.tif — that command checks the file matches OGC 21-026.

FAQ
What's the difference between COG and regular GeoTIFF? A regular GeoTIFF can be organized any way — strips, tiles, any compression. COG adds two strict requirements: internal tiling (typically 512×512) and an overview pyramid. That makes COG efficiently readable over HTTP range requests. A file that doesn't meet these requirements may still be called GeoTIFF, but not COG.
Can QGIS read COG as plain GeoTIFF? Yes. COG is a GeoTIFF with extra constraints. Any GeoTIFF-reading program reads COG as a regular file. HTTP range read benefits are simply lost on a local copy.
Where to host COG? Best choice — CloudFlare R2 ($0 egress, ~$0.015/GB storage). Alternatives: AWS S3 ($0.023/GB + egress), Backblaze B2, MinIO self-hosted, GitHub Pages (only for files < 100 MB). Main requirement — HTTP range request support (every S3-compatible service has it).
Is COG compatible with older GDAL? GDAL 2.4+ can read COG as a regular GeoTIFF (overviews are used automatically). Creating COG with the proper structure via the -of COG driver requires GDAL 3.1+ (shipped July 2020). Older versions created COG through the hack gdal_translate -co COPY_SRC_OVERVIEWS=YES, which sometimes produced incorrect structure.
Which compression is best for COG? For maps/orthos with continuous tonal range — JPEG (q=85) is 5–10x more compact than DEFLATE with imperceptible loss. For diagram-style maps (like our OSM export with sharp edges) — DEFLATE or Zstd (lossless). LZW — most compatible with older GDAL but less efficient. JPEG2000 is supported but too heavy CPU-wise.
Related
- GeoTIFF — raster geodata format since 1995
- GeoTIFF and remote sensing — practice
- Best free GIS formats 2026
- PMTiles — cloud-native single-file vector format
- Zarr — multidimensional scientific geodata
Sources
- OGC COG Specification 21-026 — docs.ogc.org/is/21-026/21-026.html
- cogeo.org community specification — cogeo.org
- GDAL COG driver — gdal.org/drivers/raster/cog.html
- rio-cogeo (Mapbox/DevSeed) — github.com/cogeotiff/rio-cogeo
- TiTiler (DevSeed) — github.com/developmentseed/titiler
- Microsoft Planetary Computer — planetarycomputer.microsoft.com