Discussion: Adopting go-chi/chi as the HTTP router for LabKit v2
As part of ongoing work in LabKit v2, we're evaluating whether to adopt go-chi/chi as the standard HTTP router for all Go services within GitLab.
This follows the same process used for slog adoption: an open discussion where senior technical leadership and Go service maintainers can raise concerns, suggest alternatives, or approve the direction. We want explicit alignment before v2/httpserver ships, since the router choice affects every Go service that adopts LabKit v2.
This issue is intended to be a place where team members can raise concerns or additional requirements that need to be catered to going forward.
Justification
The proposed v2/httpserver package introduces an abstract Router interface designed so the underlying HTTP framework can be swapped without breaking consumers (team-tasks#4283). Before this package ships, we need alignment on which router backs the interface by default, since that choice affects the interface design, the middleware story, and the dependency footprint of every Go service that adopts LabKit v2.
Services today that need route grouping, scoped middleware, or sub-router mounting bring their own routers (Gorilla, Chi, or custom), creating the same fragmentation we addressed with slog. Standardising on a single router through LabKit v2 eliminates this.
Objectives
- Standardisation: Define one consistent way of structuring HTTP routing across services, reducing the cognitive load when moving between codebases.
- Faster iteration by engineering teams: Provide route grouping, scoped middleware, and sub-router mounting out of the box so teams focus on business logic instead of HTTP plumbing.
- Faster iteration for infrastructure teams: Centralise routing so cross-cutting concerns (rate limiting, circuit breakers, auth middleware) can be rolled out consistently.
Why Chi?
An investigation with benchmarks was conducted in team-tasks#4294. Key findings:
-
Minimal dependency footprint. Chi depends only on the standard library. No transitive dependencies beyond
net/http. -
Stdlib-compatible API. Chi uses standard
http.Handlerandfunc(http.Handler) http.Handlermiddleware signatures. Existing stdlib handlers and middleware work without adapters. - Active maintenance. Chi is widely adopted in the Go ecosystem with consistent releases and responsive maintainership.
- Performance. Comparable to stdlib ServeMux for static routes, faster for parameterized routes. Significantly faster than Gorilla. Full benchmark data is in the investigation issue.
Compared to alternatives:
| Router | Stdlib-compatible | Route groups | Scoped middleware | Dependencies | Status |
|---|---|---|---|---|---|
net/http.ServeMux |
Yes | No | No | None | Active |
go-chi/chi |
Yes | Yes | Yes | None (stdlib only) | Active |
gorilla/mux |
Yes | No | Limited | 0 | Archived, then revived |
The full evaluation (including httprouter, Fiber, Echo, Gin) is in team-tasks#4294.
Prior Art Within GitLab
Chi is not new to GitLab. It has already been evaluated or adopted in several projects:
| Project | Status | Notes |
|---|---|---|
| Container Registry | Chi migration attempted (2022-2023, gitlab-org#9467) | Hayley Swimelar authored MRs, Stan Hu reviewed. Work stalled but validated the approach. |
| Zoekt Indexer | Chi v5.2.5 in production | Already shipping with Chi as the HTTP router. |
| Artifact Registry | Evaluating LabKit v2 | First new service to adopt v2/httpserver. Router choice directly affects their architecture. |
Affected Go Services
The router standardisation would affect these services over time:
| Service | Current Router | Migration Complexity |
|---|---|---|
| Container Registry | gorilla/mux | Medium (prior Chi migration work exists) |
| GitLab Pages | gorilla/mux + handlers + securecookie + sessions | High (deep Gorilla dependency) |
| Workhorse | stdlib | Low (stdlib routing, Chi is stdlib-compatible) |
| Gitaly | gRPC (minimal HTTP) | Low |
| gitlab-shell | gRPC/SSH (no HTTP) | Minimal |
| Runner | stdlib | Minimal |
| KAS (gitlab-agent) | No HTTP routing | Low |
| Artifact Registry (new) | Will use LabKit v2 | N/A (greenfield) |
Functional Requirements
Based on the design requirements in team-tasks#4283 and current service patterns:
| Functionality | Notes |
|---|---|
| Route grouping | Scope middleware to route subtrees (e.g. auth on /api/* only) |
| Method-specific registration |
r.Get("/path", handler) instead of pattern strings |
| Per-route middleware | r.With(authMW).Get("/admin", handler) |
| Sub-router mounting |
r.Mount("/api/v2", apiRouter) for modular route trees |
| Path parameters | Abstracted behind the LabKit Router interface, not framework-specific |
| Custom 404/405 handlers | Override default not-found and method-not-allowed responses |
| Stdlib fallback | Services that don't need Chi's features can continue using ServeMux through the same interface |
| No framework types in public API | Per #4283 (closed) design requirements, all public types are stdlib or LabKit-defined |
Migration Strategy
If approved, Chi would be the default router in v2/httpserver:
- Resolve this discussion to get alignment on Chi as the default router.
-
Ship
v2/httpserverwith Chi backing theRouterinterface, while keeping the interface implementable by alternative routers. - Validate in a low-risk service (similar to the gitlab-shell approach for slog) before broader rollout.
Approval
This list represents a sample of senior technical leaders from across our engineering org.
- @andrewn
- @ash2k
- @cmiskell
- @engwan
- @grzesiek
- @hswimelar
- @iamphill
- @igor.drozdov
- @igorwwwwwwwwwwwwwwwwwwww
- @jdrpereira
- @jessieay
- @josephburnett
- @nolith
- @patrickbajao
- @pedropombeiro
- @reprazent
- @samihiltunen
- @slashmanov
- @stanhu
- @vyaklushin
Please note: This list is not comprehensive, if you believe that you should be on this list, please feel free to add yourself!
Related
- team-tasks#4103: Discussion: Deprecating Logrus in favour of log/slog (precedent for this process)
- team-tasks#4283: LabKit v2 httpserver package (design requirements)
- team-tasks#4294: Router investigation (benchmarks and evaluation)
- !339: v2/httpserver MR (implementation)
- epic: UAM LabKit Follow-up Work