# Image thumbnail

Fetch each record's image and add a bounded WebP `data:` thumbnail.

## When to use it

Add a bounded thumbnail to each record containing an image address. A failed or missing image can leave the record usable with a reason for the absent thumbnail. Thumbnail success does not determine whether the article itself was successfully read.

## Add and configure

1. Add **Image thumbnail** from the workflow step picker.
2. Give the step a recognisable name and connect its required inputs.
3. Set the options below. Nested names identify fields within an object or a list item.
4. Validate the recipe, inspect the test result, then run it on the intended data.

The step identifier used in the editor’s code view is `image_thumbnail`.

## Settings

| Setting | Accepted value | Required | Default | What it controls |
| --- | --- | --- | --- | --- |
| Concurrency (`concurrency`) | integer; minimum 1; maximum 16 | No | 4 | Maximum simultaneous source-image fetches, from 1 to 16. concurrency × max_source_bytes must not exceed 32 MiB: all 16 fit at the 512 KiB default, while at most 4 fit at the 8 MiB ceiling. Raising this setting does not increase decoding concurrency. |
| Max Data Bytes (`max_data_bytes`) | integer; minimum 256; maximum 262144 | No | 16384 | Emit the WebP only when it is at most this many bytes; else null. |
| Max Edge Px (`max_edge_px`) | integer; minimum 16; maximum 1024 | No | 320 | The thumbnail's long edge is shrunk to at most this many pixels. |
| Max Source Bytes (`max_source_bytes`) | integer; minimum 1024; maximum 8388608 | No | 524288 | Hard cap on the fetched image body; the stream is abandoned past it. |
| Output Field (`output_field`) | string | No | "thumbnail_data_url" | Record field to write the data:image/webp;base64 thumbnail to (null when no image / not fetchable / over budget). |
| Timeout Seconds (`timeout_seconds`) | number; minimum 1.0; maximum 120.0 | No | 10.0 | Total deadline for ONE record's image fetch (resolution + connect + whole body); expiry is the per-record thumbnail_error_code 'timeout'. WARNING: the runner ALSO reads this key as the step's wall-clock timeout, so a value sized for a single slow image fails the whole run once the batch outlives it — leave it unset (default) or size it for the whole batch. |
| Url Field (`url_field`) | string | No | "image_url" | Record field holding the image URL to fetch (http(s), public hosts only). |

## Inputs and outputs

| Direction | Port | Content | Required | Multiple records |
| --- | --- | --- | --- | --- |
| Inputs | `in` | records | Yes | Yes |
| Outputs | `out` | records | Yes | Yes |

## Effects, testing, and recovery

Reads an external source.

The declared preview behaviour is to execute this step. Reads, processing, or model usage can therefore be real. Read [dry runs](/docs/workflows/dry-runs) before using a preview with live connections.

No duplicate-prevention key is declared for this step. Do not assume that manually repeating the step is free of repeated effects.

## Example: Add a thumbnail beside each crawled article

Step settings:

```json
{
  "url_field": "image_url"
}
```

Input records:

```json
[
  {
    "image_url": "https://news.example.com/img/rates.jpg",
    "url": "https://news.example.com/2026/09/rates"
  }
]
```

## Example: Smaller thumbnails under a tighter byte budget

Step settings:

```json
{
  "concurrency": 8,
  "max_data_bytes": 8192,
  "max_edge_px": 160,
  "output_field": "photo_thumb",
  "url_field": "photo"
}
```

Input records:

```json
[
  {
    "photo": "https://shop.example.com/a-100.png",
    "sku": "A-100"
  }
]
```

## Check the result

Inspect the selected run’s status, counts, errors, and output records. An empty collection can be a valid result, and a completed step can contain per-record failures where the step defines that behaviour. Check the next step’s expected record shape before publishing or delivering the result.
