Tinderbox 8 Icon

Optimising code for performance

In small TBX files there is rarely a need to consider code optimisation, but as your files grow in note count and complexity and acquire more agents you may see the time-to update increase - i.e. how quickly code changes are effected. In such circumstances, or just as best practice, it is worth reviewing and applying a few optimisation techniques.

General practices

These do not directly affect code execution (other than by bad syntax) but help make everything else easier.


Using prototypes to set up and/or locate discrete sets of note(s) is a big productivity gain. Editing code (or code notes) once can then affect many notes. Consider using $RuleDisabled and $DisplayExpressionDisabled in the prototype so as to suppress execution of such code in the prototype. If applying prototypes as part of incremental formalisation, do not forget to reset the inheritance of any prototype-using note's attributes that may have previously had a local value set.

Check your syntax

Make sure your code does not include deprecated syntax. At some point in the future the code may not work at all and in the meantime you're making Tinderbox guess your real intent.


These techniques can help with tuning performance once the size and complexity of your TBX grows.

Narrow the scope of agent search

Review and rewrite queries so each successive query terms tests fewer items. The fewer tests, in aggregate that Tinderbox has to make the faster the results. This is especially true if the (final) tests is based on a complex regular expression such as in .contains(). If the desired matching group of notes is not easily defined in narrow scope, consider giving them all the same prototype.

Querying existing agents

Rather than have numerous agent all querying the same overall scope, consider making one agent to to that first selection and then have other agents query that agent's results using different queries. So rather than have 5 agents querying descendedFrom("X"), make a single agent, e.g. 'agent A', do the latter and the the other use inside("agent A") as their first query term. Do note though that this means it may take several agent cycles for a change to cycle through.

Agent Priority ($AgentPriority)

Not every agent needs to run every cycle. The agent's priority can be set via the agent's Action Inspector's Query sub-tab or directly in code via $AgentPriority. Also consider an agent to find all agents allowing you to easily adjust their $AgentPriority via its action. Or make a stamp to toggle $AgentPriority on/off.

Caching expression results in a user attribute

Expressions like display and hover expressions are, in v5, slower to run than rules or agent actions. As a result, if such expressions are complex, it is better to use a rule or agent action to run the code and store the expression's result in a user attribute and have the display/hover expression use the value of the latter. Adding an extra attribute has negligible impact on the TBX.

Use $Searchable to exclude notes

The $Searchable attribute provides an ad hoc way to exclude some notes from all searches.

Action removes note from query scope

Consider making the action outcome make changes such that the altered note no longer meets the query. This is a good method for making an agent effectively act once only on a note. If it is not possible to alter an attribute value being matched, e.g. it is $Text that must not be changed, consider either moving the note (via $Container), making a user Boolean as a 'guard' field for the action to set (e.g. an $IsCorrected), or adding extra query terms so that the extra item can safely be saved via the action to affect later matches.

A Tinderbox Reference File : Actions & Rules : Optimising code for performance