---
title: "Media at Scale: Callbacks vs pipelines"
description: "Shopify’s Rails monolith needed to add native product videos and 3D models while continuing to support an image infrastructure containing more than 7 billion images. The design question was whether media creation should rely on Active Record callbacks or an explicit pipeline, with transactions protecting interdependent database writes. Callbacks were quick for simple cases, but adding media-specific behavior such as video thumbnails spread conditionals across models and made lifecycle ordering difficult to follow and debug. The pipeline design routes requests through a single Product Create Media Service and media handlers, each organized into before_transaction, during_transaction, and after_transaction steps, while confining logic to one media type. This structure separates concerns, controls creation order, limits model access, and makes implementation details easier to understand and maintain as the feature grows."
---

# Media at Scale: Callbacks vs pipelines

[Shopify](https://yomu.fyi/company/shopify) · 2023-10-18 · Jul 9, 2020

**Type:** Problem & solution

## Summary

Shopify’s Rails monolith needed to add native product videos and 3D models while continuing to support an image infrastructure containing more than 7 billion images. The design question was whether media creation should rely on Active Record callbacks or an explicit pipeline, with transactions protecting interdependent database writes. Callbacks were quick for simple cases, but adding media-specific behavior such as video thumbnails spread conditionals across models and made lifecycle ordering difficult to follow and debug. The pipeline design routes requests through a single Product Create Media Service and media handlers, each organized into before\_transaction, during\_transaction, and after\_transaction steps, while confining logic to one media type. This structure separates concerns, controls creation order, limits model access, and makes implementation details easier to understand and maintain as the feature grows.

## Context

The Shopify Admin needed to add videos and 3D models to products while supporting the legacy image infrastructure. The design also required safe database writes for interdependent media records in a large Rails monolith.

## Approach / What changed

The implementation replaced media-related callbacks with a pipeline composed of a Product Create Media Service, a media create handler, and separate handlers for each media type. Each handler uses before\_transaction, during\_transaction, and after\_transaction methods, with transactions coordinating database persistence.

## Takeaways

- Callbacks are quick to implement for simple media cases, but growing media-specific logic can spread conditionals across Active Record models and obscure lifecycle ordering.
- The pipeline confines each media type’s behavior to its own handler and exposes a single service entry point, reducing the caller’s knowledge of implementation details.
- The pipeline controls the order of creation, updates, and deletions, while its steps should perform only the expected action and avoid side effects.

**Tags:** [Architecture](https://yomu.fyi/topic/architecture), [Rails](https://yomu.fyi/topic/rails), [Ruby](https://yomu.fyi/topic/ruby)

- Source: [Shopify](https://shopify.engineering/media-at-scale-callbacks-vs-pipelines)
- Source URL: https://shopify.engineering/media-at-scale-callbacks-vs-pipelines
- Ingested by Yomu: 2026-08-31T01:12:18.413Z

[Read original post](https://shopify.engineering/media-at-scale-callbacks-vs-pipelines)
