Copilot Fusion Is GA: You Choose Effort Now, Not a Model

·11 min read·Evergreen Tools Team

GitHub made Copilot Fusion generally available on October 28, 2026, at Universe, and the changelog is unusually blunt about what changed: you no longer pick a model, you pick how hard the system should try. Fusion folds two earlier systems into one — the multi-model orchestration from Project HydraFusion and the fine-tuned router behind Copilot auto model selection. The feature list is the boring part. The interesting part is a paragraph in the middle: on the Artificial Analysis Coding Agent Index, Fusion Max scored 60, within two points of Claude Code with Opus 5.5 Max, at roughly half the average API cost per task, about half the tokens, and around 40% less time. That is a routing win, and routing is something you can measure and copy.

Routing and cost charts for coding agents on screen

The routing win is not a stronger model. It is fewer dollars, fewer tokens and less waiting for the same task.

1. What actually shipped on October 28

When you select Copilot Fusion in the model picker you are not selecting a model. You are selecting a runtime router and orchestrator. You do not switch models mid-task and you do not decide which model suits each step; for every prompt, Fusion picks the execution pattern, the reasoning effort, and the models that run it. You can see which model is running, but only the final answer ships. The shift is that the manual loop people used to run by hand — ask the cheap model, escalate if the result looks thin — now lives inside the product.

2. Three effort levels, and the one that is hard to price

Fusion Standard balances cost, quality and latency, and it is where everyday work lands; per the docs it selects one model per task. Fusion High is for substantial but well-scoped work — a nasty bug, a behaviour change across several files — where extra model calls might earn their time and credits. Fusion Max puts the most capable models first for deep reasoning while still considering token efficiency. There is a fourth level, Fusion Fast, which users cannot select; it only appears in VS Code inline chat. The genuinely hard decision is High: whether it pays depends entirely on whether one correct pass or one rework costs you more.

# Routing decisions are only auditable if you log which model ran each step.
# Copilot's usage export gives per-request token counts; join them to the
# effort level your team actually selected.
import csv, collections

by_tier = collections.defaultdict(lambda: {"tasks": 0, "tokens": 0, "resolved": 0})

for row in csv.DictReader(open("copilot_usage.csv")):
    tier = row["effort_level"].lower()
    b = by_tier[tier]
    b["tasks"] += 1
    b["tokens"] += int(row["total_tokens"])
    b["resolved"] += 1 if row["task_outcome"] == "resolved" else 0

for tier, b in sorted(by_tier.items()):
    t = b["tasks"] or 1
    print(f"{tier:<18} tasks={t:<5} tok/task={b['tokens']//t:<7} resolved={b['resolved']/t:.0%}")

# The row you are looking for is the one where tok/task doubles and the
# resolved rate does not move.

3. Three execution patterns: single, cascade, critique

Single means one model does the task. Cascade means an efficient model drafts and a judge decides whether to accept the draft or escalate to something stronger. Critique means one model drafts, several models critique it independently in parallel, the feedback is aggregated, and the drafting model revises. The pattern is chosen per prompt, so the first prompt in a session can be Single and the follow-up can be Critique. The docs say choosing a pattern is a lightweight step, and that Fusion only adds model calls when a task warrants them. Translation: review is a decision, not a default.

# Cascade is not magic: a cheap draft, a judge, and a rule for escalation.
# You can build the same loop around any provider, with your own acceptance bar.
from dataclasses import dataclass

@dataclass
class Draft:
    text: str
    model: str
    files_touched: int
    tests_pass: bool
    lint_clean: bool

def judge(d: Draft) -> bool:
    # Deterministic signals first. Never ask a model what a test suite can answer.
    if not d.tests_pass or not d.lint_clean:
        return False
    if d.files_touched > 4:
        return False  # wide edits are where cheap drafts quietly break things
    return True

def cascade(task, cheap_model, strong_model):
    d = cheap_model.run(task)
    if judge(d):
        return d, "accepted"
    s = strong_model.run(task, prior=d.text)  # escalate, draft kept as context
    return s, "escalated"

4. How to read the five numbers

Sixty points, two points behind, half the cost, half the tokens, 40% less time. Any one of those alone misleads you. The score says Fusion Max is chasing frontier quality; the cost says it is doing it for half the money. But this is a vendor-published result on a third-party index, and an index is a proxy. What matters is your own distribution. If your tasks are one-line edits, the gap between Standard and Max may be smaller than the noise. If your tasks are cross-repo refactors, those two points may be the whole game. Treat "half the average cost" as a hypothesis you are going to reproduce, not a promise you get to quote.

{
  "copilot_fusion": {
    "default_effort": "standard",
    "pool": {
      "enabled_for_fusion": ["model-a-code", "model-b-reason", "model-c-fast"],
      "disabled_for_fusion": ["model-legacy-2025"]
    },
    "team_overrides": {
      "platform": "high",
      "docs-site": "standard"
    }
  }
}

// A shape like this is worth writing down even if your admin console stores
// it differently: it forces the argument about who gets Max and who does not.

5. Three operational edges that will bite

First, Fusion has no context window of its own: each step runs inside the limits of the model executing it, and the number shown in the UI is a conservative value derived from the smallest model in the pool. Second, routing happens along cache boundaries and at large jumps in conversation complexity, specifically to avoid paying for cache rebuilds that buy no quality — which means if your own prefix changes every turn, that optimisation is dead for you. Third, the pool is an admin surface: enterprises can inspect which models Fusion may pick from, set each model's effective policy state independently, and disable a model for Fusion without disabling it for everyone. Setting Fusion, at any effort level, as the default for users lives behind enterprise managed settings.

# Routing happens along cache boundaries, so keep the expensive prefix stable.
# A prefix that changes every request re-bills the whole context every turn.
import hashlib, json

def make_prefix(repo_rules: str, tool_schemas: dict) -> tuple[str, str]:
    blob = json.dumps({"rules": repo_rules, "tools": tool_schemas}, sort_keys=True)
    return blob, hashlib.sha256(blob.encode()).hexdigest()[:12]

def build_turn(prefix_text: str, prefix_id: str, user_turn: str) -> list[dict]:
    return [
        {"role": "system", "content": prefix_text},  # identical bytes every turn
        {"role": "user", "content": f"[turn {prefix_id}] {user_turn}"},
    ]

# Editing repo_rules should create a new prefix on purpose. Editing the user
# turn must never invalidate the cache sitting above it.

6. Measure three things before you flip the default

One: tokens and actual spend per task, split by effort level. Two: resolved rate — the share of tasks finished in one pass, not the share where the model said it was finished. Three: p95 latency, because cascade and critique add time in the tail and the mean will lie to you. Run all three for two weeks before and two weeks after, then you are allowed to have an opinion.

# Do not compare routing setups on vibes. Compare resolved tasks per dollar,
# with p95 latency next to it, or you will optimise the average and ship a
# regression to the slow tail of your team.
import json, statistics

def summarise(path: str) -> dict:
    lat, tok, resolved = [], [], 0
    for line in open(path):
        r = json.loads(line)
        lat.append(r["latency_ms"])
        tok.append(r["total_tokens"])
        resolved += 1 if r["resolved"] else 0
    return {
        "n": len(lat),
        "p95_ms": statistics.quantiles(lat, n=20)[18],
        "tok_per_task": round(sum(tok) / len(tok)),
        "resolved_rate": round(resolved / len(lat), 3),
    }

print("baseline", summarise("runs_before.jsonl"))
print("fusion  ", summarise("runs_after.jsonl"))
Code and test output in a dark editor

Cascade only pays when the judge is a deterministic signal: tests, lint, and how wide the edit is.

📌 Frequently Asked Questions

Is Copilot Fusion free, and which plans include it?

GitHub docs state that Copilot Fusion is available with all Copilot plans, including Free. Standard covers everyday coding, while High and Max target more complex work. Fusion itself carries no extra fee, but cascade and critique make more model calls and consume more AI credits, billed under your plan's rules.

Do I still choose a model after selecting Fusion?

No. You are selecting a runtime system that decides the execution pattern and the model mix per prompt. Different prompts in one session can use different patterns, and after a response you can hover the effort-level label to see which models were used.

Is Fusion Max the same as always calling the strongest model?

No. Max prioritises the most capable models for demanding reasoning while still considering token efficiency, so it escalates when depth is warranted rather than unconditionally calling the biggest model available.

Why does the context window shown look smaller than the model's?

Because Fusion has no context window of its own. Every step runs within the limit of the model executing it, and the displayed value is a conservative figure based on the smallest limit among the models in the pool — a conservative display, not a reduced allowance.

Can enterprises restrict which models Fusion uses?

Yes. Fusion only uses models enabled in your enterprise and organisation model policies. Enterprise admins can view the pool Fusion picks from, set each model's effective policy state independently, and disable a model for Fusion without disabling it for everyone. With enterprise managed settings they can also set Fusion, at any effort level, as the default model.