Skip to main content

Fiber Framework: High-Performance Web Development

Created: May 8, 2026 5 min read

Introduction

Fiber is the fastest web framework for Go, inspired by Express.js. It’s designed for high-performance applications with minimal memory footprint. This guide covers building ultra-fast web applications with Fiber. See Go Installation Guide, Go Ecosystem Overview, Go Best Practices for more context.

Core Concepts

Why Fiber?

  • Speed: Fastest web framework for Go
  • Familiar API: Similar to Express.js
  • Low Memory: Minimal allocations
  • Middleware: Extensive middleware ecosystem
  • Validation: Built-in validation support

Good: Basic Fiber Setup

Creating a Fiber Application

package main

import (
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/logger"
	"github.com/gofiber/fiber/v2/middleware/recover"
)

// ✅ GOOD: Basic Fiber application
func main() {
	app := fiber.New()

	// Middleware
	app.Use(logger.New())
	app.Use(recover.New())

	// Routes
	app.Get("/", handleHome)
	app.Get("/users/:id", handleGetUser)
	app.Post("/users", handleCreateUser)

	// Start server
	app.Listen(":8080")
}

func handleHome(c *fiber.Ctx) error {
	return c.JSON(fiber.Map{
		"message": "Welcome to Fiber",
	})
}

func handleGetUser(c *fiber.Ctx) error {
	id := c.Params("id")
	return c.JSON(fiber.Map{
		"id": id,
	})
}

func handleCreateUser(c *fiber.Ctx) error {
	user := struct {
		Name  string `json:"name"`
		Email string `json:"email"`
	}{}

	if err := c.BodyParser(&user); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": err.Error(),
		})
	}

	return c.Status(fiber.StatusCreated).JSON(user)
}

Route Groups

package main

import (
	"github.com/gofiber/fiber/v2"
)

// ✅ GOOD: Route grouping in Fiber
func setupRoutes(app *fiber.App) {
	// API v1
	v1 := app.Group("/api/v1")
	{
		v1.Get("/health", handleHealth)
		v1.Get("/users", handleListUsers)
		v1.Post("/users", handleCreateUser)
	}

	// Protected routes
	protected := app.Group("/api/v1")
	protected.Use(authMiddleware())
	{
		protected.Get("/profile", handleProfile)
		protected.Put("/profile", handleUpdateProfile)
	}

	// Admin routes
	admin := app.Group("/admin")
	admin.Use(authMiddleware(), adminMiddleware())
	{
		admin.Get("/stats", handleStats)
		admin.Delete("/users/:id", handleDeleteUser)
	}
}

func handleHealth(c *fiber.Ctx) error {
	return c.JSON(fiber.Map{"status": "ok"})
}

func handleListUsers(c *fiber.Ctx) error {
	return c.JSON([]string{})
}

func handleCreateUser(c *fiber.Ctx) error {
	return c.Status(fiber.StatusCreated).JSON(fiber.Map{"created": true})
}

func handleProfile(c *fiber.Ctx) error {
	return c.JSON(fiber.Map{"profile": "data"})
}

func handleUpdateProfile(c *fiber.Ctx) error {
	return c.JSON(fiber.Map{"updated": true})
}

func handleStats(c *fiber.Ctx) error {
	return c.JSON(fiber.Map{"stats": "data"})
}

func handleDeleteUser(c *fiber.Ctx) error {
	return c.JSON(fiber.Map{"deleted": true})
}

func authMiddleware() fiber.Handler {
	return func(c *fiber.Ctx) error {
		token := c.Get("Authorization")
		if token == "" {
			return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
				"error": "Unauthorized",
			})
		}
		return c.Next()
	}
}

func adminMiddleware() fiber.Handler {
	return func(c *fiber.Ctx) error {
		// Check admin role
		return c.Next()
	}
}

Good: Middleware

Creating Fiber Middleware

package main

import (
	"github.com/gofiber/fiber/v2"
	"log"
	"time"
)

// ✅ GOOD: Logging middleware
func loggingMiddleware(c *fiber.Ctx) error {
	start := time.Now()

	err := c.Next()

	duration := time.Since(start)
	log.Printf("%s %s %d %v",
		c.Method(),
		c.Path(),
		c.Response().StatusCode(),
		duration,
	)

	return err
}

// ✅ GOOD: Rate limiting middleware
func rateLimitMiddleware(c *fiber.Ctx) error {
	// Implement rate limiting
	return c.Next()
}

// ✅ GOOD: CORS middleware
func corsMiddleware(c *fiber.Ctx) error {
	c.Set("Access-Control-Allow-Origin", "*")
	c.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
	c.Set("Access-Control-Allow-Headers", "Content-Type")

	if c.Method() == "OPTIONS" {
		return c.SendStatus(fiber.StatusNoContent)
	}

	return c.Next()
}

// ✅ GOOD: Error handling middleware
func errorHandlingMiddleware(c *fiber.Ctx) error {
	defer func() {
		if err := recover(); err != nil {
			log.Printf("Panic: %v", err)
			c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"error": "Internal server error",
			})
		}
	}()
	return c.Next()
}

Good: Request Handling

Binding and Validation

package main

import (
	"github.com/gofiber/fiber/v2"
)

// ✅ GOOD: Struct with validation tags
type User struct {
	Name  string `json:"name" validate:"required,min=3,max=50"`
	Email string `json:"email" validate:"required,email"`
	Age   int    `json:"age" validate:"min=0,max=150"`
}

// ✅ GOOD: Parse JSON body
func handleCreateUserWithValidation(c *fiber.Ctx) error {
	user := new(User)

	if err := c.BodyParser(user); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": "Invalid request",
		})
	}

	return c.Status(fiber.StatusCreated).JSON(user)
}

// ✅ GOOD: Extract query parameters
func handleSearch(c *fiber.Ctx) error {
	query := c.Query("q")
	limit := c.Query("limit", "10")

	return c.JSON(fiber.Map{
		"query": query,
		"limit": limit,
	})
}

// ✅ GOOD: Extract path parameters
func handleGetByID(c *fiber.Ctx) error {
	id := c.Params("id")
	return c.JSON(fiber.Map{
		"id": id,
	})
}

// ✅ GOOD: Set response headers
func handleWithHeaders(c *fiber.Ctx) error {
	c.Set("X-Custom-Header", "value")
	return c.JSON(fiber.Map{"message": "ok"})
}

// ✅ GOOD: Set cookies
func handleCookies(c *fiber.Ctx) error {
	c.Cookie(&fiber.Cookie{
		Name:     "session",
		Value:    "abc123",
		Expires:  time.Now().Add(24 * time.Hour),
		HTTPOnly: true,
	})
	return c.JSON(fiber.Map{"message": "cookie set"})
}

Advanced Patterns

Custom Error Handler

package main

import (
	"github.com/gofiber/fiber/v2"
)

// ✅ GOOD: Custom error handler
type ErrorResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Details string `json:"details,omitempty"`
}

func customErrorHandler(c *fiber.Ctx, err error) error {
	code := fiber.StatusInternalServerError
	message := "Internal server error"

	if e, ok := err.(*fiber.Error); ok {
		code = e.Code
		message = e.Message
	}

	return c.Status(code).JSON(ErrorResponse{
		Code:    code,
		Message: message,
	})
}

// ✅ GOOD: Using custom error handler
func setupErrorHandling(app *fiber.App) {
	app.Use(func(c *fiber.Ctx) error {
		return c.Next()
	})
}

File Upload

package main

import (
	"github.com/gofiber/fiber/v2"
)

// ✅ GOOD: Handle file upload
func handleFileUpload(c *fiber.Ctx) error {
	file, err := c.FormFile("file")
	if err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": "No file provided",
		})
	}

	// Save file
	if err := c.SaveFile(file, "./uploads/"+file.Filename); err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"error": "Upload failed",
		})
	}

	return c.JSON(fiber.Map{
		"filename": file.Filename,
		"size":     file.Size,
	})
}

Performance Optimization

Efficient Request Handling

package main

import (
	"github.com/gofiber/fiber/v2"
)

// ✅ GOOD: Reuse buffers for performance
func handleLargeResponse(c *fiber.Ctx) error {
	// Fiber automatically manages buffers efficiently
	return c.JSON(fiber.Map{
		"data": "large response",
	})
}

// ✅ GOOD: Stream large files
func handleStreamFile(c *fiber.Ctx) error {
	return c.SendFile("./large-file.bin")
}

// ✅ GOOD: Use connection pooling
func setupDatabase(app *fiber.App) {
	// Configure connection pooling
}

Best Practices

1. Use Middleware for Cross-Cutting Concerns

// ✅ GOOD: Middleware for logging, auth, etc.
app.Use(loggingMiddleware)
app.Use(authMiddleware())

// ❌ BAD: Repeating logic in handlers
func handler(c *fiber.Ctx) error {
	// Log
	// Check auth
	// Do work
}

2. Validate Input

// ✅ GOOD: Use validation tags
type Request struct {
	Email string `json:"email" validate:"required,email"`
	Age   int    `json:"age" validate:"min=0,max=150"`
}

// ❌ BAD: Manual validation
type BadRequest struct {
	Email string
	Age   int
}

3. Handle Errors Consistently

// ✅ GOOD: Consistent error responses
return c.Status(fiber.StatusBadRequest).JSON(ErrorResponse{
	Code:    fiber.StatusBadRequest,
	Message: "Invalid input",
})

// ❌ BAD: Inconsistent error handling
return c.SendString("Error")

Resources

Summary

Fiber is the fastest web framework for Go, perfect for high-performance applications. Use route groups for organization, middleware for cross-cutting concerns, and proper validation for robust applications. Fiber’s speed and low memory footprint make it ideal for building scalable web services.

Comments

Share this article

Scan to read on mobile