Skip to content

Concepts

Simulations

A simulation is a hosted, stateful copy of an API's behaviour: records in collections, a plan that changes them over time, and rules that bend individual responses.

Lifecycle

When you create a simulation, Slurry parses the spec, works out the data model, generates seed data and starts serving. A model is used for the analysis and seed data; everything after that is deterministic engine work.

StatusMeaning
queuedWaiting for a worker.
analysingReading the spec and building the data model.
seedingGenerating and storing records.
runningServing requests and running the behaviour plan.
pausedRequests return 503 and the schedule stops. Data is kept.
failedSet-up could not complete. The status detail says why.
suspendedStopped by abuse monitoring or an administrator, pending review.

Collections

The data model groups records into collections - tasks, projects, users - each with an id style, a schema, field hints for realistic values and, where the API has one, a status field with its states and allowed transitions. Operations in the spec are bound to collections as list, get, create, update, delete or action.

  • A POST to a create operation inserts a record; later lists and gets include it.
  • Nested paths such as /projects/{project_gid}/tasks are scoped to their parent.
  • References between collections point at records that exist, so joins in your code behave.
  • Operations that do not map to data return a schema-valid static response.

The behaviour plan

The behaviour plan is what makes a simulation live. It is a declarative list of rules; each rule runs every everySeconds (never faster than your plan allows) and applies its steps. It is written once, by a model, when the simulation is created, then executed by the engine with no model calls per tick. You can read and replace it at any time.

StepWhat it does
transitionMoves a fraction of matching records from one state to another, optionally weighted.
createCreates between min and max new records, with optional field overrides.
updateIncrements, decrements, touches or regenerates a field on a fraction of records.
deleteDeletes a fraction of records, optionally filtered.
PUT /v1/simulations/{id}/behaviour
{
  "rules": [
    {
      "id": "progress-tasks",
      "name": "Tasks move through the board",
      "everySeconds": 900,
      "enabled": true,
      "steps": [
        {
          "kind": "transition",
          "collection": "tasks",
          "field": "status",
          "from": ["todo", "in_progress"],
          "to": ["in_progress", "in_review", "done"],
          "weights": [0.5, 0.3, 0.2],
          "fraction": 0.1,
          "maxPerTick": 25,
          "event": "task.updated"
        },
        {
          "kind": "create",
          "collection": "tasks",
          "count": { "min": 0, "max": 3 },
          "event": "task.created"
        }
      ]
    }
  ]
}
Limits: up to 20 rules, 10 steps per rule and 200 changes per tick. The minimum interval is 60 seconds, raised to your plan's schedule floor (15 minutes on Starter, 5 on Team, 1 on Scale).

Fast-forward

POST /v1/simulations/{id}/fast-forward with { "hours": 168 } runs each enabled rule as many times as it would have fired in that window (capped at 200 ticks per rule), then persists the net changes and queues webhooks. The maximum is 720 hours - 30 days - per call. The response tells you how many records changed.

Reset

POST /v1/simulations/{id}/reset regenerates the world from the original seed. Generation is seeded deterministically from the simulation, so a reset puts back the same records every time. It runs in the background: the status goes to queued and back to running.

Pause and resume

Pause a simulation to stop both traffic and schedule without losing data: POST /v1/simulations/{id}/pause and /resume.