This page documents Gin's performance optimization features and techniques. It covers the framework's architectural choices that enable high-throughput request handling with minimal memory allocations.
Gin achieves its performance through several key optimizations:
sync.Pool to reduce garbage collection pressure gin.go183sonic or go-json codec/json/api.go10unsafe pointers internal/bytesconv/bytesconv.go11-21The benchmark results show Gin achieving 0 B/op and 0 allocs/op for routing operations, making it one of the fastest Go web frameworks BENCHMARKS.md33-46
Gin uses sync.Pool to maintain a pool of reusable Context objects, eliminating the need to allocate new contexts for every request. This significantly reduces GC overhead under high load.
Context Pool Lifecycle Sources: gin.go183 gin.go229-231 gin.go667-674
The pool is initialized when creating a new Engine gin.go229-231
| Component | Location | Purpose |
|---|---|---|
Engine.pool | gin.go183 | Pool storage field. |
pool.New | gin.go229-231 | Factory function for new contexts. |
allocateContext() | gin.go252-256 | Creates context with pre-sized slices for params. |
ServeHTTP() | gin.go667-674 | Entry point that retrieves context from pool. |
Context.reset() | context.go103-118 | Clears context state for reuse. |
Sources: gin.go183 gin.go229-231 gin.go252-256
Gin's router uses a radix tree (prefix tree) that performs path matching without heap allocations. Each HTTP method has its own tree stored in Engine.trees gin.go184
methodTrees Structure and Node Types Sources: gin.go184 tree.go45-59 tree.go90-108
Gin dynamically reorders child nodes based on access frequency. Frequently accessed routes move to the front of the indices string and children slice for faster matching tree.go111-131
| Field | Type | Purpose |
|---|---|---|
path | string | Path segment for this node tree.go100 |
indices | string | First bytes of child paths for quick lookup tree.go101 |
priority | uint32 | Access count used for reordering tree.go104 |
handlers | HandlersChain | Handler functions if this is a leaf tree.go106 |
Sources: tree.go99-108 tree.go111-131
Gin allows developers to swap the default encoding/json library for faster alternatives using build tags. This is managed via the codec/json abstraction codec/json/api.go10
| Library | Build Tag | Implementation File |
|---|---|---|
encoding/json | Default | codec/json/json.go |
sonic | sonic | codec/json/sonic.go |
go-json | go_json | codec/json/go_json.go |
json-iterator | jsoniter | codec/json/jsoniter.go |
Sources: codec/json/api.go10-19 codec/json/json.go5 codec/json/sonic.go5
The json.API variable implements the Core interface, providing a unified way to access the chosen library codec/json/api.go10-19
Sources: codec/json/api.go13-19
Gin uses unsafe pointers in the internal/bytesconv package to convert between []byte and string without copying memory. This is used extensively in the router for path processing tree.go13
| Function | Implementation | Purpose |
|---|---|---|
StringToBytes | unsafe.Slice(unsafe.StringData(s), len(s)) | Convert string to byte slice internal/bytesconv/bytesconv.go13-15 |
BytesToString | unsafe.String(unsafe.SliceData(b), len(b)) | Convert byte slice to string internal/bytesconv/bytesconv.go19-21 |
Sources: internal/bytesconv/bytesconv.go11-21
The Engine tracks the maximum number of parameters and path sections across all registered routes to pre-allocate Context slices with sufficient capacity gin.go379-386
Pre-allocation Data Flow Sources: gin.go185-186 gin.go252-256 gin.go379-386 tree.go80-88
addRoute, Gin calls countParams and countSections gin.go379-386Engine.maxParams and Engine.maxSections are updated to the highest values found gin.go380-385pool.New is called, it uses allocateContext to create a Context with slices pre-allocated to these maximums gin.go252-256Sources: gin.go252-256 gin.go379-386 tree.go80-88
Refresh this wiki