Skip to content

A fast L7 reverse proxy with in memory LRU caching, TCP & HTTP health checks and custom proxy implementation of net/http/httputil.

License

Notifications You must be signed in to change notification settings

kunalvirwal/minato

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Minato 🌊

Minato is a high-performance, feature-rich reverse proxy and load balancer written in Go with in-memory caching and hot configuration reloads

Go Version License :MIT Race Detection

Features

  • High-speed load balancing with path and domain-based routing
  • In-memory LRU caching with absolute TTL eviction
  • Health monitoring of upstream backend servers with automatic Failover and Recovery
  • HTTP cache-control header support (max-age, no-store, no-cache)
  • Thread-safe design with no locks in hot request path to upstreams
  • A complete custom implementation for net/http/httputil.ReverseProxy
  • Streaming-safe response handling (SSE/chunked)
  • Hot-reloadable runtime configuration using SIGHUP and reuse of state for optimising GC pressure

Minato behaves like a tiny CDN layer embedded into your infrastructure.

Load Balancing Algorithms

  • Round Robin - Evenly distribute requests across healthy backends
  • Least Connections - Route to backend with fewest active connections

Health Monitoring

  • Dual-Layer Checks - Fast TCP check followed by HTTP endpoint verification
  • Automatic Failover - Unhealthy backends automatically removed from rotation
  • Recovery Detection - Backends automatically restored when healthy
  • Configurable Endpoints - Per-backend health check URIs

In-Memory Caching

  • LRU Cache - Scratch implementation of LRU using Go maps and doubly linked lists
  • Absolute TTL - TTL based LRU eviction which respects cache-control headers
  • HTTP Cache-Control Aware - Respects max-age, no-cache, and no-store directives
  • Size-Limited - Configurable capacity and max response body size prevents memory exhaustion

πŸ“‹ Table of Contents

⚑ Quick Start

  1. Clone the repository

    git clone https://github.com/kunalvirwal/minato.git
    cd minato
  2. Configure your services (edit config.yaml)

    services:
        - name: "my-service"
          listen_port: 80
          balancer: "RoundRobin"
          hosts:
              - "http://example.com/"
          upstreams:
              - host: "http://localhost:8001"
                health_uri: "/health"
              - host: "http://localhost:8002"
                health_uri: "/health"
  3. Run Minato

    sudo go run ./cmd

    Or build and run

    go build -o minato ./cmd
    sudo ./minato
    
  4. Test it

    curl -H "Host: example.com" http://localhost/

πŸ“¦ Installation

Prerequisites

  • Go 1.21+
  • Root/sudo privileges - Required for binding to ports < 1024

From Source

# Clone repository
git clone https://github.com/kunalvirwal/minato.git
cd minato

# Install dependencies
go mod download

# Build binary
go build -o minato ./cmd

# Run
sudo ./minato

βš™οΈ Configuration

Configuration is managed through config.yaml in the root directory.

Configuration File Structure

# Cache Configuration (Optional)
cache:
    enabled: true # Enable/disable response caching
    max_body_size: 1048576 # Max cacheable response size (1MB)
    capacity: 100 # Number of global cache entries
    type: "LRU" # Cache eviction policy: "LRU"
    ttl: 300 # Time-to-live in seconds

# Service Definitions (Required)
services:
    - name: "service-name" # Unique service identifier
      listen_port: 80 # Port to listen on
      balancer: "RoundRobin" # Load balancing algorithm

      # Domains/paths this service handles
      hosts:
          - "http://example.com/"
          - "http://example.com/api"

      # Backend servers
      upstreams:
          - host: "http://backend1:8000"
            health_uri: "/health"
          - host: "http://backend2:8000"
            health_uri: "/health"

Configuration Options

Cache Settings

Option Type Description
enabled bool Enable response caching
max_body_size int Maximum response body size to cache (bytes)
capacity int Maximum number of cached responses
type string Cache eviction policy (LRU or LFU)
ttl int Cache entry time-to-live (seconds)

Service Settings

Option Type Required Description
name string βœ… Unique service identifier
listen_port int βœ… Port number to listen on
balancer string βœ… Load balancing algorithm (RoundRobin)
hosts array βœ… List of domain/path combinations to route
upstreams array βœ… Backend server configurations

Upstream Settings

Option Type Required Description
host string βœ… Backend server URL (with protocol)
health_uri string βœ… Health check endpoint path

Note : The Upstream[Host] field and Service[hosts] fields allows path to be a part of URLs. So for inbound hosts the largest matching path prefix will be given priority.

Hot Reload Configuration

Update config.yaml and send a SIGHUP signal:

# Find the process ID
sudo ps aux | grep minato

# Send reload signal
sudo kill -1 <PID>

What happens during reload:

  • βœ… New configuration is validated
  • βœ… New backend servers are added
  • βœ… Older unused backend servers are cleaned up
  • βœ… Existing connections continue uninterrupted
  • βœ… New listeners start on new ports
  • βœ… Old listeners on removed ports shut down gracefully
  • βœ… A fresh cache instance replaces the old one.

πŸ—οΈ Project Structure

minato/
β”œβ”€β”€ cmd/
β”‚   β”œβ”€β”€ main.go           # Entry point, signal handling
β”‚   └── helper.go         # Config building, cleanup
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ backend/          # Backend server abstraction
β”‚   β”œβ”€β”€ balancer/         # Load balancing algorithms
β”‚   β”œβ”€β”€ cache/            # Response caching (LRU)
β”‚   β”œβ”€β”€ config/           # YAML config parsing and global config generation
β”‚   β”œβ”€β”€ healthcheck/      # Health monitoring
β”‚   β”œβ”€β”€ proxy/            # Reverse proxy implementation
β”‚   β”œβ”€β”€ state/            # Global state management and Runtime resource management
β”‚   └── utils/            # Logging utilities
β”œβ”€β”€ Readme_Assets/        # Documentation assets
β”œβ”€β”€ config.yaml           # Main configuration file
β”œβ”€β”€ go.mod
└── README.md

⚑ Performance Benchmarks with Caching

Cache-NoCache

The benchmark above demonstrates the performance impact of enabling in-memory caching. Testing was conducted with 10,000 requests distributed across 125 concurrent connections to two nginx backend upstreams.

Key Results:

Metric Without Cache With Cache Improvement
Average Latency 8.33ms 1.88ms 4.4x faster
Requests/Second 14,951.71 65,712.20 4.4x throughput

Caching reduced max latency by 35% and increased throughput by 4.4x, making it highly effective for serving cacheable content at scale.

🀝 Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Guidelines

  • βœ… Run go fmt before committing
  • βœ… Test with -race flag
  • βœ… Update documentation for new features
  • βœ… Add comments for exported functions
  • βœ… Keep hot path lock-free

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

About

A fast L7 reverse proxy with in memory LRU caching, TCP & HTTP health checks and custom proxy implementation of net/http/httputil.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages