gdal_merge
What is gdal_merge?
gdal_merge.py combines several rasters into one output file — either by placing them in a common extent and overlaying by paint order, or by stacking them as separate bands with -separate. Unlike gdalwarp it does not reproject, cutline, or resample with proper filtering; it is a blunt, fast mosaicker best used on tiles that share CRS, resolution, and band structure.
gdal_merge.py [options] <input_file_1> [<input_file_2>...]Commonly used options:
-o <out_filename>— output file (defaultout.tif)-of <format>— output driver (defaultGTiff)-ot <type>— output data type-separate— stack inputs as separate bands-n <nodata_value>— ignore these pixels in the source (transparent overlay)-a_nodata <value>— set output NoData-init "<v1> [<v2>...]"— initial fill value before mosaicking-ps <pixelsize_x> <pixelsize_y>— output pixel size-ul_lr <ulx> <uly> <lrx> <lry>— explicit output extent-co <NAME>=<VALUE>— creation options-pct— copy the colour table from the first input
When would you use gdal_merge?
Use gdal_merge.py for quick mosaics of tiles that already match (same CRS, same pixel size, no overlaps needing blending): gdal_merge.py -o mosaic.tif -co COMPRESS=DEFLATE tiles/*.tif. It is also handy for stacking single-band products into a multi-band raster with -separate: gdal_merge.py -separate -o stack.tif b4.tif b3.tif b2.tif produces an RGB-like stack from three Sentinel-2 bands.
For anything beyond the simplest case — inputs with different CRSes, overlapping tiles that need feathering, irregular resolution — prefer gdalwarp which has proper resampling, or gdalbuildvrt followed by gdalwarp for truly large mosaics. gdal_merge.py remains useful for its simplicity and because it is easy to reason about: later inputs overlay earlier ones pixel-for-pixel.
FAQs
gdal_merge vs gdalwarp vs gdalbuildvrt — which should I use?
gdalbuildvrt for zero-cost virtual mosaics used as intermediate inputs. gdalwarp for authoritative mosaics with proper resampling, CRS handling, and multi-threading. gdal_merge.py for simple same-grid mosaics and for -separate band stacking. On modern GDAL, most practitioners prefer gdalwarp for real outputs because it handles more cases and is faster on large inputs.
How does overlap handling work?
gdal_merge.py overlays inputs in the order given — last file wins for overlapping pixels — unless -n <value> is set, in which case that value in the later input is treated as transparent. There is no feathering or blending; the seam is hard. For seamless mosaics, use gdalwarp with proper cutlines or a dedicated mosaicking tool.
Does gdal_merge reproject?
No. Inputs must share a CRS. If you need to combine rasters in different CRSes, reproject each to a common one with gdalwarp first, or build a VRT with -allow_projection_difference and warp that to a single CRS.
Why is my output misaligned or the wrong size?
Without -ps, -ul_lr, or -tap, gdal_merge.py picks a grid from the first input and may produce half-pixel offsets when later inputs do not align. For predictable grids, set -ps explicitly or — again — use gdalwarp -tap -tr, which snaps to a clean origin.