Quodsi Docs

Activity

An activity is a step in your process. Its capacity sets how much can happen at once, and its actions say what happens.

What it is

An activity is a process step: a shape on your diagram where entities wait and get worked on. It has a capacity, a queue on each side, and an ordered list of actions.

The question it helps answer

Where's the bottleneck, and what would relieve it? Activity results show how busy each step is and how long work queues in front of it, so you can see whether a step lacks capacity, is starved, or is blocked by the step after it.

How it behaves

  1. An entity arrives and joins the inbound queue, in arrival order unless Queue Ranking says otherwise.
  2. When the activity has a free unit of capacity, the entity takes it.
  3. The entity runs the actions in order, top to bottom. Processing time comes from these actions.
  4. Quodsi picks the outgoing connector. This happens after the actions, so routing can read any value they changed.
  5. The entity moves on when there's room at the next place. If there's no outgoing connector, it leaves the model.

If the next place is full, a finished entity stays put and keeps its capacity. That's blocking: the step looks busy, but it's waiting on the step after it. An outbound queue gives finished work somewhere to wait. By default, inbound and outbound queues are unlimited, so a line won't block until you set real buffer sizes.

A queue limit never turns work away. It holds back the step before it. Entities coming straight from a generator, or sent by a Split or Create action, keep waiting for a place even when the queue is full.

Breakdowns

With breakdowns on, each unit of capacity has its own cycle. It runs for a time drawn from MTBF (mean time between failures), fails, gets repaired for a time drawn from MTTR (mean time to repair), and the next cycle starts when the repair ends.

A failure takes a free unit if there is one. If every unit is busy, it interrupts one entity. That entity stays in the step, waits for the next unit to come free, then finishes its remaining time. Entities in the queue can't get ahead of it. On a step with several units, that can be before the repair ends, because any free unit will do.

An entity that has finished and is blocked is treated the same way. It can't leave until it has a unit back, even if room opens downstream in the meantime. Then it carries on waiting for the next place. Only a failure can take a unit from an entity: under Queue Ranking, a better-ranked arrival waits its turn.

Blocked time is the same wherever the entity waits. A finished entity waiting for room at the next step is blocked, whether it waits in the outbound queue or, with no room there, in its own slot. In the slot it still holds a unit, so the next entity can't start, but the wait counts as Blocked time, not as processing time or Utilization. And it counts only here: the next step doesn't count it as its own queue time too. Two parts through a 2-minute step in front of a 10-minute one with no inbound queue read 4 minutes blocked and 2 processing each, with an outbound queue of 1 or with none. A step that blocks a lot has a constraint after it: check the next step.

Reading breakdowns in your results

A repair isn't work, and a unit under repair isn't capacity on offer. So Utilization and Share of time active leave repairs out. Being worked on, average still counts an entity sitting in a broken machine, because it's still there.

Time in failure adds up the repair time of every unit, so on a step with several units it can pass the length of the run. Failures counts the breakdowns, and Interruptions counts how many times a breakdown took a unit from an entity. Failure time for an entity type is only the repair those entities actually sat through. A breakdown on an empty unit belongs to no entity, so entity types won't add up to the step's Time in failure.

For example, take one entity with 20 minutes of work, on a step with an MTBF of 10 minutes and an MTTR of 5, over 100 minutes. The step fails 6 times, for 30 minutes. Two of those failures interrupt the entity, so it's in the step for 30 minutes: 20 working and 10 sitting out repairs. Utilization is 20 of the 70 minutes on offer, or 0.29. Share of time active is 0.20. Time in failure is 30, and the entity's failure time is 10.

Two Failure behaviors to plan around. The simulation counts time to the next failure continuously, including while the activity is idle. And a repair needs no resource, so read results as if repairs need no staff.

Properties

Select an activity's shape to open its editor. The Basic, Actions, Financial, Routing and Levers tabs show in every complexity view. The Failure tab needs the Advanced view. Anything else that depends on a view says so below.

A view only changes what you can edit, never what runs. If an activity uses something your view hides, a line under the tabs names it, such as This uses failures, hidden in Basic, with a link to switch views.

Basic tab

PropertyWhat it does
NameNames the activity in reports and on the diagram. An empty name or one another activity uses shows an inline message, and validation flags it.
Capacity: Fixed capacityHow many entities it can process at once, for the whole run. Default 1, and validation requires at least 1.
Capacity: Follow a scheduleAdvanced view. Takes capacity from a work schedule instead. If the model has no schedule, Quodsi creates one with a Monday to Friday day shift at the current capacity, and opens it. If it has several, Quodsi links the first and tells you.
Work scheduleShows while following a schedule. Picks which one. A link to a deleted schedule shows as Missing schedule, and validation reports it as an error.
Edit scheduleOpens the linked schedule. Other resources and activities following it change too.
New scheduleCreates a schedule, links it and opens it.
Nominal capacity (for reporting)Shows while following a schedule. It doesn't change the run. It's what nominal utilization divides by, so use it to say what fully staffed means. Linking a schedule raises it to the schedule's highest capacity if it was lower.

If an activity follows a schedule and you're not in the Advanced view, the option shows disabled, and the schedule still applies.

The rest of this tab is in the collapsed Advanced section. The section itself shows in every view.

PropertyWhat it does
Inbound Queue CapacityHow many entities can wait to enter. 999999 means unlimited, which is the default. 0 means no queue.
Outbound Queue CapacityHow many finished entities can wait to leave. 999999 means unlimited, which is the default. 0 means no queue, so a finished entity holds its capacity until it can move.
Queue Ranking: Serve byAdvanced view. Serves waiting entities by a value they carry, rather than first come, first served. It lists entity states of type number. If there are none, Create a "priority" state makes one. Every entity starts that state at 0, so ranking only takes effect once entities carry different values. Choose (first come, first served) to turn ranking off.
Queue Ranking: OrderAdvanced view. Lowest value first (the default, where 1 is most urgent) or Highest value first. Available once Serve by is set. Ties keep arrival order.

Actions tab

Actions are how an activity does its work. An entity runs them in order, one at a time. The tab has two views of the same list: Recipe, written as plain sentences, and Classic, as cards. Recipe is the default. The toggle at the top switches between them, and your choice is remembered in this browser.

Your view decides which actions you can add. An action already in the model stays, even if your view can't add that kind.

Action (Classic)In RecipeLowest viewWhat it does
DelayWait a while, or Use a resourceBasicTakes time, with or without a resource. With a requirement, it gets the resource, waits Processing Time Duration, then gives it back.
Seize ResourceGrab a resourceIntermediateGets a resource and keeps holding it, so it can span several actions. The entity waits until the whole requirement is free.
Release ResourceLet a resource goIntermediateGives back a seized resource. Leave the requirement as (release all) to give back everything the entity holds.
Assign StateChange a valueIntermediateChanges state values. Takes no time.
Dispose EntityRemove from modelAdvancedRemoves the entity, even with connectors going out. It releases anything the entity holds, and any actions after this one don't run.
Split EntitySplit into copiesAdvancedReplaces the entity with Count new ones, and sends them to Destination Activity. The original is removed, so any actions after this one don't run.
Create EntitySpawn a new entityAdvancedMakes a new entity and sends it to Destination Activity. The original carries on.
Join EntitiesCombine severalAdvancedHolds entities with the same Match State value until Join Count have arrived, then combines them into one and sends it to Destination Activity. The originals are removed. Each Join gathers its own entities, so two Joins in one activity never share them, even on the same Match State.
LoopRepeat…AdvancedRuns its Steps, in order, Repeat Count times. Steps can be any action, including another Loop.

A model may also hold a Branch action, usually from an import. It keeps running, but you can't add one or edit its steps in the side panel.

Action properties

An entity waiting at a Join keeps its slot and anything it has seized until its batch completes. A failure while it waits doesn't change the batch. Entities still waiting when the run ends stay in this activity's contents. The new combined entity counts as a new entity, and the originals count as consumed, not completed.

The forms ask for a Join Count of at least 2 and a Repeat Count of at least 1. In a model written by hand or by an agent, a Join Count of 1 replaces each entity with a new one straight away, and a Repeat Count of 0 skips the Loop.

New entities from Split, Create and Join don't use connectors. They go straight to Destination Activity and join its queue. Each one copies Inherit States first, then applies State Modifications.

PropertyActionWhat it does
Action TypeEvery action (Classic)Changes the kind of action. Other settings reset to defaults, keeping the name and any condition. Changing a Loop that has steps asks first, because its steps are removed.
NameEvery action (Classic)Optional label, such as Triage. Step levers show it.
State ConditionEvery action (Only if… in Recipe)Intermediate view. Runs the action only if a test passes. If not, the entity skips it. Add state condition starts one: a State, a Comparison and a Value. Clear condition removes it. The test reads an entity state or a model state. See State.
RequirementDelayThe resource requirement to use. (none — just a delay) means no resource. + New requirement… creates one, and the pencil edits the one selected.
PriorityDelay, Seize ResourceAdvanced view. Shows once a requirement is chosen. 0 to 900, default 0. Higher wins when a resource is contested. Ties go to whoever has waited longest.
Keep resource after delayDelayIntermediate view. Shows once a requirement is chosen. Holds the resource after the delay rather than giving it back. Default off.
Processing Time DurationDelayHow long it takes. A distribution and a Time Unit, drawn fresh on every visit. New actions use a constant 1 minute. In Recipe, type a value and unit, or use vary… to pick a distribution. See Randomness and replications.
Delay DurationOlder DelaySome older models hold a Delay with only this field. It's the same as a Delay with no requirement.
State ModificationsDelayIntermediate view. Changes states once the resource is held, before the time passes. Add modification opens a form with a State, an Operation and a value. See State.
State ModificationsAssign StateThe changes to make, in order, with Add modification. In Recipe, use + change.
State ModificationsSplit, Create, JoinChanges to make on the new entity.
Resource RequirementSeize ResourceWhat to seize. Required: the model can't run until you pick one.
Resource RequirementRelease ResourceWhat to give back. (release all), the default, gives back everything. Otherwise pick the same requirement you seized.
Destination ActivitySplit, Create, JoinWhere new entities go. Required. It can't be this activity, so this activity isn't listed.
CountSplitHow many new entities. Whole number, default 1, minimum 1.
Entity TemplateSplitThe type for new entities. Use original's template is the default.
Entity TemplateCreateThe type for the new entity. Required.
Inherit StatesSplit, Create, JoinTick the states to copy to the new entity. On Join they come from the first entity joined.
Split Index StateSplitOptional number state that gets each new entity's index: 0, 1, 2 and so on.
Match StateJoinThe state to group by, such as an order number. Required. Use an entity state.
Join CountJoinHow many entities to wait for. Whole number, default 2, minimum 2.
Combined TemplateJoinThe combined entity's type. Use first entity's template is the default.
Join Count StateJoinOptional number state that gets the count joined.
Repeat CountLoopHow many times to repeat. Whole number, default 1, minimum 1.
StepsLoopThe actions to repeat. In Classic, use + Add step to loop. Conditions on the Steps are tested on every pass.

Dispose Entity has no settings of its own.

Recipe keeps the sentence short. On Split, Create and Join, the optional settings are under More options: the new type, the index or count state, the states to copy, and Then set for State Modifications.

Some settings are only in Classic: Name, Keep resource after delay, editing Priority, and State Modifications on a Delay. Recipe shows a Priority above 0 in the sentence. A random draw or an expression in Change a value also shows in Recipe but opens through edit in Classic. That link and Edit in Classic show Classic for this activity only, without changing your choice of view.

Financial tab

The hourly rates are per hour whatever time unit your model uses, and each charges per unit of capacity. None of the costs can be negative. See Costing.

A unit is held from when an entity arrives in it until the entity leaves it, including time the entity spends waiting for a resource, waiting in a Join, blocked by the next step, or waiting out a repair. Only the time a Delay is running on it is billed at the working rate; the rest of a held unit's time is billed at the idle rate.

PropertyWhat it does
Enable financial trackingDefault off. While it's off the costs below are kept but hidden, and this activity costs nothing.
Fixed CostCharged once at the start of each replication, per unit of capacity. An activity following a schedule pays for the schedule's highest capacity. A warm-up doesn't remove it. Default 0.
Cost Per Entity ProcessedCharged each time an entity starts at this activity, so an entity still here when the run ends is counted. Default 0.
Cost / Hour ActiveCharged for each unit of capacity while a Delay is running on it. Two working units for an hour cost twice this. Default 0.
Cost / Hour IdleCharged for each unit of capacity on shift with no Delay running on it. That includes a unit held by an entity waiting for a resource, for a Join match, to leave, or for a repair, and a unit under repair with nothing in it. An off-shift unit isn't idle, so it costs nothing. Default 0.

A model saved earlier may show one more setting here, disabled and marked Not available yet. It has no effect on the run.

Failure tab

This tab needs the Advanced view. Below that, the tab is hidden and any breakdowns you've set still run.

PropertyWhat it does
Enable breakdowns (MTBF/MTTR)Turns on random failures. Default off. While it's off the durations below are kept but hidden.
MTBF DurationHow long each unit runs from the end of one repair to its next failure, idle time included. A distribution and a Time Unit. Starts at a constant 60 minutes when you enable breakdowns. It can't be one that only ever gives zero: the unit would fail the moment it's repaired and never work, so validation refuses it.
MTTR DurationHow long a repair takes. A distribution and a Time Unit. Starts at a constant 5 minutes. Zero is allowed: the unit is back at once.

A model saved earlier may show other settings here, disabled and marked Not available yet. They have no effect on the run.

Routing tab

This tab sets how entities choose between the activity's outgoing connectors. The tab shows one card per connector under Outgoing Connectors, named with its destination and its current share, rank or rule. Open a card to reach its move time. Connector explains each rule.

PropertyWhat it does
Connect TypeThe routing rule. Default Probability, the only choice in the Basic view. State Condition, Entity Template and First Available arrive at Intermediate. A rule already set stays, shown disabled, in a lower view. Disabled with one or no outgoing connector, because there's nothing to choose.
WeightProbability only. Relative share, with the resulting percentage beside it. Default 1.
State ConditionState Condition only. The test for this connector.
Entity TemplateEntity Template only. The entity type this connector carries.
PriorityFirst Available only. Order of preference, lower goes first. Default 1.
Move timeInside an open card. Travel time along the connector.

Levers tab

Tick a setting to mark it as a lever, then give it a Label, a Sweep and a min, max and step. Settings are grouped under Capacity, Reliability and Cost.

PropertyWhat it does
CapacityMarks capacity to vary. Hidden while the activity follows a schedule, because the schedule sets capacity.
Inbound queue capacity, Outbound queue capacityThe same, for each buffer size.
Step N — Processing timeOne row for each Delay in the list, with the action's Name if it has one. Steps inside a Loop aren't listed.
Step N — PriorityAdvanced view. One row for each Delay and Seize Resource in the list. It only matters on a step that uses a resource.
MTBF duration, MTTR durationThese show once breakdowns are on.
Fixed cost, Cost per entity processed, Cost / hour active, Cost / hour idleThese show once financial tracking is on.

A lever you've already saved keeps its row, greyed with the reason, if its setting stops applying.

Example

An exam needs a nurse throughout and a doctor for part of it. Use Seize Resource for the nurse, then a Delay of 5 minutes for the intake. Add a Delay with a Doctor requirement for the exam itself, which gets and gives back the doctor. Finish with Release Resource for the nurse. The nurse is held across all of it, as in real life.

Common mistakes

Related pages