Data / ML · Make

Make Data Stores for Cross-Scenario State

Make's Data Store module gives scenarios a persistent key-value table without standing up a database, but its row limits, lack of transactions, and coarse locking mean it only fits a narrow set of jobs well.

John Kihiu12 min read

A Make Data Store is a table that lives inside your Make organization, addressable from any scenario, that survives between runs. It's the feature you reach for when a scenario needs to remember something across executions — the last processed record ID, a dedup key, a small lookup table — without provisioning an actual database. It works well for that. It works badly for anything that starts to look like real application state.

What a Data Store actually is

Structurally it's a schema-less key-value table: you define field names and types up front, then read and write rows via the Data Store modules (Add/Replace a Record, Search Records, Get a Record, Delete a Record) from any scenario with access to it. There's no query language beyond basic filters, no joins, no transactions. It behaves like a spreadsheet with an API in front of it, which is exactly the right amount of structure for tracking "have I seen this webhook payload before" and the wrong amount for modeling anything relational.

The good fit: dedup and checkpoints

The most common legitimate use is deduplication — a webhook can fire more than once for the same event, and a scenario that isn't idempotent will double-process it. Look up the event ID in a Data Store before acting on it; if it's there, skip; if not, write it and proceed. The second common use is a checkpoint: storing the last synced timestamp or record ID so a polling scenario knows where it left off instead of re-fetching everything on every run.

JSON · MAKE MODULE CONFIG
{
  "module": "datastore:ActionAddReplaceRecord",
  "parameters": {
    "datastore": "processed_webhook_events",
    "key": "{{1.event_id}}",
    "data": {
      "processed_at": "{{now}}",
      "source": "{{1.source}}"
    }
  }
}

Where it breaks: concurrency and size limits

Data Stores have no transactional guarantees. Two scenario executions running concurrently can both read "record not found," both write, and you end up with a race condition that a real database's unique constraint or row lock would have prevented outright. If your scenario can run in parallel (multiple webhook deliveries, a scheduled trigger overlapping a slow previous run), a Data Store dedup check is a best-effort guard, not a hard guarantee. There are also hard row and record-size caps depending on your Make plan — it's not built to hold your whole customer table, and treating it as a data warehouse will hit those limits at an inconvenient time.

Don't model relationships in a Data Store

Once you're storing a record that references another record by ID and joining across two Data Stores inside a scenario's routing logic, you've outgrown the tool. That's a five-minute job in Postgres and a fragile multi-module mess in Make.

Data Stores vs. a real external database

For anything beyond a lookup table or a checkpoint, point Make's HTTP or database modules at a real database instead. A small Postgres instance (even a free-tier hosted one) gives you actual transactions, indexes, and a query language, and Make can read and write to it over its built-in database connectors or a thin REST API in front of it. The Data Store's advantage is zero setup; a real database's advantage is that it behaves correctly under concurrency, which matters the moment more than one scenario execution can touch the same row.

Export before you rely on it long-term

Data Stores don't have the backup and migration tooling a real database has. If a Data Store is holding anything you'd be upset to lose, script a periodic export (Make can do this to itself, ironically) to a location outside Make.

Wrapping up

Data Stores are the right tool for scenario-local memory: dedup keys, sync checkpoints, small lookup tables that don't change often. The moment you're modeling relationships, need transactional writes, or are storing anything above a few thousand rows, move it to a real database and have Make talk to that instead — it's less code inside the scenario, not more, once you stop fighting the Data Store's limits.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.