Looking for the best way to automate recurring pre-order update emails

We’re trying to build a better communication flow for customers who purchase pre-order items and would love to hear how others may have approached this.

Here’s the goal:

  • Customer places an order containing a pre-order item
  • They receive an initial confirmation email
  • If the order hasn’t shipped yet, we’d like to send an update every ~4-6 days letting them know we’re still waiting on inventory and provide an ETA
  • Once the item arrives and the order ships, the update emails should stop automatically

The biggest issue we’ve run into is that our estimated arrival messaging is stored in a custom product metafield (for example: “Early August”), but Shopify Email doesn’t appear to be able to display custom product metafield values in email templates. Because of that, we can’t dynamically show the current ETA to the customer

Ideally, we’d like to avoid maintaining individual order notes or manually updating every affected order whenever an ETA changes. We’d rather have merchandising update one field on the product and have customer communications reflect that automatically

A few questions:

  • Has anyone built a recurring pre-order update flow like this?
  • Is there a clean way to surface custom product metafields in Shopify Email that we’re missing?
  • If not, what’s the recommended architecture? Would you copy the product metafield to an order metafield at purchase, use Shopify Flow, or move the entire journey into another platform like Listrak/Klaviyo?
  • If you’ve implemented something similar, what cadence and messaging worked well for customers?

Would love to hear how others have solved this. Thanks!

Hi @KJL2024

This is a well-designed workflow, but you’ve identified the main limitation correctly—Shopify Email currently can’t render custom product metafields dynamically, so using a product metafield as the single source of truth for an ETA isn’t practical with Shopify Email alone.

If I were designing this, I’d separate the concerns:

  • Product metafield → Source of truth for the current ETA.

  • Shopify Flow → Handles order tagging, customer segmentation, and automation triggers.

  • Klaviyo (or Listrak) → Manages the recurring email sequence with dynamic content and automatically exits the flow once the order is fulfilled.

If you want to remain entirely within the Shopify ecosystem, copying the product metafield to an order metafield at checkout using Shopify Flow is a reasonable approach. However, keep in mind that this creates a snapshot of the ETA at the time of purchase. If the ETA changes later, existing orders won’t be updated automatically unless you build an additional synchronization workflow.

For stores with a significant volume of pre-orders, I’d avoid relying on order notes or manual updates. Keeping the ETA in a single product metafield and using an email platform capable of reading dynamic product data is much more scalable and easier to maintain.

Best regards,
Devcoder :laptop:

One practical addition on the snapshot problem: instead of copying the metafield onto each order, keep the ETA only on the product. Run a scheduled Shopify Flow every few days that pulls unfulfilled pre-order-tagged orders, reads the current product metafield, and sends an event carrying that value to Klaviyo. Each email then renders the latest ETA from the one field merchandising maintains. Worth adding a check for “ETA unchanged since last send” so customers are not mailed identical updates.

One thing I’d add is to make the cadence event-led as well as time-led. Send immediately when the ETA changes, then use the 4–6 day update only when nothing has changed. Each message can stay short:- item and current ETA- what changed since the last email (“no change” is useful too)- the date you’ll update them again- clear choices: keep waiting, ship available items separately if possible, or cancel/refundThat last line matters because uncertainty is usually what creates support tickets.I’d also store last_eta_sent and last_update_at against the order so the flow can suppress duplicates and stop on fulfillment or cancellation. Before launch, test mixed carts, two pre-order items with different ETAs, partial fulfillment, and an ETA that moves twice. Those are the cases most likely to produce a confusing email.

I Tested on a Shopify store: built this in Flow

Skip the copy eta into the order step being debated here. It is overly complicated.

Add a variable, walk to lineItems / product / metafield, enter your namespace and key, and Flow gives you value.

Your blocker is the send.

So delivery does have to leave Shopify. That is not the same as moving the whole journey to another platform.

Keep the logic in Flow, send with one HTTP call. Flow picks the orders and decides who gets mailed. Your email tool only renders.

  • Trigger: Scheduled time, repeating daily.
  • Get order data, query fulfillment_status:unshipped AND status:open AND tag:'pre-order' AND updated_at:<'{{ scheduledAt | date_minus: "5 days" }}'.
  • For each loop, over that list.
  • A condition, then Send HTTP request to your email provider.
  • Update order metafield last, writing the send date back.

Send it transactional, not marketing. Marketing sends only go to customers who opted in to marketing.

Stopping the email: The query drops an order the moment it ships or is cancelled, so the emails stop on their own.

Running the flow daily vs every 5 days:

Run the workflow daily. If you set the schedule itself to every 5 days, everyone gets mailed on the same days, and someone who bought yesterday gets an update tomorrow.

The 5 day gap comes from the query, not the schedule. updated_at only returns orders nothing has touched for 5 days, and the last step touches the order, so each one goes quiet for its own 5 days after its own email.

Worth knowing before you build it the other way: you cannot make that comparison in a condition. Flow hands a metafield back as a String and only offers string operators on it, so there is no is before or less than for a date.

Still write the order metafield. It is a readable record of when each order was last emailed. It is not a copy of the ETA either. The ETA stays on the product, where one edit updates everybody.

New email system:

You can make the from address the same, so customers see the same email id. Above I am using Postmark, you can use any.

HI @KJL2024

What you’re trying to do is a pretty common challenge with pre-orders, and I think you’re on the right track by wanting the ETA to live in a single source of truth rather than maintaining it at the order level.

From what I’ve seen, Shopify Email is probably the biggest limitation here. While it works well for standard campaigns, it doesn’t have the flexibility to reliably pull custom product metafields into email templates the way you’re describing. Because of that, I’d be hesitant to build the entire workflow around Shopify Email if the ETA needs to stay dynamic.

For the designing purpose, we divided the Product metafield and the Automation platform into 2 parts.

For the Automation itself, a flow could look something like this:

  • Customer places an order containing a pre-order item.
  • Tag the order (or customer) as “Preorder”.
  • Start a timed workflow that waits 4-6 days.
  • Before each email, check whether the order has been fulfilled. If it’s fulfilled, end the workflow. And if it isn’t, send an update and repeat the delay.

The one architectural decision I’d think about is whether you want the ETA to be dynamic or historical.

If you copy the ETA into an order metafield at checkout, every customer keeps the original estimate they sw when ordering. That’s useful for record-keeping but means changing the product ETA later won’t automatically update existing orders.

If the emails always reference the product metafield, then every future email reflects the latest ETA without touching individual orders. That sounds closer to what you’re trying to achieve since your merchandising team only has to update one field.

As for cadence, every 4-6 days feels reasonable. Any more frequent and customers may start ignoring the emails unless the ETA actually changes. I’d also avoid sending generic “still waiting” messages repeatedly. Even if the ETA hasn’t moved, it’s helpful to reassure the customer that:

  • their order is still reserved,
  • No action is needed from them.
  • You’ll notify them immediately once it ships.
  • Include the latest expected shipping window.

If you’re already using a platform like Klaviyo or Listrak, I’d lean toward running a journey there instead of Shopify Email. Those platforms generally offer much more flexibility for conditional logic and personalization, which makes recurring pre-order communication much easier to maintain.

I’d also be interested to hear how others have solved the “single source of truth” problem for changing ETAs, since that’s usually the trickiest part of these workflows.

This is an interesting use case, and I’d lean toward moving the journey outside of Shopify Email if you want it to be fully dynamic.

From what I’ve seen, Shopify Email has limitations when it comes to rendering product metafields, so platforms like Klaviyo or Listrak are usually a better fit for recurring pre-order communications.

One approach I’d consider is:

  • Keep the ETA in a product metafield so merchandising only updates it in one place.
  • Use Shopify Flow to identify unfulfilled pre-order orders.
  • Let your email platform pull the latest ETA dynamically each time an update email is sent, and automatically stop the flow once the order is fulfilled.

That way, you avoid copying data to individual orders and don’t have to update hundreds of orders whenever the ETA changes.

I’m curious whether Shopify has any plans to expose product metafields in Shopify Email, because that would make workflows like this much easier to build natively.