Skip to main content

Reduce Image Size (Resize)

About the resize feature

What is it? Resize changes the height and width of JPG or PNG images before delivery. Set dimensions and fit mode using query parameters.

Example: Origin hosts 1100×1500 px image. With width=800&height=600, users receive 800×600 version. Origin unchanged.

Enable resize

Resize is included in the Image Optimizer service. Add query parameters to image URLs.

Use resize

Add query strings to image URLs:

image.jpg?width=800
image.jpg?height=600
image.jpg?width=800&height=600&fit=bounds

Resize parameters

Width

Resizes to specific width, preserving aspect ratio. Height calculated automatically.

?width=800

Height

Resizes to specific height, preserving aspect ratio. Width calculated automatically.

?height=600

Fit modes

Controls resize behavior when both width and height specified.

ModeBehaviorUse Case
fitResize + center crop to exact dimensionsThumbnails, cards
boundsUse greater dimension, resize proportionallyFlexible layouts
coverUse smaller dimension, resize proportionallyHero images
forceForce exact size, may distortExact dimensions needed

Default: fit=fit

fit=fit (default)

Resizes to cover the target area, then crops from center to exact dimensions.

Example: Origin image is 1000×500. You specify width=800&height=600.

  • Scale ratio: max(800/1000, 600/500) = 1.2
  • Resize to 1200×600, then crop center to 800×600.
?width=800&height=600&fit=fit

fit=bounds

Uses the greater of the two specified dimensions and resizes proportionally. The smaller dimension value is ignored; the other dimension is calculated from the aspect ratio.

Example: Origin image is 1000×500. You specify width=500&height=300.

  • Width (500) is greater than height (300), so width is used.
  • Aspect ratio is 2:1, so height = 500 / 2 = 250.
  • Result: 500×250.
?width=500&height=300&fit=bounds

fit=cover

Uses the smaller of the two specified dimensions and resizes proportionally. The larger dimension value is ignored; the other dimension is calculated from the aspect ratio.

Example: Origin image is 1000×500. You specify width=500&height=300.

  • Height (300) is smaller than width (500), so height is used.
  • Aspect ratio is 2:1, so width = 300 × 2 = 600.
  • Result: 600×300.
?width=500&height=300&fit=cover

fit=force

Forces exact dimensions, ignoring aspect ratio. May distort the image. Use sparingly.

?width=800&height=600&fit=force

Usage examples

<!-- Single dimension -->
<img src="photo.jpg?width=800" alt="Photo" />
<img src="photo.jpg?height=600" alt="Photo" />

<!-- Both dimensions -->
<img src="photo.jpg?width=800&height=600" alt="Photo" />

<!-- With fit mode -->
<img src="photo.jpg?width=800&height=600&fit=bounds" alt="Photo" />

<!-- Resize + quality -->
<img src="photo.jpg?width=800&quality=80" alt="Photo" />

<!-- Resize + crop + WebP -->
<img src="photo.jpg?width=1200&crop=16:9&fmt=webp" alt="Photo" />

Responsive images

<picture>
  <source srcset="image.jpg?width=1200" media="(min-width: 1200px)" />
  <source srcset="image.jpg?width=800" media="(min-width: 800px)" />
  <img src="image.jpg?width=400" alt="Responsive" />
</picture>

Check HTTP headers

curl -I https://your-cdn.com/image.jpg?width=800&height=600

Expected: X-Img-Operations: resizing

Limitations

Upscaling not supported

  • Requests larger than the original are rejected
  • Resize is skipped and other operations continue
  • Solution: Use appropriate source resolution

Dimension limits

  • Range: 1-10,000 px per side
  • Out of range values ignored
  • Large source images may hit the 150 MB resize memory budget (see Memory and dimension limits)

See limitations.md for details.

Processing order

  1. Resize - First
  2. Crop - Second
  3. Format + Quality - Last

Memory and dimension limits

The resize operation runs inside a Wasm module with limited memory (~150-200 MB).

How resize memory is calculated

The resizer uses a two-pass algorithm (horizontal then vertical) with u8 intermediates:

peak memory = source + intermediate + destination
            = (src_w × src_h × C) + (target_w × src_h × C) + (target_w × target_h × C)

Where C = 3 for RGB sources (JPEG, opaque PNG) or C = 4 for RGBA sources (PNG with transparency).

Maximum target dimensions (150 MB budget)

Source dimensionsSource typeMax target (approx)Peak memory
4096×4096RGB (C=3)~4050×4050142 MB
5499×2700RGB (C=3)~4800×2360148 MB
6000×4000RGB (C=3)~3800×2533147 MB
4096×4096RGBA (C=4)~2900×2900148 MB
5499×2700RGBA (C=4)~3500×1718147 MB

Calculating the max target width for your image

For a width-only resize (aspect ratio preserved):

target_h = src_h × target_w / src_w
max_target_w = (budget - src_w × src_h × C) / (src_h × C + target_h × C)

Where budget = 150 × 1024 × 1024 bytes (157,286,400).

What happens when the limit is exceeded

A pre-flight check estimates memory before allocating. If the estimate exceeds the budget:

  • The resize is skipped (not attempted)
  • The original full-resolution image is served
  • A log entry is written: Resize would require ~X MB, exceeding 150 MB budget
  • Other operations (crop, quality, format conversion) still apply

Performance

OperationTimeStatus
Resize<100ms✅ Excellent
Resize + Crop<150ms✅ Excellent

Uses CatmullRom (bicubic) filter via fast_image_resize crate for high-quality, memory-efficient resampling.

Troubleshooting

Resize not applied: Check syntax ?width=800, verify dimension limits (1-10000) Upscaling warning: Don't request larger than original dimensions Unexpected aspect ratio: Choose correct fit mode (bounds/cover/fit/force)