This episode breaks down how Fiber works behind the scenes: how fiber.App is built on fasthttp, the request flow from socket to handler, and the role of fiber.Ctx as a bridge to RequestCtx. You also get to know the core components: App, Router, Handler, Middleware, Hooks, Binding, and the default error handler.

Episode 1 covered why Fiber exists. Episode 2 now breaks down core concepts and main architecture — how Fiber works behind the scenes. You don't need to memorize code in this episode; the main goal is building a correct mental model.
This mental model matters because it determines how you solve problems later: why values in c.Params are only valid inside a handler, why allocations must be minimized, and why hooks can handle application lifecycle. All those questions come from the architecture we're about to dissect.
When a request comes in, the path it travels is very short. Fasthttp accepts the connection, creates a fasthttp.RequestCtx, then hands it to the handler produced by fiber.App via app.Handler(). That's where Fiber's router works: matching path and method to a chain of handlers.
client → fasthttp server → fiber.App → router stack → middleware → handler → response
↓
fiber.Ctx membungkus fasthttp.RequestCtxAn important consequence: fiber.Ctx is not an expensive new allocation per request. Fiber takes it from a pool, refills it, and returns it to the pool after the request finishes. This is the source of Fiber's speed.
Because fasthttp buffers are reused, strings and bytes obtained from a request are only valid while the handler runs. If you store c.Params("id") into a global variable, its value can be changed by another request. To keep data across requests, you must copy it — a pattern we use again in episodes 12 and 19.
fiber.App instance that stores config, router, and hooks. Created with fiber.New().fiber.Ctx interface that wraps fasthttp.RequestCtx and provides request, response, cookie, and locals helpers.func(fiber.Ctx) error function that is the smallest unit of execution in Fiber.app.Use.error into an HTTP response.All request and response interactions happen through fiber.Ctx. Behind the scenes, it holds a pointer to fasthttp.RequestCtx accessible via c.RequestCtx(). Some of the most frequently used methods:
func handler(c fiber.Ctx) error {
name := c.Params("name")
age := c.Query("age", "0")
body := c.Body()
c.Locals("request_id", "abc-123")
return c.JSON(fiber.Map{
"name": name,
"age": age,
"body": string(body),
})
}c.Params("name") retrieves the path parameter value, c.Query("age", "0") reads a query parameter with a default, and c.Body() returns the body as bytes. All these values are guaranteed to be valid only while the handler runs because they come from reused buffers.
To verify how the router stores routes, Fiber provides app.Stack():
routes, err := json.MarshalIndent(app.Stack(), "", " ")
if err != nil {
log.Fatal(err)
}
log.Println(string(routes))app.Stack() returns a slice per HTTP method, each containing paths and parameter names. Understanding this output helps a lot when debugging route conflicts in episode 19.
Fiber follows the principle of minimal allocation: avoid creating new objects per request as much as possible. Binding structs are reused, fasthttp buffers are managed with sync.Pool, and strings are not copied unless necessary. The results show up in go test -benchmem — a topic we'll explore in episode 17.
go test -bench=. -benchmem -benchtime=1sThe B/op and allocs/op columns show the bytes and number of allocations per operation. go test -bench=. -benchmem -benchtime=1s will be our main weapon when measuring performance in episodes 17 and 19.
Because of the zero-copy principle, there's a rule to remember: if you want to keep a request value for use after the handler finishes, use c.App().GetString(...) or strings.Clone. Fiber provides the GetString and GetBytes helpers specifically for this case when Immutable is enabled. We'll cover the details when we discuss context and concurrency.
Key takeaways:
fiber.App is built on fasthttp, not net/http.fiber.Ctx wraps fasthttp.RequestCtx and is only valid inside a handler.app.Stack() helps you inspect the route structure; go test -benchmem measures allocations.In the next episode, episode 3, we build setup and your first hello world — installing Fiber v3, creating an App instance, adding the default Logger and Recover middleware, then returning JSON and text responses with the correct status codes. Time for your first code.