Learning Fiber - Performance Tips and Template Rendering
Series/Learn Fiber/Episode 12
Episode 12 of 23

Learning Fiber - Performance Tips and Template Rendering

This episode covers Fiber v3 performance tips and best practices: limit middleware, use fasthttp pooling and prefork, render templates with github.com/gofiber/template, and serve public asset files and folders with app.Static.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Fiber is built on fasthttp and is very fast — but performance still depends on how we use it. Episode 12 covers performance tips and best practices: limiting middleware, leveraging fasthttp pooling, rendering templates, and serving public assets correctly.

Performance is a cumulative result. A little waste in every middleware will be felt under high traffic. This topic also completes the part of web applications we haven't touched yet: HTML pages from the server.

Performance Tips

Reduce Global Middleware

Every middleware adds per-request cost. Only install middleware you actually need, and attach it to groups rather than globally:

Middleware seperlunya
app := fiber.New()
app.Use(logger.New())
app.Use(recover.New())
 
api := app.Group("/api", authMiddleware())
admin := app.Group("/admin", authMiddleware(), rateLimiter())

logger and recover genuinely need to be global. But authMiddleware is enough for the /api group, and rateLimiter only for /admin. Too much middleware at the global level slows down every route for no reason.

Leverage fasthttp Pooling

Fiber uses fasthttp, which reuses connections and buffers. Avoid storing *fiber.Ctx pointers outside the handler scope:

Jangan simpan ctx
func badHandler(c fiber.Ctx) error {
    globalCtx = &c // jangan simpan ctx: di-reuse antar request
    return nil
}
 
func goodHandler(c fiber.Ctx) error {
    result := c.Params("id") // salin data yang dibutuhkan
    storeResult(result)
    return nil
}

The fasthttp context is recycled after the request finishes. Storing a Ctx pointer in a global variable or goroutine will read request data that has already expired. Always copy the values you need before the handler finishes.

Prefork for Multicore

Prefork runs several workers, one per CPU core. This multiplies throughput on multicore machines:

Aktifkan prefork
app := fiber.New(fiber.Config{
    Prefork: true,
})

With Prefork: true, Fiber creates one worker process per core and shares the port. Great for production; for development it's better to turn it off because hot-reload works more simply with a single process.

Template Rendering

Engines from github.com/gofiber/template

Fiber doesn't put a template engine in its core. Use the github.com/gofiber/template package, which provides many engines — HTML, Pug, Mustache, and others:

Setup template engine
import "github.com/gofiber/template/html/v2"
 
engine := html.New("./views", ".html")
app := fiber.New(fiber.Config{
    Views: engine,
})

html.New("./views", ".html") loads all .html files from the views folder. For another engine, just change the import, for example template/pug/v2 or template/mustache/v2 — the fiber.Views interface stays the same.

Rendering with c.Render

With Views installed, handlers can render full HTML pages complete with data:

Render halaman
app.Get("/", func(c fiber.Ctx) error {
    return c.Render("index", fiber.Map{
        "Title": "Halaman Utama",
        "User":  map[string]any{"Name": "Budi"},
    }, "layouts/main")
})

c.Render("index", data, "layouts/main") renders the index template with data, then wraps it in the layouts/main layout. The result is a complete HTML page from the server — the main pattern for applications that aren't pure APIs.

Serving Public Assets

Folders and Static Files

app.Static serves files from a folder, and app.StaticIndex sets a folder's index file:

Serve file statis
app.Static("/", "./public")
app.StaticIndex("/", "./public/index.html")

app.Static("/", "./public") maps / to the public folder. If ./public/index.html exists, the / route responds with that page directly — no extra handler needed. For a single file, use app.Static("/favicon.ico", "./public/favicon.ico").

Testing

Tes render dan static
curl http://localhost:3000/
curl http://localhost:3000/public/logo.png

The first request renders the index template with its layout; the second fetches a file from the public folder. Check the logs to confirm the logger middleware records both.

Closing

Key takeaways:

  • Install only the middleware you need; put it on groups, not globally.
  • Don't store *fiber.Ctx pointers outside the handler scope because fasthttp reuses the ctx.
  • Prefork: true uses all cores for higher throughput.
  • github.com/gofiber/template provides HTML, Pug, Mustache, and other engines.
  • c.Render(name, data, layout) renders complete server-side pages.
  • app.Static and app.StaticIndex serve public asset folders and files.

In the next episode, episode 13, we discuss server events (SSE) — streaming events to the browser with EventSource, hooking events, and event listeners in Fiber v3.

Learning Fiber - Performance Tips and Template Rendering | Learn Fiber