architecture decision

ADR-003: Offload long-running catalog work to a dedicated worker

Slow and asynchronous catalog tasks (enrichment, image processing, bulk imports) run in a separate Product Worker so the Product API stays fast and predictable.

Decision RecordFebruary 18, 2026AcceptedArchitecturePerformance

Context

Some catalog operations are slow or bursty: enriching products with derived attributes, processing and optimising images, and ingesting large supplier feeds. Running this work inline in the Product APIProduct APIServicev1.0.0The public-facing API for the product catalog. Handles commands to create, update and delete products, serves product re...Subscribescreate-product, update-product +2APIsOpenAPIOwnerproduct-platformMapRepoView docs request path would make API latency unpredictable and couple the responsiveness of create/update/read operations to whatever heavy job happens to be running.

Decision

The Product Catalog System runs a dedicated Product WorkerProduct WorkerServicev1.0.0Background worker that handles long-running and asynchronous catalog work off the request path, such as enrichment, imag...Ownerproduct-platformMapRepoView docs for long-running and asynchronous tasks. The Product APIProduct APIServicev1.0.0The public-facing API for the product catalog. Handles commands to create, update and delete products, serves product re...Subscribescreate-product, update-product +2APIsOpenAPIOwnerproduct-platformMapRepoView docs handles validation, persistence and the outbox write synchronously, then returns; the worker picks up enrichment, media processing and bulk imports independently, reading from and writing back to the Product DatabaseProduct DatabaseContainerv1.0.0PostgreSQL database that is the system of record for all product data.MapView docs.

Consequences

  • The Product API has a small, predictable surface and stays fast under load.
  • Heavy work can be scaled, retried and scheduled independently of the API.
  • Some product attributes are eventually populated after creation, so consumers must not assume every derived field is present immediately.
  • There are now two services writing to the Product DatabaseProduct DatabaseContainerv1.0.0PostgreSQL database that is the system of record for all product data.MapView docs, so write paths must respect the same invariants and avoid conflicting updates.