What Is Closed-Loop Decisioning?
Closed-loop decisioning is a way of running automated decisions in which each decision's output is fed back as input to later decisions. In the fast loop, every verdict, score, hold, limit or action is written to the state the next decision reads, often seconds later. In the slow loop, observed outcomes such as chargebacks, defaults or conversions flow back into the rules and models. An open-loop system decides and moves on: nothing it decided changes what it reads next.
Updated
What is closed-loop decisioning?
The idea comes from control engineering. In Feedback Systems, Karl Johan Åström and Richard Murray write that "a system is said to be a closed loop system if the systems are interconnected in a cycle," and that if the interconnection is broken, "we refer to the configuration as an open loop system."
Business software borrowed the phrase for slower loops. HubSpot defines closed-loop marketing as "marketing that relies on data and insights from closed-loop reporting," in which sales teams report back what happened to the leads they received (HubSpot). In decision management, champion/challenger testing runs a candidate strategy beside the live one so teams can, in FICO's words, "continuously evolve your decision strategies to improve results in a closed-loop model." Those loops are slow, because the outcome arrives long after the decision.
Tacnode describes its own role as sitting inside the decision loop, which is the fast loop described here. A decision reads context from Tacnode, produces an output, and that output is written to Tacnode, where it becomes context for the next decision. Source data from the systems a team already runs arrives by change data capture or streams, and Tacnode gives each decision accurate, consistent context over it. Decision state written to Tacnode, such as verdicts, holds, per-agent limits and agent actions, is transactional, so two conflicting decisions on that state cannot both commit.
How closed-loop decisioning works
Take a card rule: decline when approved spend on the card in the last ten minutes, plus the new request, would exceed 500. Three requests arrive close together. The numbers are illustrative.
| Time | Request | Open loop: spend the rule reads | Closed loop: spend the rule reads |
|---|---|---|---|
| 0.0 s | 300 | 0, approve | 0, approve |
| 0.6 s | 150 | 0, approve | 300, approve |
| 1.1 s | 200 | 0, approve (total 650) | 450, decline |
In the open version, approvals go to a log shipped to an analytics store, and the spend feature is rebuilt every few minutes, so every decision in the burst reads zero. In the closed version, each approval is written to the store the rule reads:
BEGIN ISOLATION LEVEL SERIALIZABLE;
SELECT coalesce(sum(amount), 0) AS approved_10m
FROM auth_decisions
WHERE card_id = $1 AND verdict = 'approve'
AND decided_at > now() - interval '10 minutes';
-- the service decides, then writes its output back
INSERT INTO auth_decisions (card_id, amount, verdict, decided_at)
VALUES ($1, $2, 'approve', now());
COMMIT;Writing back is half the job. If two requests arrive at the same instant, both can read the same total before either inserts, and under PostgreSQL's default Read Committed level both would commit. The Serializable level "emulates serial transaction execution for all committed transactions," so PostgreSQL aborts one with a serialization failure and the service retries it against the new total. Under Read Committed, locking the card's row first (SELECT ... FOR UPDATE) serializes decisions per card instead: the second request waits for the lock, and because Read Committed starts each statement with a new snapshot, its sum then includes the first approval.
The slow loop then attaches outcomes: a chargeback arriving weeks later is joined to the decision record, which works only if the record kept what the decision read. That is the job of a decision ledger.
Why closed-loop decisioning matters in real-time systems
The slow loop is well understood: retrain on labels, tune the rules, compare strategies. The fast loop fails silently. Every decision service writes its output somewhere; what matters is how soon the next decision can see it. When outputs travel to a log and come back as a rebuilt feature minutes later, the loop is open for those minutes, and under a burst those are the minutes that matter most.
The useful measure is the time from one decision committing to the next being able to read it, and it should sit inside the decision's validity window. An open loop is the same failure as pipeline lag on source data, a context gap: the decision acts on context that no longer describes what is true. Why real-time decisions fail works through both cases.
FAQ
Related terms
Decision context is everything an automated decision reads and everything earlier decisions committed, as it stands at the moment the decision executes.
A decision ledger is an append-only record of automated decisions: what was decided, on what inputs, under which policy and authority, and what changed.
A fleet control loop observes running AI agents, derives fleet state, adjusts policy, budget or routing, and has agents act on the change while still running.
A validity window is the interval within which a decision's context remains an accurate basis for action — typically 10ms to 1s for automated decisions.
Decision coherence is the property that concurrent automated decisions act on the same version of shared state, instead of contradicting each other.
Multi-writer contention is two or more actors reading and writing the same mutable state in the same short window. It is not multi-tenancy or partitioning.
