Skip to content

SYSTEM Cited by 1 source

Instacart CRM Service

What it is

The CRM Service is the vendor-abstraction layer in Instacart's multi-tenant marketing-automation platform. It is a Rails engine backed by Sidekiq async workers distributed across multiple nodes that:

  1. Receives per-batch events from the upstream stream consumer (after rebatching per-user events into groups of up to 50).
  2. Validates idempotency to handle the streaming layer's at-least-once delivery semantics.
  3. Routes each request to the correct retailer workspace inside the third-party provider — workspace- per-retailer is the tenant boundary.
  4. Assembles personalized content by merging retailer- specific template variables with the base Liquid template.
  5. Integrates with the third-party provider through a clean abstraction layer that hides provider-specific behavior from the rest of the platform.

(Source: sources/2026-05-14-instacart-scaling-personalized-marketing-for-multi-tenant-commerce-platforms)

The vendor-abstraction-layer design point

Verbatim from the 2026-05-14 post: "Just as importantly, this service isolates provider-specific behavior behind a clean abstraction layer. That gives us flexibility to change providers in the future, support multiple providers at once, and avoid tightly coupling our core platform to any one vendor."

This is the canonical wiki instance of patterns/vendor-abstraction-service-layer — a service that exists primarily to mediate between platform code and a particular vendor's quirks (rate limits, batch sizes, payload schema, auth flow, workspace identifiers) so that the rest of the platform doesn't acquire vendor-shaped scars.

Rails engine + Sidekiq architecture

"The CRM Service is implemented as a Rails engine backed by asynchronous Sidekiq workers distributed across multiple nodes."

The two cited advantages of the engine + worker split:

  1. Lightweight ingestion path. "Keeps the ingestion path lightweight by offloading the heavier personalization and delivery work to background jobs."
  2. Horizontal scaling. "Allows us to scale horizontally by adding worker capacity as campaign volume increases."

The Sidekiq queue is the buffer between the steady-rate streaming-layer ingest and the bursty-rate downstream third-party API calls.

Idempotency at the at-least-once boundary

"When the stream consumer forwards a batch, the CRM Service first validates idempotency to account for at-least-once delivery semantics in the streaming layer."

The streaming substrate may redeliver a batch event after a worker crash or network partition; the CRM Service must deduplicate using the idempotent message identifier attached to each request. Deduplication happens before the heavier personalization work, so a redelivered batch costs only an idempotency-table lookup, not a full re-personalization + vendor API call.

Persisted send-result store

"We also persist and send results in a dedicated datastore, which gives us a durable record of message delivery and helps support observability, retry handling, and operational debugging."

The persisted send-result table is the substrate for:

  • Observability — campaign-level send-rate / delivery / open / click metrics rolled up to operational dashboards.
  • Retry handling — vendor failures or transient errors can be replayed against a known-good source of truth.
  • Operational debugging — supporting per-message audit when a retailer escalates a delivery question.

The 2026-05-14 source does not name the substrate (Postgres / DynamoDB / something else).

Workspace-routed delivery

The CRM Service is the layer where the multi-tenant routing decision lives. Each batch carries the retailer identifier; the CRM Service maps that to the correct third-party provider workspace (which holds the retailer's customer data, templates, and rate-limit budget) and dispatches the send. The rest of the platform — Campaigns Engine, stream consumer — is multi-tenant only at the data level, not at the infrastructure-routing level.

Composes with

Caveats

  • The 2026-05-14 source is the first wiki disclosure of the CRM Service.
  • Worker-pool sizing, queue topology, retry policy, and idempotency-key TTL are not described.
  • The third-party-provider product is not named.
  • The persisted-send-result datastore is not named.

Seen in

Last updated · 542 distilled / 1,571 read