Back to Blog

Engineering Hybrid Matchmaking: How Call of Duty's Queue Split Exposes Modern Game Matchmaking Architecture

Published on July 24, 2026
Engineering Hybrid Matchmaking: How Call of Duty's Queue Split Exposes Modern Game Matchmaking Architecture

In a nutshell

Architect scalable game matchmaking architecture using connection-based queues, dynamic SBMM expansion, and robust C# ticket processing algorithms.

When Activision announced that Call of Duty: Black Ops 7 would split its player base across three distinct matchmaking queues—Skill-Based Matchmaking (SBMM), Classic Connection-Based, and Hybrid—it brought a long-standing backend engineering debate directly into the spotlight. For competitive titles, deciding how to pair players isn't just a game design preference; it is a complex game matchmaking architecture problem that balances sub-millisecond network constraints, mathematical skill variance, pool fragmentation, and cloud compute costs.

Splitting your matchmaking system into multiple distinct queues sounds like a simple player-preference feature on the surface. In reality, it doubles or triples the engineering overhead on your backend infrastructure. When you divide a concurrent player base into separate queues, ticket density drops sharply, queue times explode exponentially in low-density regions, and server allocation algorithms face heightened churn.

In this article, we will analyze the technical trade-offs of SBMM versus connection-first matchmaking, dissect the mathematics behind dynamic hybrid queue expansion, inspect real backend C# code for ticket processing, and explore how to build resilient matchmaking pools that scale cleanly.


The Immutable Matchmaking Trilemma

Every modern game matchmaking architecture must solve a constraint optimization problem bound by three competing variables:

  1. Latency (RTT): The round-trip time between the player client and the allocated dedicated server instance (measured in milliseconds).
  2. Skill Delta ($\Delta$MMR): The mathematical gap in skill representation (MMR, Elo, or TrueSkill) between players in a given lobby.
  3. Queue Duration ($T_{queue}$): The total time a player spends waiting in a state of idle queue friction before a valid match ticket transitions into an active server allocation.
                    Latency (RTT)
                      /       \
                     /         \
                    /   Ideal   \
                   /    Match    \
                  /               \
Skill Delta (ΔMMR) --------------- Queue Duration (T_queue)

You can easily optimize for any two of these variables at the absolute expense of the third:

  • Low Latency + Low Skill Delta: Results in long queue times because the engine must search for rare, perfectly skilled players who also live near the exact same cloud datacenter.
  • Low Queue Time + Low Skill Delta: Results in high latency because the matchmaker must expand its geographic search radius worldwide to find equal-skill opponents.
  • Low Queue Time + Low Latency: Results in high skill variance (the classic "connection-first" public match experience) because the matchmaker immediately grabs the nearest available clients regardless of performance metrics.

When a title like Black Ops 7 introduces three separate queue modes, it forces the underlying matchmaking architecture to maintain three parallel rule evaluation loops over fragmented memory pools.

If your Concurrent Users (CCU) count in a specific region—say, South America at 4 AM—drops below 2,000 active players, dividing those players across three separate pools reduces the local density for each queue to just a few hundred players. As a result, connection-first queues fail to find low-ping dedicated servers, and SBMM queues stall indefinitely.


Deconstructing SBMM vs. Ping-First vs. Hybrid Queues

To build a backend capable of handling millions of match tickets, you must first understand how each architectural model operates under the hood.

1. Connection-Based (Ping-First) Architecture

In a connection-first engine, skill matrices are entirely secondary or discarded. The core objective is minimizing network degradation (jitter, packet loss, high RTT).

  • Client Ping Probing: Upon opening the queue, the game client emits ICMP or UDP ping beacons to a series of regional edge gateways (e.g., us-east-1, eu-central-1, ap-southeast-1).
  • Ping Vector Generation: The client constructs a vector of latencies: [ us-east: 24ms, us-west: 78ms, eu-central: 142ms ] and attaches it to the matchmaking payload.
  • Spatial Indexing: The matchmaker buckets players strictly into region hashes based on acceptable latency thresholds (e.g., $RTT < 50ms$).

Because network topology dictates match creation, player search buckets are predictable, allowing tickets to be resolved in $O(1)$ time using simple FIFO (First-In, First-Out) spatial queues.

2. Skill-Based Matchmaking (SBMM) Architecture

SBMM prioritizes match fairness by modeling player capability using multidimensional Gaussian distributions (e.g., TrueSkill 2) or customized Elo variants. Key inputs include win/loss ratios, kill/death ratios, damage per minute, and recent performance trajectory.

  • Distance Evaluation: The matchmaker calculates the Euclidean or Mahalanobis distance between candidate player vectors in $N$-dimensional skill space.
  • Sorting Cost: Matchmakers cannot rely on simple FIFO queues. They must maintain sorted sets or spatial trees (like KD-trees) of ticket profiles to quickly find candidates within an acceptable skill variance $\sigma$.
  • Search Space Contraction: As skill increases (e.g., top 0.5% of players), the pool of eligible candidates shrinks drastically. This forces the system to either hold tickets indefinitely or slowly decay its skill strictness parameters.

3. Dynamic Hybrid Architecture

Rather than forcing players into hard-coded queue choices, modern production backends frequently implement a Dynamic Hybrid model. In this setup, every match ticket begins with strict SBMM and low latency bounds. As $T_{queue}$ increases, a rule decay function continuously expands the acceptable skill delta ($\Delta MMR$) and latency limit ($RTT_{max}$)...

$$\Delta MMR_{allowed}(t) = \Delta MMR_{base} + \alpha \cdot t^{\gamma}$$

$$RTT_{allowed}(t) = \min\left(RTT_{max_cap}, RTT_{base} + \beta \cdot \lfloor t / \Delta t_{step} \rfloor\right)$$

Where $\alpha$ and $\beta$ are expansion coefficients, $\gamma$ controls exponential curve steepness, and $t$ is elapsed queue duration in seconds.

By leveraging dynamic relaxation, you prevent infinite queue hangs while maintaining high match quality during peak CCU periods.


Code Implementation: Dynamic Rule Expansion Engine

Below is a battle-tested C# implementation of a dynamic matchmaking rule expansion engine. This service evaluates incoming tickets against active queue pools, calculating real-time ping compatibility matrices and dynamic MMR variance caps.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Horizon.Matchmaking.Engine
{
    public class MatchmakingTicket
    {
        public string TicketId { get; set; } = Guid.NewGuid().ToString();
        public string PlayerId { get; set; }
        public double SkillRating { get; set; } // Elo/MMR representation
        public Dictionary<string, int> RegionalPingMap { get; set; } = new(); // e.g., "us-east": 28
        public DateTime EnqueuedAtUtc { get; set; }
    }

    public class DynamicMatchRules
    {
        public double MaxAllowedMmrDelta { get; set; }
        public int MaxAllowedPingMs { get; set; }
    }

    public class MatchmakingEvaluator
    {
        private const double BaseMmrDelta = 50.0;
        private const double MaxMmrCap = 600.0;
        private const int BasePingMs = 35;
        private const int AbsoluteMaxPingMs = 180;
        private const double PingStepIntervalSeconds = 4.0;

        /// <summary>
        /// Calculates the expanded criteria for a ticket based on elapsed queue time.
        /// </summary>
        public DynamicMatchRules GetRelaxedRules(MatchmakingTicket ticket, DateTime currentUtc)
        {
            double elapsedTime = (currentUtc - ticket.EnqueuedAtUtc).TotalSeconds;

            // Exponential expansion for skill tolerance to ensure high-skill players eventually match
            double mmrExpansion = Math.Pow(elapsedTime, 1.35) * 4.5;
            double calculatedMmrDelta = Math.Min(MaxMmrCap, BaseMmrDelta + mmrExpansion);

            // Step-wise discrete expansion for latency tolerance (prevents constant server hopping)
            int pingSteps = (int)Math.Floor(elapsedTime / PingStepIntervalSeconds);
            int calculatedPingLimit = Math.Min(AbsoluteMaxPingMs, BasePingMs + (pingSteps * 15));

            return new DynamicMatchRules
            {
                MaxAllowedMmrDelta = calculatedMmrDelta,
                MaxAllowedPingMs = calculatedPingLimit
            };
        }

        /// <summary>
        /// Evaluates whether two tickets can be paired into a match session.
        /// </summary>
        public bool CanMatchTickets(MatchmakingTicket ticketA, MatchmakingTicket ticketB, DateTime currentUtc, out string selectedRegion)
        {
            selectedRegion = null;

            DynamicMatchRules rulesA = GetRelaxedRules(ticketA, currentUtc);
            DynamicMatchRules rulesB = GetRelaxedRules(ticketB, currentUtc);

            // 1. Evaluate Skill Delta
            double actualMmrDelta = Math.Abs(ticketA.SkillRating - ticketB.SkillRating);
            if (actualMmrDelta > rulesA.MaxAllowedMmrDelta || actualMmrDelta > rulesB.MaxAllowedMmrDelta)
            {
                return false; // Skill variance too wide for current queue age
            }

            // 2. Evaluate Common Datacenter Ping Compatibility
            int lowestCombinedPing = int.MaxValue;

            foreach (var (region, pingA) in ticketA.RegionalPingMap)
            {
                if (ticketB.RegionalPingMap.TryGetValue(region, out int pingB))
                {
                    // Match must satisfy BOTH players' dynamic ping limits
                    if (pingA <= rulesA.MaxAllowedPingMs && pingB <= rulesB.MaxAllowedPingMs)
                    {
                        int combinedPing = pingA + pingB;
                        if (combinedPing < lowestCombinedPing)
                        {
                            lowestCombinedPing = combinedPing;
                            selectedRegion = region;
                        }
                    }
                }
            }

            return selectedRegion != null;
        }
    }
}

Key Technical Aspects of This Implementation:

  • Asymmetric Rule Satisfaction: The method checks that both players' expanding constraints are respected (pingA <= rulesA.MaxAllowedPingMs && pingB <= rulesB.MaxAllowedPingMs). A new player in queue for 2 seconds won't be dragged into a 150ms ping server just because the other player has been waiting for 90 seconds.
  • Discrete Ping Stepping: Latency bounds expand using discrete time steps (PingStepIntervalSeconds) rather than continuous curves. This avoids unnecessary edge router reassignment on every tick loop.
  • Spatial Intersection: Pairing relies on dictionary key intersections across regional maps, selecting the datacenter with the lowest cumulative round-trip latency.

Backend Infrastructure Challenges: Concurrency, Lock Contention, and Dedicated Server Provisioning

Writing match algorithms in isolation is straightfoward. The real engineering difficulty emerges when you run this system across distributed node clusters handling hundreds of thousands of concurrent tickets.

[Player Clients]
       │ (WebSockets / Low Latency)
       ▼
[Ingress Load Balancers]
       │
       ▼
[Distributed Ticket Pool (e.g., Redis Cluster / Memory Grid)]
       │
  ┌────┴────────────────────────┬────────────────────────┐
  ▼                             ▼                        ▼
[Worker Node 1]           [Worker Node 2]          [Worker Node 3]
  │                             │                        │
  └────┬────────────────────────┴────────────────────────┘
       │ (Atomic Claim / Lua Mutex Lock)
       ▼
[Server Orchestration API] ──► Spin up Agones / Fleet Instances

1. Distributed Ticket Lock Contention

When multiple parallel matchmaker processes scan the same central ticket pool, race conditions inevitably occur. Two separate worker threads might simultaneously evaluate Ticket #1042 and attempt to pair it into two completely different lobbies.

To solve this, developers must execute atomic lock claims using distributed primitives (such as Redis Lua scripts or memory grid atomic operations) prior to emitting a match assignment. If a ticket is locked by another match worker, the thread immediately releases its state and backtracks.

2. High-Frequency Real-Time Communication

Matchmaking status updates cannot rely on standard HTTP polling without burning massive compute resources on useless connection handshakes. To keep clients informed of queue duration estimates and dynamic ping searches, backends must maintain persistent, dual-channel WebSockets or long-lived gRPC streams.

If you are currently relying on inefficient polling loops for your multiplayer state, check out our guide on how to ditch HTTP polling for Unreal Engine WebSockets in real-time backends.

3. Server Allocation Handshakes & Fleet Provisioning

Matching players is only half the battle. Once a valid ticket group is formed:

  1. The matchmaker contacts a dedicated server orchestrator (e.g., Agones, custom Kubernetes controllers).
  2. A clean game server instance must be claimed or allocated in the selected datacenter within a strict deadline (typically $< 1500ms$).
  3. The server spins up, binds its listening UDP port, and returns its IP/Port address payload.
  4. The matchmaker dispatches the connection details to all client WebSockets.

Building distributed ticket pools, handling lock contention, managing region-based socket clusters, and orchestrating dedicated server lifecycles manually requires months of infrastructure work.

This is where horizOn eliminates severe engineering overhead. Rather than assembling Redis ticket stores, writing custom Agones cluster wrappers, and managing server fleet scaling scripts, horizOn provides fully managed, ultra-low-latency matchmaking queues and server fleet orchestration out of the box. You write your matchmaking rule sets; horizOn handles global distribution, atomic ticket locking, and automatic server allocation seamlessly.


5 Best Practices for Building Modern Game Matchmaking Architecture

Whether you are constructing a high-stakes competitive shooter or an indie casual arcade title, follow these battle-tested architectural principles:

1. Mandate Client Ping Vectors Before Ticket Submission

Never rely on client IP Geo-IP lookups to determine proximity to your datacenters. Geo-IP databases are notoriously inaccurate for edge routing and ignore real-time ISP congestion. Always force the client engine to measure direct latency via UDP ping probes to all regional endpoints before calling the enqueue endpoint.

2. Guard Against Pool Fragmentation

Avoid creating separate queues for minor game modes unless your active player base cleanly justifies it. Splitting your player base across game modes, map preferences, and matchmaking strictness queues compounds pool degradation. If your active CCU per queue falls below 1,000 players in a region, switch automatically to dynamic single-queue fallback modes.

3. Decouple Server Provisioning from Match Evaluation

Ensure your matchmaker threads operate asynchronously from your fleet orchestration layer. Never hold an active matchmaker worker loop open while waiting for a virtual server instance to boot. Utilize non-blocking pub/sub message queues to request server allocations and deliver connection payloads when instances report healthy status.

4. Optimize Idle Server Costs with Smart Hibernation

Matchmaking surges unpredictably during peak player hours and drops sharply off-peak. Leaving hundreds of game server instances idling empty wastes significant operational revenue. Implement dynamic fleet warm-up and server hibernation patterns. For a deep technical analysis on optimizing idle server usage, read our post on architecting zero-waste servers and Fortnite server optimization proposals.

5. Benchmark Netcode and Replication Under High Latency

Even the most advanced matchmaking architecture will occasionally pair players across moderate latency gaps ($100-120ms$) during off-peak hours. Ensure your server netcode utilizes rigid client prediction, lag compensation, and state reconciliation to survive packet delay gracefully. If client positions tear or jump during high-ping matches, consult our guide on how to fix player location desync in Unreal Engine multiplayer.


Summary & Next Steps

Activision's decision to offer explicit SBMM, Connection-First, and Hybrid queues in Call of Duty: Black Ops 7 illustrates how critical matchmaking architecture is to player satisfaction. However, splitting queues requires immense player density, low-latency socket networking, dynamic rule decay algorithms, and atomic ticket handling.

If you are building your next multiplayer game, don't waste months writing backend infrastructure, socket servers, and fleet allocation logic from scratch. Learn how horizOn empowers developers to deploy scalable multiplayer game backends, automated matchmaking, and server orchestration in minutes. Try horizOn for free today or explore the horizOn documentation to accelerate your backend workflow.


Source: Call of Duty: Black Ops 7 will very soon offer three different matchmaking systems, and you'd be right to be confused