Arifur.
← Back to blog
9 min readArifur Rahman Abir

I Benchmarked Gin vs Chi for 3 Days. The Real Answer Wasn't in the Numbers.

  • Go
  • Backend Architecture
  • Clean Architecture
  • Benchmarking
The Gin and Chi gopher logos facing off, with Gin at 88.2k GitHub stars and Chi at 21.7k
What I learned about Go's two most popular frameworks — and why the most-quoted benchmark gets it wrong.

It was 2 in the morning. The chai was cold. My laptop fan was doing that whine it does when too many tabs are open.

I had been comparing two Go frameworks for almost three days. Gin and Chi. Both popular. Both production-ready. Both endorsed by engineers I respect. I needed to pick one for the backend of a calling system we're building. It handles around twenty thousand calls a day.

How hard could this be?

Three days, apparently. That's how hard.

Here's what I thought I'd find: a clear winner, a faster framework, decision made by Tuesday lunch.

Here's what I actually found: the most quoted benchmark in the Go community misses the most important question, the most-recommended framework isn't the one used by the companies you'd expect, and the decision had almost nothing to do with raw performance.

This is what 72 hours of digging taught me. Let me show you the numbers first. Then I'll show you what the numbers hide.

The popularity numbers everyone quotes

Type "Gin vs Chi" into a search engine and you'll see the same story everywhere. Gin won. Gin is faster. Gin has more stars. Move on.

On the surface, the data does say that:

GinChi
GitHub stars (May 2026)88,20021,700
Forks8,6001,100
Contributors508157
Dependent projects293,00030,400
Latest releasev1.12.0 (Feb 2026)v5.2.5 (Feb 2026)
Sources: github.com/gin-gonic/gin and github.com/go-chi/chi

And the JetBrains 2025 Developer Ecosystem Report — the most rigorous public survey of professional Go developers — puts Gin at 48% adoption worldwide, up from 41% in 2020. Chi doesn't even crack the top 5. Echo sits at 16%. Fiber at 11%. Gorilla/mux at 17% but declining (it was archived in 2023).

By every popularity metric, the case is closed.

But this is where I started questioning the question itself.

Popularity in software is a lagging indicator. A framework that's popular today won the battle five years ago, when the people using it today were just learning Go. It tells you about the past. It doesn't tell you about what the best engineers are reaching for right now.

So I stopped looking at adoption charts and started looking at production code.

The performance benchmark that almost decided it for me

First, the actual speed test. Standard setup. Hello-world JSON endpoint. M2 MacBook. Single core. Bombardier as the load tester.

text
Gin:        ~58,000 requests/second
Chi:        ~52,000 requests/second
net/http:   ~47,000 requests/second

Gin is roughly 10–15% faster. This matches the well-known pkieltyka/go-http-routing-benchmark suite on GitHub and the TechEmpower Round 22 results.

Then I did the math for the actual workload I was building for.

Twenty thousand calls a day. Each call generates maybe ten backend HTTP requests when you account for webhooks, status callbacks, recording uploads, billing events. That's around two hundred thousand requests a day total. Peak load during business hours: maybe sixty requests per second. Sustained average: three.

Both frameworks benchmark at around 50,000 requests per second per single core.

My peak load is sixty.

I had been agonizing over which race car to use for delivering groceries. Whichever I picked was going to spend 99.9% of its time waiting on PostgreSQL anyway. The performance gap between Gin and Chi at my scale wasn't a difference. It was a rounding error.

This is where most comparison articles end. Pick the popular faster one. Ship it.

I almost did. Then something stopped me…

The benchmark missing from every comparison post

I started checking which companies actually use which framework in production. Not "company X uses Go" handwaving — I mean opening their public GitHub repositories and reading their import statements with my own eyes.

What I found broke my assumption.

The companies whose entire business is running infrastructure for other developers — they don't use the popular framework. They use Chi.

Cloudflare. Heroku. Netlify. Supabase. HelloFresh. Malwarebytes. Parts of Uber.

Supabase's auth service has github.com/go-chi/chi/v5 imported right at the top of its router file. You can verify this on their public GitHub: supabase/auth/internal/api/router.go. HelloFresh's Janus API gateway runs on Chi. The httprate rate limiter under Chi was inspired by Cloudflare's own sliding window counter algorithm — Cloudflare wrote the underlying paper, Chi built the implementation. Netlify's gotrue (the predecessor codebase to Supabase Auth) was built on Chi from day one. Pathao — Bangladesh's largest ride-sharing platform — uses Chi for internal services. An engineer from there self-identified in go-chi/chi issue #91.

Where does Gin show up? Different list entirely:

  • PayPal's infrastructure platform team (ex-engineering manager wrote about it on Medium, May 2024)
  • Tencent and Bilibili, through their Kratos microservices framework built on top of Gin
  • Kaplan Test Prep, Sezzle, Teachable, Shippo, ZestMoney, SWORD Health, PhotoPrism
  • Most of the Indian, Bangladeshi, and Chinese fintech ecosystems

Look at the pattern. Both lists contain serious, well-funded companies. But they have different identities.

The first list is we build infrastructure that other developers depend on.

The second list is we build product features that customers pay for.

Same kind of engineering quality. Different kind of engineering job.

So why does the popularity number mislead?

Once I saw this split, the JetBrains 48% figure stopped looking like a verdict and started looking like a clue.

Forty-eight percent of Go developers using Gin doesn't mean Gin is forty-eight percent of Go's best engineering. It means Gin is forty-eight percent of Go's easiest path — the framework with the most tutorials, the most Stack Overflow answers, the most AI coding assistant training data, the most YouTube videos.

Think about how that compounds. A junior developer in Dhaka, Mumbai, Jakarta, or Lagos searches for "how to build a REST API in Go." They land on a Gin tutorial. They build their first service in Gin. They join a company and recommend Gin because that's what they know. Now Gin is on the company's resume requirements. New hires must know Gin. Another generation of Go developers starts with Gin. Repeat.

This is what survey results capture: the accumulated weight of the easiest path.

Now look at the other companies. If you're a senior engineer at Cloudflare building edge infrastructure, you don't pick frameworks based on Stack Overflow availability. You pick them based on how cleanly they compose with the standard library, how easy they are to debug at 3 AM, how little magic they add between your code and the bytes coming in over the wire. Chi wins on those metrics because it doesn't try to be a framework. It's a router with standard http.Handler signatures. No custom context type. No opinionated layer. Just routing, done well.

For an average product team shipping CRUD APIs, none of that matters. Gin's c.JSON(200, gin.H{...}) saves you ten characters per response. Over a hundred-endpoint codebase, that adds up. You ship faster. Your juniors onboard faster. You can hire from a much larger pool.

Both choices are correct. They're correct for different jobs.

The code shows the philosophy

Here's the same simple JSON endpoint in both frameworks.

Gin:

go
func ping(c *gin.Context) {
    c.JSON(200, gin.H{"message": "pong"})
}

Two lines of real code. The framework hides the HTTP plumbing. Reads almost like an English sentence: respond with JSON, status 200, message pong.

Chi:

go
func ping(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(200)
    json.NewEncoder(w).Encode(map[string]string{"message": "pong"})
}

Four lines. More ceremony. But every single line uses standard Go's net/http interfaces — meaning any Go developer who has ever touched HTTP can read this code without learning a new framework first. There's no c.JSON. There's no gin.H. There's no magic context. Just the standard library.

Both work. Both ship. Both have their own kind of elegance.

The Gin code is the elegance of polish.

The Chi code is the elegance of subtraction.

The decision framework, in three questions

After three days of benchmarking, my actual decision came down to three questions. If you're staring at the same Gin vs Chi crossroads, try these:

  • One. Is this code customer-facing or infrastructure-facing? Customer-facing favors Gin's productivity. Infrastructure-facing favors Chi's clarity.
  • Two. What's the seniority of your team — and where will it be in two years? Senior teams compose more naturally with Chi. Mixed-experience teams ship faster with Gin.
  • Three. Will you ever want to extract part of this code into a separate micro-service with different ownership? If yes, Chi's standard library compatibility makes that trivial. Gin's custom context type makes it harder.

For my calling system, the honest answer to all three questions was: it depends which part of the code we're talking about.

The product API is customer-facing, mixed-team, single-service work. Gin territory.

The webhook ingestion service is infrastructure-grade, must-be-bulletproof, gets-debugged-at-2-AM-when-Twilio-misfires work. Chi territory.

So I stopped picking. I split the codebase.

What I ended up shipping

The product API runs on Gin. All the customer-facing endpoints. The dashboard data. The WebSocket hub that pushes real-time call events to the Next.js frontend. The CRUD operations. The places where shipping speed wins.

The webhook ingestion service runs on Chi. The endpoints that receive Twilio callbacks at random hours and need to validate HMAC signatures, return 200 within Twilio's strict 15-second timeout, and push events into a queue without ever blocking. The places where every line needs to be obvious to anyone reading the code at 3 AM.

This isn't a creative invention. It's exactly how Supabase structures their stack. It's how HelloFresh structures Janus. It's how Netlify built their auth service before it became Supabase Auth. Mature engineering organizations split product code from infrastructure code and pick the right framework for each. I didn't invent the pattern. I just had to benchmark for three days to discover I should follow it.

The benchmark answer was never in the numbers

The chai is fresh now. The fan has stopped whining. I closed thirty-seven browser tabs.

Two frameworks. Three days. One conclusion that turned out to be obvious in hindsight: stop asking which tool is better. Start asking what each tool is for.

The companies that build product picked one framework. The companies that build infrastructure picked the other. Both kinds of companies make the same kind of money. Both ship. Neither is wrong.

The benchmark answer was never going to be in the requests-per-second column. It was hiding inside the question of what you're actually trying to build, and for whom.

Pick yours based on that.

Not on what's trending.

References

I write about backend architecture, founder decisions, and what it's actually like to build production software from Dhaka. The full 30-page research document, with code samples, sizing math, and security middleware comparisons, is available on request.

Originally published on Medium. Read it there or get in touch to talk about backend architecture.