Lead Routing

Round-robin lead routing belongs in the CRM, not a background poller

Event-driven CRM routing uses current lead data, per-group round-robin state, and manual escalation to avoid polling failures and load spikes.

Octacer July 24, 2026
A dark editorial scene where incoming leads fan into team-and-location buckets and a rotating cursor assigns them evenly inside a single system, one bucket lit green, no readable text.

The silent failure behind background lead routing

Most sales teams route leads through a poller: a scheduled job that runs every few minutes, pulls new or unassigned leads from the CRM, and assigns them to the next salesperson in a rotating order.

It functions predictably until a poll cycle exposes a drift between the data and the routing decision. The job fails silently. A lead sits unassigned for an hour. Two reps receive the same lead because the previous poll timed out and retried. The rotation order resets unexpectedly and one rep gets three leads in a row while another gets none.

The technical cause is usually the same: the routing decision is made from a snapshot of data that may already be stale, and the process that makes the decision is disconnected from the events that should trigger it.

This article explains why pollers fail, how event-driven routing removes the failure class entirely, and what to consider before you rebuild your routing logic.

Why background pollers break lead routing

A poller solves a scheduling problem: check for new work on an interval, then act. But lead routing is not fundamentally a scheduling problem. It is a state problem. Each lead has a status, each rep has a position in a rotation, and each assignment changes the state of both.

The mismatch between a polling model and a state problem produces several predictable failure modes.

Stale reads and duplicate assignments

A poller reads the CRM, finds unassigned leads, and assigns them. Between the read and the write, another process may have already assigned the same lead. This is a classic race condition. Pollers running concurrently — or a poll overlapping with a manual assignment by a rep — will occasionally assign the same lead twice.

Silent failures with no retry visibility

When a poll job fails — a timeout, an API rate limit, a schema change — the lead simply does not move. There is no event that says "this lead was supposed to be routed and was not." The failure is invisible until someone notices the lead is old.

Load spikes and CRM API abuse

A poller that checks every few minutes across a large lead volume generates constant API traffic. Under peak load — a campaign launch, a burst of inbound form submissions — the poller either runs too often to keep up or gets rate-limited by the CRM, which delays the very work it exists to accelerate.

Rotation state drift

Round-robin routing requires remembering whose turn it is next. Pollers often keep this state outside the CRM — in a database table, a cache key, or a file. Any reset, rollback, or partial failure of that external state breaks the rotation. Reps get skipped or doubled, and the logic that "fixes" the rotation usually makes it worse.

Duplicate assignment is not a rare edge case. It happens whenever two assignment paths touch the same record within the same window.

Silent failures with no retry visibility

This is the worst failure mode in lead routing: not the crash, but the quiet drift. Response time grows, the lead goes cold, and nobody is alerted because the system believes the job ran successfully.

Load spikes and CRM API abuse

The polling interval is a compromise: too short and you hammer the API; too long and leads sit unreasonably long. No interval is correct, because the actual demand is event-driven, not interval-driven.

Rotation state drift

The rotation state is not incidental to the routing decision. It is part of the data. Keeping it detached from the CRM invites drift.

The better approach: event-driven round-robin inside the CRM

The principle is simple: routing should be triggered by the event that creates the lead, not by a timer that periodically checks whether a lead exists.

When a lead is created — via a web form, an API call, a manual entry — the CRM fires an event. That event carries the lead's data. A routing process subscribes to the event, reads the current rotation state, assigns the lead to the correct rep, and updates the state. All within the same transaction boundary, using current data.

This removes the entire class of polling failures:

  • No stale reads. The routing decision uses the data at the moment of the event, not a snapshot from a previous poll.
  • No duplicate assignments. The assignment happens in a single, atomic operation within the CRM. There is no window where two processes can claim the same lead.
  • No load spikes. The system does work only when a lead exists. Zero idle traffic, zero interval compromise.
  • No external rotation state. The rotation position lives in the CRM alongside the data it governs, so it cannot drift from the records it is supposed to order.

How the routing logic is structured

The routing workflow can be modeled as a few distinct steps, each with a clear responsibility:

  1. Trigger. A lead is created or a lead's status changes to "unassigned."
  2. Read rotation state. The workflow reads the current position for the lead's group — by territory, product line, or any segmentation you use.
  3. Assign. The lead is assigned to the rep at the current position.
  4. Advance. The position increments, wrapping around to the first rep after the last.
  5. Escalate. If no rep is available in the group, the lead routes to a fallback queue or a manager for manual assignment.

The critical design choice is that steps 2 through 4 execute inside the CRM's transaction, using a locking mechanism to prevent concurrent assignments. This is what makes the routing deterministic rather than probabilistic.

A typical implementation in a CRM like Salesforce might use a Flow or an Apex trigger on the Lead object with a custom object to hold round-robin state per group:

trigger RouteLead on Lead (after insert) {
    for (Lead lead : Trigger.new) {
        if (lead.Status == 'Unassigned') {
            RoundRobinRouter.assign(lead);
        }
    }
}

The assign method reads the current position for the lead's group, assigns the lead, and updates the position — all in one transaction.

Per-group rotation, not global rotation

Most teams do not have one uniform queue. Leads arrive from different sources, target different products, and belong to different territories. A single global rotation would assign a French lead to a rep who only handles the US market.

The routing state should be keyed by group. Each group — territory, product line, lead source — maintains its own position counter. The same event-driven mechanism works; only the state key changes.

This is where pollers get particularly awkward. A global poller that routes by group must either query for each group's pending leads or maintain a complex filtering state. The event-driven model handles grouping naturally, because each lead's group is known at creation time.

What good looks like

When routing is event-driven and lives in the CRM, several operational signals improve:

  • Immediate assignment. A lead is routed at the moment of creation, not at the next poll cycle. Response time drops from "within minutes" to "immediately."
  • Zero duplicate assignments. Because the assignment is atomic within the CRM, the race condition disappears entirely.
  • No silent failures. If a routing workflow fails, the failure is visible in the CRM itself. The lead remains unassigned with an obvious error state, rather than quietly languishing.
  • Rotation accuracy. The position counter lives beside the leads it orders, so it cannot reset or drift independently of the data.
  • Predictable API load. The system makes no API calls when no leads exist. Traffic is proportional to actual demand.

Important caveats and tradeoffs

Event-driven routing is not universally superior. It has costs and constraints worth understanding.

CRM platform limits

The routing logic runs inside the CRM, which means it is constrained by the CRM's platform. Salesforce has governor limits on triggers — the number of records processed, the number of SOQL queries per transaction, the execution time. Large batch inserts of leads could hit these limits.

Mitigation: keep the routing logic minimal, avoid queries inside loops, and batch operations where possible. If you import thousands of leads at once, consider whether immediate routing is even desirable, or whether a small, controlled batch process is more appropriate for that specific path.

Not all CRMs support this cleanly

The event-driven approach assumes your CRM supports custom triggers, workflows, or event subscriptions. Most enterprise CRMs do. Some smaller or industry-specific CRMs do not. If your CRM lacks this capability, you cannot implement the pattern inside it, and a poller or an external integration may be the only option.

Complexity of edge cases

Event-driven routing shifts complexity from "timing" to "state." You now need to handle edge cases that the poller handled implicitly:

  • What happens when a new rep joins the group mid-cycle? The rotation should include them at the next natural position.
  • What happens when a rep leaves or goes on vacation? The group's available reps change, and the rotation must adapt.
  • What happens when a lead's group changes after assignment? Re-routing rules must be explicit.

These are solvable, but they require deliberate design. The poller's simplicity was partly an illusion — it just pushed these decisions elsewhere.

When this approach makes sense

Event-driven round-robin routing in the CRM is the right choice when:

  • Your CRM supports custom logic (triggers, flows, or equivalent).
  • Lead assignment needs to be immediate and accurate.
  • You are currently experiencing duplicate assignments, rotation drift, or delayed routing.
  • You have per-group routing requirements that a global poller handles poorly.

When to keep the poller

A poller remains a reasonable choice in narrower circumstances:

  • Your CRM does not support event-driven custom logic.
  • You import leads in large batches and prefer to route them in controlled waves rather than as each record arrives.
  • Your routing logic is extremely simple — a single global queue with no groups — and the failure modes above are acceptable.
  • You already have an external integration platform that handles routing, and it reliably retries with visibility.

Even then, the polling interval should be short enough to keep response time acceptable, and the job should have explicit failure alerting. A silent poller is worse than no poller.

A practical path forward

If you are currently running lead routing through a background poller, the first step is not to rewrite the routing logic. It is to map the current workflow and identify which failure modes actually occur in your system.

Worth answering these questions before changing anything:

  • Where does the rotation state live, and has it ever drifted from the records it orders?
  • Have duplicate assignments ever happened? How were they detected — by a rep, or by the system?
  • When a poll job fails, is anyone alerted, or does the lead simply wait?
  • How long is the current polling interval, and what is the actual response time for a lead?

Once you know which of these are real problems in your environment, the decision becomes clear. If the answer is "yes" to any of the first three questions — or the response time is unacceptable — the event-driven pattern inside the CRM is the structural fix. It removes the failure class rather than adding more retry logic on top of it.

If you would like a diagnostic review of your current lead routing workflow — including where the rotation state lives, how failures are detected, and which routing path is worth rebuilding — Octacer can help map the current system and identify the smallest credible change that eliminates the failure modes you are actually seeing.

Ready to Implement These Strategies?

Let's discuss how to apply these insights to your specific business challenges.

Schedule Consultation