This article discusses the Matching Rule activity, which automates the grouping of print jobs that belong to the same shipment. It explains how this activity assigns human-readable container numbers to groups of items, ensuring efficient packing and shipping. The article also covers core concepts, configuration options, use cases, and the overall workflow integration.
The problem it solves
When multiple print jobs for the same shipment are processed on different machines or at different times, it becomes necessary for someone in the packing department to physically regroup these items before shipping. The Matching Rule activity automates this process by assigning a human-readable container number (e.g., box-7) to each group of items that are meant to be shipped together. Operators can easily identify the number on each finished job and place it into the corresponding physical bin. Once the bin is full, it is ready for shipment.
In summary:
Matching = "assign the same numbered bin to every group of items that ship together, allowing the packer to easily identify what goes with what."
This activity is a reimplementation of the old GN Matching Box service, designed to work with any partner product. Instead of relying on hard-coded product taxonomies, users can configure how to group, sort, and assign numbers through rule configuration.
Core concepts
Concept | What it means |
Matching number | The integer assigned to a group (e.g., |
Matching group name | The prefix attached to the number — |
Matching criteria (group keys) | The attributes that determine which items belong together. Items with identical values for every group key share one number. |
Sorting criteria (sort keys) | The order in which groups are considered. Order matters because lower sort position results in a lower matching number. |
Customer range | The |
Reset window / reset times | When previously used numbers become available for reuse. |
The pool | The facility-wide set of items still waiting for a number in this group. Matching always considers the entire pool, not just the items in the current context. |
Where the configuration lives
A Matching Rule is defined centrally on the Matching Rules page and then selected within a workflow's Matching Rule activity, similar to Batching Rules. Some fields can be overridden per workflow on the activity itself:
Field | Source of truth | Activity can override? |
Reset times | Rule | No (read-only display) |
Item limit | Rule | No (read-only display) |
Matching strategy ( | Rule | No (read-only display; intrinsic to the rule) |
Matching group name | Rule | Yes |
Customer range (start/end) | Rule | Yes |
Group keys / sort keys | Activity parameters | n/a (defined on the activity) |
Quantity attribute / threshold | Activity only | Yes (not stored on the rule) |
What the activity produces
For every order item, the activity generates a result that can be referenced downstream via {{flow:matching-rule:<idx>.matchingNumber}} and related fields:
Output field | Meaning |
| The assigned number (e.g., |
| The prefix (e.g., |
| The date (YYYY-MM-DD, facility-local) when the number was assigned. |
| A human-readable summary of the contents of the box (e.g., |
| The number of items sharing this number — i.e., the group size. |
| This item's 1-based position within its group, in sort order. |
Items are also re-sorted in the resumed workflow so that higher matching numbers come first, and unassigned (0) items are sorted to the end.
Configuration options (the activity UI)
The activity presents these groups, top to bottom:
Matching Rule — select which rule this activity uses. Required.
Matching rule parameters (read-only) — displays the rule's reset times, items-per-number limit, and strategy for reference.
Matching Group — the name/prefix.
boxresults inbox-1,box-2;palletresults inpallet-1. Overrides the rule default when set.Matching Criteria — the group-by table. Each row is an attribute path (e.g.,
{{order.tenantCustomerUid}}) plus an optional alias.Sorting Criteria — the sort table. Each row is an attribute path plus ascending/descending order.
Conditional Matching Settings — only visible when the rule's strategy is
conditional. Quantity attribute + threshold for the single-item guard.Customer Range — start (default 1) and end (empty/0 = no upper bound).
Use cases covered
Basic grouping
Define one or more group keys. Every item whose group-key values match exactly receives the same matching number.
Example: Group by
{{order.tenantCustomerUid}}and{{order.orderId}}— every item of the same customer's order lands in one box.Items that resolve to an empty/missing group key are dropped (no number) and left in the pool for future consideration.
If you define no group keys, all items effectively fall into one bucket (subject to the unkeyed pool semantics).
Cross-machine / cross-time matching
Each time the activity runs, it does not only consider the items in the current context; it loads the entire facility pool for this (group name, group keys) combination.
What makes an item part of the pool: To be included in an allocation cycle, a candidate must:
Belong to this facility, and
Not yet have a number for this
(group name, group keys)identity, andHave an active execution status —
in_progressorbatched.
Items whose execution has completed or failed are not in the pool. This ensures that an item printed on one machine can still receive the same box number as its sibling printed on another machine, as long as both are still active.
Multiple allocation cycles
A matching cycle is a snapshot in time. Each time the activity runs, it considers only the items active in the pool at that moment, and sorting is applied only across that snapshot.
If matching runs several times throughout the day, then:
Items already numbered in an earlier pass retain their number (they're excluded from the pool).
Each new pass sorts and numbers only the items that are currently active and currently unmatched.
This means sorting is local to each pass. An item that arrives in a later pass is sorted only against that pass's pool.
Consequence: If all items of a day must be sorted together, run matching exactly once per day.
Sorting
Number assignment walks the pool in sort order, awarding the next free number to each new group as it is encountered. Sorting controls priority: the group that sorts first receives the lowest number.
Numeric attributes sort numerically (not lexicographically).
Ascending vs. descending is per sort column.
Ties fall back to creation time, then a stable ID, ensuring deterministic output.
Within a group, sort order also drives
matchingItemIndex.
Customer range
The Customer Range[start, end] constrains the integers used:
startdefaults to1.end = 0(or empty) means no upper bound; numbers grow indefinitely.When
end > 0and all numbers in the range are in use, further groups collapse ontoenduntil the reset window frees slots.
Reset window
Numbers are not reused indefinitely; they become available at reset times (weekday + time-of-day windows defined on the rule). The activity only counts numbers assigned since the most recent reset boundary.
No reset times configured defaults to the most recent midnight (facility-local).
Timezone is the facility's timezone, ensuring correct day rollover.
Item limit
Set Items per matching number (ItemLimit) on the rule to cap bucket size.
A group larger than the limit is split across consecutive numbers in sort order.
ItemLimit = 0means no limit (default).ItemLimit = 1results in a unique number per item.Overflow buckets consume real slots in the shared number space.
Item limit is independent of strategy.
Standard vs. Conditional strategy
Mirroring Batching's Standard/Conditional split:
Standard (default): every group with matching keys gets a number, regardless of size.
Conditional: enables the single-item quantity guard.
Reprints
When an item is reprinted, it must return to the same box it was originally assigned. The activity retrieves any prior matching assignment for the item's (orderId, orderItemId) and stamps the original number, date, contents, total, and index onto the reprint without reallocating.
Reprocessing
If matching runs again for an item that already has a number for this group, the same prior-assignment merge applies: the original output is re-stamped verbatim. Re-running never changes an already-assigned number.
Idempotency & determinism
It is important to clarify the stability guarantees of the activity:
Guaranteed identical: already-numbered items are re-stamped verbatim.
Guaranteed deterministic: a single allocation pass always produces the same result for the same input.
Guaranteed one number per group: every item sharing a matching-key tuple in the same pass inherits one number.
Not guaranteed: the same group keys do not always map to the same number across different passes.
Rule of thumb: an item keeps its number forever once assigned; a set of keys does not reserve a number for future items.
Dry run
In dry-run mode, the activity does not interact with the pool, allocator, or database. It simply assigns matchingNumber = 1 to every item in the signal and resumes. Item limit and the quantity guard do not run in dry-run mode.
Items that can't be matched
Several scenarios can leave an item without a number, and they all behave the same: the item flows through the workflow with matchingNumber = 0, while matchingGroupName remains set:
Group keys are empty or unresolvable.
The item was dropped by the conditional quantity guard.
The item simply wasn't part of the allocated set.
Failure handling
If matching fails internally, the activity does not leave the upstream order_processing_workflow hanging. It marks the affected print jobs as failed and completes the executions through the normal failure path.
How it all fits together
For each (facility, matching group name), there is a single matching workflow. Each run of the activity sends it a signal. Because the workflow is a singleton keyed on the deterministic ID, concurrent runs for the same pool are serialized automatically.
Matching Rule activity │ (reads rule + activity params → MatchingConfig) ▼ SignalWithStartMatching ItemsMatchingWorkflow (singleton per facility + group name) ├─ 1. Resolve group/sort keys for the signal's items (in memory) ├─ 2. Load the facility pool (unmatched + active items for this group) ├─ 3. Resolve keys for pool items from their stored payload ├─ 4. (conditional) drop lonely undersized items ├─ 5. Allocate numbers in sort order, splitting by item limit, │ bounded by the customer range, skipping in-use numbers ├─ 6. Persist one matching record per allocated item (one transaction) ├─ 7. Re-stamp original numbers for reprints / reprocessed items └─ 8. Resume the order processing workflow with the outputs stamped on
Quick reference
You want to… | Configure… |
Decide what belongs in the same box | Matching Criteria (group keys) |
Control which group gets the low numbers | Sorting Criteria |
Name the container (box/pallet/tray) | Matching Group name |
Bound the numbers to a range | Customer Range start/end |
Reuse numbers on a schedule | Reset times (rule) |
Cap items per box and split oversized groups | Items per matching number (rule) |
Skip boxing lonely small items | Strategy = Conditional + Quantity attribute + Quantity threshold |
Keep reprints in their original box | Automatic — no config needed |
