Skip to content

Sequential access, random access, and materialisation

Copy page

The access mode is the contract for the order in which a pipeline may ask a loader for pixels. It is not the same thing as “the file arrived as a stream”: a JPEG opened sequentially can still be asked to seek backwards by a later operation.

Mode What the loader promises Where it fits
Random access Regions may be read in any order, more than once Unknown orientation, attention or entropy crops, several outputs from one image
Sequential access Usually one top-to-bottom pass Downscale, horizontal flip, most row convolutions, a single transcode
Materialisation Decode and buffer the full image into memory or a temporary file, then allow random reads The explicit cost of a random operation after a sequential stream

Sequential access is opt-in. govips sets AccessSequential on import parameters, sharp sets sequentialRead: true, pyvips passes access="sequential", and the CLI uses [access=sequential]. Leaving the switch unset does not make the four defaults identical.

The saver walks backwards from the output image and asks for pixels. A sequential loader can only move forward. It refuses the request when an operation needs a row from the bottom, needs a row it has already passed, or tries to feed one sequential pipeline to two consumers.

Diagnose in this order:

  1. Check whether the input was opened sequentially or has already been materialised (fully decoded into memory or a temporary file).
  2. Check whether the last operation before the failure needs random reads.
  3. Check whether the error is raised by Export, Save, or the CLI write.

A sequential path can usually still downscale, extract a region near the top, flip horizontally, convert colour space, and flatten.

These usually need random reads or a full materialisation: 90° and 180° rotation, vertical flip, entropy or attention crops, and a second read of the same sequential image. Choose random access before loading, or materialise first, when the pipeline needs them.

Materialisation buys random access with memory or temporary disk. It is not a cache miss, and running the job again does not remove the cost.