Building a Low-Latency Global Code Completion Service

github · Tech · 2024 · source Agentic: no · promotional bias: low · source-backed · extracted with prompt 0.5.4 (schema v2)

Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.

Problem

Domain: Low-latency LLM code completion

GitHub Copilot needed to serve cloud-hosted LLM code completions fast enough to compete with local IDE autocomplete while authenticating users, avoiding wasted inference, and routing traffic globally.

Constraints:

Architecture

GitHub built copilot-proxy, an authenticating HTTP/2 proxy between IDE extensions and Azure-hosted LLMs. IDEs authenticate to GitHub, exchange OAuth credentials for signed short-lived completion tokens, and send completion requests through the proxy. The proxy validates tokens locally, swaps in the provider service key, forwards requests over long-lived HTTP/2 connections, streams completions back, propagates cancellation through request contexts, routes users to nearby proxy/model regions with octoDNS, and relies on GLB/HAProxy for end-to-end HTTP/2 control and graceful redeploys.

Diagram confidence: explicit (topology described by the source).

flowchart LR
  ide-extensions[IDE extensions] --> github-oauth[GitHub OAuth]
  github-oauth --> short-lived-completion-token[short-lived completion token]
  ide-extensions --> glb-load-balancer[GLB load balancer]
  glb-load-balancer --> copilot-proxy[copilot-proxy]
  short-lived-completion-token --> copilot-proxy
  copilot-proxy --> http-2-connection-pool[HTTP/2 connection pool]
  http-2-connection-pool --> azure-hosted-llm-models[Azure-hosted LLM models]
  octodns-routing[octoDNS routing] --> copilot-proxy
  octodns-routing --> azure-hosted-llm-models
  copilot-proxy --> proxy-observability[proxy observability]
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
IDE extensions Client integrations for VS Code, Visual Studio, IntelliJ IDEs, Neovim, Xcode, and other editor surfaces. GitHub OAuth, copilot-proxy
GitHub OAuth Authenticates IDE installations and issues credentials that can be exchanged for completion tokens. IDE extensions, short-lived completion token
short-lived completion token Signed authorization token for a short period of completion-service use. GitHub OAuth, copilot-proxy
GLB load balancer GitHub's HAProxy-based load balancer that preserves client HTTP/2 connections and supports graceful proxy redeployments. IDE extensions, copilot-proxy
copilot-proxy Authenticates requests, swaps service keys, forwards to models, streams responses, propagates cancellation, observes SLOs, mutates requests when needed, and manages model traffic. short-lived completion token, GLB load balancer, HTTP/2 connection pool, Azure-hosted LLM models, octoDNS routing
HTTP/2 connection pool Long-lived pooled streams from proxy to model that avoid repeated TCP/TLS setup and support stream-level cancellation. copilot-proxy, Azure-hosted LLM models
Azure-hosted LLM models Regional model endpoints that generate code completions and support global placement. HTTP/2 connection pool, octoDNS routing
octoDNS routing DNS configuration and health-check routing layer for geographic placement, weighted routing, and regional failover. copilot-proxy, Azure-hosted LLM models
proxy observability Proxy-layer SLO and metrics vantage point for latency, cancellation, success rate, traffic splits, and provider behavior. copilot-proxy

Data flow

A developer pauses in an IDE, triggering a completion request. The IDE uses a short-lived code-completion token obtained from GitHub. copilot-proxy validates the token signature, swaps it for the API service key, forwards the request to an Azure-hosted model over pooled HTTP/2 connections, and streams tokens back. If the user types through, the IDE resets the HTTP/2 stream; cancellation propagates through the proxy to the model without closing the underlying connection. octoDNS routes users to healthy nearby proxy/model regions, and proxy metrics define the service SLO.

4 supporting quotes
“The IDE now can use that OAuth credential to go to GitHub and exchange that for what we call a short-lived code completion token.”article, stated
“If it's good, we swap the key out for the actual API service key, forward it on, and stream back the results. We don't need to do any other further validation.”article, stated
“We use HTTP/2 between the client and the proxy because that allows us to create a connection once and reuse it over and again.”article, stated
“The cancellation that happens in the IDE propagates to the proxy and into the model effectively immediately. This is all rather neatly expressed here, but it requires that all parties speak HTTP/2 natively.”article, stated

Why this architecture

GitHub kept an intermediary proxy despite low-latency pressure because it solved authentication, cancellation, observability, regional health, request mutation, traffic splitting, and model-provider abstraction. Colocating proxy and model instances in the same Azure regions made the extra hop cheap enough while preserving operational control.

3 supporting quotes
“The solution that we arrived at is to build an authenticating proxy which sits in the middle of this network transaction.”article, stated
“Instead, by colocating proxy instances and model instances in the same Azure region, we, to most extent, ameliorated the cost of that extra hop.”article, stated
“This vantage point is also good, because while our upstream provider does give us lots of statistics, they're really targeted to how they view running the service”article, stated

Models used: Azure-hosted OpenAI models · LLMs for code completion

Scale

Alternatives considered (roads not taken)

Embed model service keys in the IDE extension

Rejected because: A shipped extension cannot hide a service key from casual or malicious extraction.

“The wrong way to do it would be to encode the key somehow in the extension that we give to users in a way that it can be extracted and used by the service but is invisible to casual or malicious onlookers.”article, stated
“This is impossible. This is at best security by obscurity. It doesn't work, just ask the rabbit r1 folks. The solution that we arrived at is to build an authenticating proxy which sits in the middle of this network transaction.”article, stated

HTTP/1-style cancellation by closing connections

Rejected because: Closing the TCP connection forces reconnects for the next immediate completion request and costs more latency than ignoring stale results.

“Because cancellation in HTTP world is the result of closing that connection. In our case, in the usage of networking TCP to talk to the proxy, the reason we canceled that request is because we want to make another one straightaway.”article, stated
“The latency of that far exceeds the cost of just letting the request that we didn't need, run to completion, and then just ignoring it.”article, stated

Use standard cloud load balancers/CDNs for HTTP/2

Rejected because: At the time, common providers downgraded backend traffic to HTTP/1 or lacked the HTTP/2 control Copilot needed.

“For example, most load balancers are happy to speak HTTP/2 on the frontend but downgrade to HTTP/1 on the backend. This includes most of the major ALB and NLBs you get in your cloud providers.”article, stated
“At the time, CDNs didn't support HTTP/2 on the backend. That was an absolute non-starter. Most cloud providers didn't support HTTP/2 on the backend.”article, stated

Point-of-presence edge proxy model

Rejected because: Completions always call back to a model, so PoPs created traffic tromboning and operational burden without enough latency benefit.

3 supporting quotes
“one model we experimented with and then rejected because it just didn't work out for us was the so-called point of presence model.”article, stated
“For us doing code completions, it's always going back to a model. What we ended up after a lot of experimentation was the idea of having many regions calling back to a few models just didn't pay for itself.”article, stated
“The latency wasn't as good and it carried with it a very high operational burden. Every point of presence that you deploy is now a thing you have to monitor, and upgrade, and deploy to, and fix when it breaks.”article, stated

Have clients connect directly to Azure

Rejected because: Direct Azure connections left authentication and observability unresolved, likely recreating the same proxy layer behind Azure's curtain.

“What if we just went straight to Azure instead, we had clients connect straight to Azure? This would have left authentication as the big problem, as well as observability.”article, stated

Patterns

latency-optimization (performance)

Copilot uses long-lived HTTP/2 connections, stream-level cancellation, regional colocation, and request streaming to hit IDE-completion latency targets.

“We serve hundreds of millions of requests a day with an average response time of under 200 milliseconds.”article, stated
“We use HTTP/2 between the client and the proxy because that allows us to create a connection once and reuse it over and again.”article, stated

cost-aware-routing (operations)

HTTP/2 cancellation prevents paying for stale inference when users type through completion requests.

“Half of the time, we'd be performing that inference and then throwing the result on the floor, which is an enormous waste of money, time, and energy”article, stated
“Without cancellation, we'd make twice as many requests and waste half of them.”article, stated

fallback-degradation (reliability)

Unhealthy regional proxy/model capacity removes itself from DNS so users route elsewhere and receive degraded latency instead of errors.

“If a proxy instance starts seeing its success rate drop, they vote themselves out of DNS.”article, stated
“It turns a regional outage when we're like, "All of Europe can't do completions", into a just reduction in capacity because traffic is routed to other regions.”article, stated

observability-tracing (operations)

The proxy provides the correct measurement point for latency, cancellation distributions, provider gaps, and end-user SLOs.

“We do that by defining in our SLOs that the point we are measuring is at our proxy.”article, stated
“There would be no way we would have been able to spot this without our own observability at that client proxy layer.”article, stated

model-routing (model_operations)

The proxy can split traffic across model capacity, mirror requests to new model versions, and combine multiple capacity units into a logical model.

“we can now split traffic across multiple models.”article, stated
“We can do the opposite. We can mirror traffic. We can take a read-only tap of requests and send that to a new version of the model”article, stated

canary-rollout (release_management)

Proxy-level traffic splits and mirrored traffic let GitHub test new model versions and experiments without waiting for client rollout.

“Then we can take these two ideas and mix and match them and stack them on top of each other and make A/B tests, experiments, all those kinds of things, all without involving the client.”article, stated

safety-policy-enforcement (access_control)

The proxy validates signed short-lived tokens and swaps them for the protected provider service key instead of exposing provider credentials to clients.

“When the request lands on the proxy, all we have to do is just check that that signature is valid.”article, stated
“If it's good, we swap the key out for the actual API service key, forward it on, and stream back the results.”article, stated

Tradeoffs

Keep copilot-proxy in the hot path

Chose GitHub-owned authenticating proxy over Direct IDE-to-Azure model calls.

Rationale: The proxy adds a hop, but it solves authentication, observability, request mutation, cancellation, routing, traffic splitting, and operational control.

“This would have left authentication as the big problem, as well as observability.”article, stated
“We would have probably ended up with exactly the same number of moving parts just with more of them behind the curtain in the Azure side.”article, stated

Use regional proxy/model colocation

Chose Proxy instances colocated with Azure model regions over Many edge PoPs proxying back to a few centralized models.

Rationale: Completions always require model inference, so edge PoPs caused tromboning and operational burden without enough latency benefit.

“if there is a model in an Azure region, we colocate a proxy instance in that same Azure region and we say that is the location that users' traffic is sent to.”article, stated
“Every point of presence that you deploy is now a thing you have to monitor, and upgrade, and deploy to, and fix when it breaks.”article, stated

Invest engineering budget in a bespoke HTTP/2 proxy

Chose Custom proxy accelerating one API call over Pure off-the-shelf glue between model providers and clients.

Rationale: The proxy created a marketable latency and operations advantage where generic infrastructure did not meet requirements.

“the challenge to you is, find the place where investing your limited engineering budget, in a bespoke solution, is going to give you a marketable return.”article, stated
“In our case, it was writing a HTTP/2 proxy that accelerated one API call.”article, stated

Gotchas (what bit them)

HTTP cancellation is normally too destructive for rapid autocomplete.

Root cause: HTTP/1 cancellation closes the TCP connection, but autocomplete users usually need another request immediately.

Resolution: Use HTTP/2 streams so each request can be reset while the underlying connection remains open.

“In our case, in the usage of networking TCP to talk to the proxy, the reason we canceled that request is because we want to make another one straightaway.”article, stated
“Instead of resetting the TCP connection itself, you just reset the individual stream representing the request you made. The underlying connection stays open.”article, stated

End-to-end HTTP/2 support was weaker than expected.

Root cause: Common load balancers and CDNs often spoke HTTP/2 only on the frontend and downgraded backend traffic.

Resolution: Use GitHub's GLB/HAProxy stack to control HTTP/2 end-to-end and preserve client connections across proxy redeployments.

“most load balancers are happy to speak HTTP/2 on the frontend but downgrade to HTTP/1 on the backend.”article, stated
“HAProxy turns out to be one of the very few open-source load balancers that offers just exquisite HTTP/2 control.”article, stated

Typed-through completions can waste nearly half of inference work.

Root cause: Users keep typing after the request was sent, so the request context no longer matches the editor state.

Resolution: Propagate cancellation from IDE to proxy to model and add pre-forward checks for immediately canceled requests.

“If you continue to type after we've made a request, you've now diverged from the data we had and our request is now out of date.”article, stated
“just before we made the request to the model, we would check, has it actually been cancelled?”article, stated

Client rollout is too slow for urgent provider fixes.

Root cause: A long tail of outdated IDE extensions means client-side fixes do not reach everyone quickly.

Resolution: Use the proxy to mutate requests or trigger client upgrade prompts while normal client rollout catches up.

“That last 20% will take until the heat death of the universe.”article, stated
“Because we have a proxy in the middle, we can just mutate the request quietly on the way through”article, stated

Provider metrics do not describe end-user experience.

Root cause: Model providers optimize their own service view, while users care about end-to-end completion latency.

Resolution: Set SLOs and dashboards at the proxy layer, the data-plane split between client and provider.

“their metrics. They have basic request counts and error rates and things like that, but they're not really the granularity we want.”article, stated
“What you care about is the total end-to-end time of the request.”article, stated

Evaluation

GitHub measures Copilot from the proxy/data-plane viewpoint, using latency, success rate, cancellation distributions, regional health, and traffic-split/mirror experiments rather than relying only on client-side averages or provider metrics.

Metrics: mean response time under 200 milliseconds · peak throughput around 8,000 requests per second · typed-through request share around half · success-rate SLO per proxy instance · regional health-check status · cancellation lifetime distributions · traffic split and mirrored model validation

3 supporting quotes
“We do that by defining in our SLOs that the point we are measuring is at our proxy.”article, stated
“each proxy instance is looking at the success rate of requests that it sees and it handles.”article, stated
“We can take a read-only tap of requests and send that to a new version of the model that we might be either performance testing, or validating”article, stated

Outcomes

The source reports over 400 million daily completion requests, about 8,000 requests per second at peak, under-200-millisecond mean response time, over 100 million GitHub users, around half typed-through requests, and global model/proxy regions.

4 supporting quotes
“We serve more than 400 million completion requests.”article, stated
“We peak at about 8,000 requests a second”article, stated
“Without cancellation, we'd make twice as many requests and waste half of them.”article, stated
“By having multiple models around the globe, that turns SEV1 incidents into just SEV2 alerts.”article, stated