BigTIFF: TIFF Without the 4 GB Limit
What Is BigTIFF?
BigTIFF is an extension to the classic TIFF (Tagged Image File Format) that removes the most severe constraint of the original 1992 format: the hard 4 GB file size limit. While ordinary TIFF uses 32-bit file offsets — limiting any single file to 2^32 = 4,294,967,296 bytes (~4 GB) — BigTIFF uses 64-bit offsets, allowing single image files up to 18 exabytes (2^64 bytes) in theory.
BigTIFF files use the same .tif or .tiff extension as regular TIFF, but can be distinguished by their magic bytes: classic TIFF starts with 49 49 2A 00 (little-endian) or 4D 4D 00 2A (big-endian), while BigTIFF starts with 49 49 2B 00 (little-endian) or 4D 4D 00 2B (big-endian) — the version field changes from 0x002A (42) to 0x002B (43).
Why 4 GB Isn't Enough Anymore
The original TIFF 6.0 specification (1992) was designed when 4 GB seemed impossibly large. Today, several common use cases routinely exceed this limit:
- Whole-slide pathology images: A single digitized glass slide at 40× magnification can produce a 3–15 GB TIFF (typical: 100,000 × 80,000 pixels at 24-bit RGB = ~23 GB uncompressed)
- Satellite and aerial imagery: A single WorldView-3 panchromatic scene at 0.31 m resolution covering 13×13 km is ~1.5 GB; full ortho-mosaic tiles are routinely 10–50 GB
- Large-format document scanning: A single A0 technical drawing scanned at 600 DPI × 24-bit color = ~4.6 GB uncompressed
- Microscopy Z-stacks: Fluorescence microscopy with 100+ Z-slices at 16-bit depth across multiple channels easily reaches 20+ GB per acquisition
- GeoTIFF mosaics: Country-level or continent-level terrain rasters (30 m resolution DEM for North America = multiple terabytes)
Internal Structure Differences
| Feature | Classic TIFF | BigTIFF |
|---|---|---|
| Magic bytes (LE) | 49 49 2A 00 |
49 49 2B 00 |
| Version field | 42 (0x002A) | 43 (0x002B) |
| Offset size | 32-bit (4 bytes) | 64-bit (8 bytes) |
| Max file size | ~4 GB | ~18 EB |
| IFD entry value size | 4 bytes | 8 bytes |
| IFD offset to next | 32-bit | 64-bit |
| Tag count field | 16-bit | 64-bit |
BigTIFF preserves the entire TIFF tag ecosystem — all existing TIFF tags, including GeoTIFF tags for CRS/projection metadata, work identically. Only the offset arithmetic changes.
Cloud-Optimized GeoTIFF (COG) and BigTIFF
Cloud-Optimized GeoTIFF (COG) is a BigTIFF-compatible layout convention that enables efficient HTTP range-request access to remote files without downloading the entire file:
- Overview (pyramid) levels stored first in the file (smallest resolution at the top)
- Tiles (typically 256×256 or 512×512) rather than strips — tile bytes are contiguous for O(1) access
- Ghost metadata in the first IFD that lists all tile/overview offsets
- A standard
gdal_translatecommand creates COGs:
gdal_translate input.tif output_cog.tif \
-co TILED=YES \
-co COMPRESS=DEFLATE \
-co COPY_SRC_OVERVIEWS=YES \
-co BIGTIFF=IF_NEEDED
COG + BigTIFF is the standard for cloud-native geospatial workflows (AWS, GCS, Azure Blob Storage with GDAL's /vsicurl/ virtual filesystem).
Reading BigTIFF with Python
GDAL / rasterio (recommended for geospatial)
import rasterio
with rasterio.open('large_orthophoto.tif') as src:
print(src.profile) # {'driver': 'GTiff', 'width': 120000, ...}
print(src.width, src.height) # e.g. 120000 × 95000
# Read only a windowed region (avoids loading the full image)
from rasterio.windows import Window
window = Window(col_off=0, row_off=0, width=1024, height=1024)
data = src.read([1, 2, 3], window=window) # shape: (3, 1024, 1024)
# Check if COG
from rasterio.enums import MaskFlags
print(src.is_tiled) # True if tiled layout
libtiff (low-level C library via Python)
import tifffile
# tifffile handles both classic TIFF and BigTIFF transparently
with tifffile.TiffFile('pathology_slide.tif') as tif:
print(tif.is_bigtiff) # True
print(tif.pages[0].shape) # (height, width, channels)
# Read a region using asarray with key
page = tif.pages[0]
data = page.asarray() # Full page (careful with very large files!)
# Access pyramid levels (if present as sub-IFDs or series)
for level, series in enumerate(tif.series[0].levels):
print(f"Level {level}: {series.shape}")
ImageJ / FIJI
FIJI (ImageJ2 distribution) natively opens BigTIFF files — just File → Open. For very large files use the Bio-Formats plugin which streams tiles rather than loading the whole image.
Creating BigTIFF Files
GDAL
# Convert existing GeoTIFF to BigTIFF with tiling and LZW compression
gdal_translate input.tif output.tif \
-co BIGTIFF=YES \
-co TILED=YES \
-co BLOCKXSIZE=512 \
-co BLOCKYSIZE=512 \
-co COMPRESS=LZW \
-co PREDICTOR=2
# BIGTIFF=IF_NEEDED automatically switches to BigTIFF when output > 4 GB
gdal_translate input.tif output.tif -co BIGTIFF=IF_NEEDED
Python rasterio
import rasterio
from rasterio.transform import from_bounds
profile = {
'driver': 'GTiff',
'dtype': 'uint8',
'width': 150000,
'height': 120000,
'count': 3,
'crs': 'EPSG:4326',
'transform': from_bounds(-180, -90, 180, 90, 150000, 120000),
'compress': 'lzw',
'tiled': True,
'blockxsize': 512,
'blockysize': 512,
'bigtiff': 'yes', # key BigTIFF flag
}
with rasterio.open('world_ortho.tif', 'w', **profile) as dst:
dst.write(band1, 1)
dst.write(band2, 2)
dst.write(band3, 3)
libtiff C API
TIFF *tif = TIFFOpen("output.tif", "w8"); // "8" flag = BigTIFF mode
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, 150000);
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, 120000);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
// ... write strips or tiles
TIFFClose(tif);
Compression Options Inside BigTIFF
BigTIFF inherits all TIFF compression types:
| Compression | Tag value | Best for |
|---|---|---|
| None | 1 | Maximum speed (writing) |
| LZW | 5 | General purpose; predictor=2 for continuous tone |
| DEFLATE (ZIP) | 8 | Slightly better ratio than LZW |
| PackBits | 32773 | Legacy; fast but weak |
| JPEG | 6 | Lossy RGB imagery (use carefully) |
| LERC | 34887 | Floating-point scientific rasters |
| ZSTD | 50000 | Fast + good ratio (GDAL 2.3+) |
| LZ4 | 50001 | Fastest decompression |
| WebP | 50001 | Lossy RGB, small size |
For geospatial floating-point data (elevation, temperature, SAR intensity), use DEFLATE or ZSTD with PREDICTOR=3 (floating-point predictor) for best results.
Practical Tips
- Always use tiling (
TILED=YES, 256×256 or 512×512 blocks) — strip-based BigTIFF is nearly unusable for large files since reading any pixel requires seeking through the file - Build overviews before storing:
gdaladdo -r average output.tif 2 4 8 16 32 64 - Use
BIGTIFF=IF_NEEDEDin GDAL rather than always forcing BigTIFF — it auto-activates only when needed and avoids compatibility issues with software that doesn't read BigTIFF - Verify BigTIFF with
tiffinfo: look for "BigTIFF" in the first line of output - Not all software reads BigTIFF: Photoshop (with limited support), some older GIS viewers, and many embedded/IoT applications only support classic TIFF. Test recipients before sending
- COG is the cloud standard: for any file that will be accessed remotely, generate a Cloud-Optimized GeoTIFF layout
BigTIFF's 64-bit offsets unlock TIFF's rich tag ecosystem — including GeoTIFF's full CRS/projection metadata — for the era of multi-gigabyte to terabyte-scale imaging datasets.
Related conversions
Most teams that read this guide convert images in one of these directions: