Make's pricing is per-operation, where an operation is roughly one module execution. That billing model is easy to reason about for a scenario that runs a handful of times a day and expensive to ignore for anything syncing an ERP, because ERPs deal in bulk: order lines, inventory adjustments, ledger entries. A scenario that looks cheap in the editor can burn through an operations allowance fast once it's iterating over real record volumes.
Where the operations actually go
Every module firing on every item in an iterator counts. A scenario that fetches 500 order lines, then runs an Iterator module followed by three transformation modules per line, spends roughly 2,000 operations on one execution — the fetch is one operation, but each of the 500 iterations multiplies out. The fix usually isn't fewer modules, it's fewer per-item modules: batch operations where the target API supports them, and push filtering as early as possible so you're iterating over the 20 records that changed, not the 500 that didn't.
{
"flow": [
{"module": "http:ActionSendData", "name": "Fetch changed orders only",
"parameters": {"url": "{{env.erp_base}}/orders?modified_since={{lastRun.timestamp}}"}},
{"module": "flow:iterator", "name": "Iterate line items"},
{"module": "http:ActionSendData", "name": "Batch update inventory",
"parameters": {"batchSize": 50}}
]
}
Polling interval is a cost lever, not just a latency one
A scenario polling an ERP every minute runs 1,440 times a day regardless of whether anything changed. If the business doesn't need near-real-time sync, stretching the interval to every 15 or 30 minutes cuts operations proportionally with no functional loss for most back-office workflows — invoice sync, inventory reconciliation, and reporting exports rarely need minute-level freshness. Reserve tight polling intervals, or move to a webhook-driven trigger instead, for the handful of flows where latency genuinely matters, like payment confirmation.
A webhook-triggered scenario only runs when there's actually something to process. A polling scenario runs on a fixed schedule whether or not anything changed. If your ERP can push events, that's almost always the cheaper design as well as the faster one.
Router and filter placement changes the bill
Filters and routers that run after the expensive modules don't save anything — the operations were already spent by the time the filter discards the item. Move condition checks as early in the flow as possible, ideally into the initial fetch (query parameters, not post-fetch filtering) so records that don't need processing never enter the scenario at all.
Aggregators collapse operation count for bulk writes
Where the downstream API accepts a batch payload, use an Aggregator to collect iterator output into a single array and send one request instead of one request per record. This is the single highest-leverage change on most ERP scenarios I've reworked for cost: a nightly sync doing 800 individual order-update calls becomes a handful of batched calls, and the operation count (and often the wall-clock time) drops by an order of magnitude.
Operations usage tends to grow quietly as more fields, more validation steps, and more error-handling branches get added to a working scenario. Check the operations-per-execution trend monthly, not just when the bill jumps — by the time it jumps, the scenario has usually been overspending for weeks.
Wrapping up
ERP-facing Make scenarios get expensive from per-item module chains, tight polling intervals, and late-placed filters — not from having too many scenarios. Batch what the target API allows, filter as early as the fetch itself, and switch tight polling loops to webhooks wherever the ERP supports them. The cost problem and the reliability problem usually have the same fix: process less, and process it in fewer, larger steps.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.