Skip to content

V3DxNT/GoShort

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GoShort πŸš€

A high-performance URL shortening service built with Go, PostgreSQL, and Redis. GoShort converts long URLs into compact, memorable short links while maintaining fast redirects through intelligent caching.

Table of Contents

Features

✨ Key Features:

  • URL Shortening: Convert long URLs into compact, base62-encoded short links
  • Redis Caching: Lightning-fast redirects with in-memory caching layer
  • PostgreSQL Storage: Persistent, reliable storage for all shortened URLs
  • Health Checks: Built-in health endpoint for monitoring
  • Efficient Encoding: Uses base62 encoding for human-readable short codes
  • Automatic Cache Population: Smart caching strategy that learns from access patterns

Architecture

GoShort follows a layered architecture pattern:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         HTTP Request Handler            β”‚
β”‚    (Standard Go http.ServeMux)          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚                β”‚
   β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”      β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
   β”‚ Routes β”‚      β”‚ Handlers   β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
           β”‚           β”‚           β”‚
      β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”   β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”  β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”
      β”‚ Redis β”‚   β”‚ Models β”‚  β”‚Config  β”‚
      β”‚ Cache β”‚   β”‚        β”‚  β”‚ (DB)   β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
      β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
      β”‚  PostgreSQL DB   β”‚
      β”‚  (Long-term      β”‚
      β”‚   storage)       β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Project Structure

GoShort/
β”œβ”€β”€ cmd/
β”‚   └── main.go                 # Application entry point
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ postgre.go          # PostgreSQL connection & initialization
β”‚   β”‚   └── redis.go            # Redis connection & initialization
β”‚   β”œβ”€β”€ handlers/
β”‚   β”‚   └── routeHandlers.go    # HTTP request handlers (shorten & redirect)
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── model.go            # Data models (currently minimal)
β”‚   └── routes/
β”‚       └── routes.go           # Route definitions & multiplexing
β”œβ”€β”€ pkg/
β”‚   └── utils/
β”‚       └── base62.go           # Base62 encoding utility
└── go.mod                      # Go module definition & dependencies

Directory Explanation

  • cmd/: Contains the application entry point (main.go) that initializes the server
  • internal/: Private packages used only within this application
    • config/: Database and cache connection management
    • handlers/: Business logic for handling HTTP requests
    • models/: Data structures and models
    • routes/: Route registration and request multiplexing
  • pkg/: Reusable packages that could potentially be imported by other projects
    • utils/: Helper functions (base62 encoding)

Tech Stack

Technology Version Purpose
Go 1.26.2 Core language
PostgreSQL Via lib/pq Primary data storage
Redis Via go-redis/v9 Caching layer
godotenv 1.5.1 Environment variable management
xxhash 2.3.0 Fast hashing (indirect dependency)

Dependencies

github.com/joho/godotenv v1.5.1    // Load .env files for configuration
github.com/lib/pq v1.12.3          // PostgreSQL driver
github.com/redis/go-redis/v9 v9.19.0 // Redis client library

Setup & Installation

Prerequisites

  • Go 1.26.2 or higher
  • PostgreSQL database instance
  • Redis instance (local or cloud-based like Upstash)

Step 1: Clone & Install

git clone https://github.com/V3DxNT/GoShort.git
cd GoShort
go mod download

Step 2: Database Setup

Create a PostgreSQL database with the following schema:

CREATE TABLE urls (
    id SERIAL PRIMARY KEY,
    long_url VARCHAR(2048) NOT NULL,
    short_code VARCHAR(20) UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Optional: Create an index on short_code for faster lookups
CREATE INDEX idx_short_code ON urls(short_code);

Step 3: Environment Configuration

Create a .env file in the root directory:

# PostgreSQL Configuration
DATABASE_URL=postgresql://username:password@localhost:5432/goshort

# Redis Configuration
REDIS_URL=redis://default:password@host:port

# Server Configuration
PORT=7777

Step 4: Run the Application

go run cmd/main.go

The server will start on the specified PORT (default: 7777) and output:

Connected to DB
Connected to Redis
Listening on port 7777

Configuration

Environment Variables

Variable Description Default Required
DATABASE_URL PostgreSQL connection string - βœ… Yes
REDIS_URL Redis connection URL - βœ… Yes
PORT Server port 7777 ❌ No

Connection Details

PostgreSQL (postgre.go):

  • Uses standard Go database/sql package with pq driver
  • sql.Open() initializes the connection pool (doesn't connect immediately)
  • DB.Ping() performs actual TCP connection verification
  • Supports any PostgreSQL instance (local, remote, cloud-hosted)

Redis (redis.go):

  • Connects via URL parsing (supports Upstash or self-hosted Redis)
  • No localhost fallback - requires explicit Redis URL
  • Uses context for connection lifecycle management
  • Implements PING for connection verification

API Endpoints

1. Create Short URL

Endpoint: POST /api/shorten

Request:

{
  "url": "https://example.com/very/long/url/that/is/hard/to/remember"
}

Response (Success 200):

{
  "url": "https://localhost:7777/abc123"
}

Response (Error 400):

Bad Request - Invalid JSON format

Response (Error 500):

Internal Server Error - Database issue

2. Redirect to Original URL

Endpoint: GET /{short_code}

Behavior:

  1. Checks Redis cache first (instant, if available)
  2. Falls back to PostgreSQL if not cached
  3. Caches result in Redis for future requests
  4. Redirects (HTTP 302) to original long URL

Example:

  • Request: GET /abc123
  • Response: HTTP 302 redirect to https://example.com/very/long/url/...

3. Health Check

Endpoint: GET /health

Response (200):

GoShort IS LIVE

4. Root Endpoint

Endpoint: GET /

Response:

πŸš€ GoShort IS LIVE & READY!

How It Works

URL Shortening Flow

1. User sends POST /api/shorten with long URL
        ↓
2. Handler receives and validates JSON
        ↓
3. Insert long_url into PostgreSQL β†’ returns auto-generated ID
        ↓
4. Encode ID using Base62 algorithm β†’ generates short_code
        ↓
5. Update URL record with short_code in PostgreSQL
        ↓
6. Cache short_code β†’ long_url mapping in Redis
        ↓
7. Return shortened URL to user

Redirect Flow

1. User requests GET /{short_code}
        ↓
2. Check Redis cache for short_code
        β”œβ”€ HIT: Redirect immediately (fast path)
        β”œβ”€ MISS: Query PostgreSQL
        β”‚        β”œβ”€ FOUND: Cache result + redirect
        β”‚        └─ NOT FOUND: Return 404
        └─ ERROR: Return 500 Redis error

Base62 Encoding

The Base62Encode() function converts database IDs into human-readable short codes:

Algorithm:

  1. Takes unsigned 64-bit integer (database ID)
  2. Iteratively divides by 62, collecting remainders
  3. Maps remainders to alphabet: [a-z][A-Z][0-9]
  4. Reverses the result to get final short code

Example:

  • ID: 12345 β†’ Short Code: "3kd"
  • ID: 1000000 β†’ Short Code: "4c92"

Advantages:

  • Compact representation (62 possible characters)
  • Deterministic & reversible
  • No external API calls needed
  • Human-readable (includes letters and numbers)

Core Components

cmd/main.go

Responsibilities:

  • Load environment variables from .env
  • Initialize PostgreSQL connection
  • Initialize Redis connection
  • Create HTTP request multiplexer
  • Register all routes
  • Start HTTP server on configured port

Key Functions:

func main()
  └─ godotenv.Load()       // Load .env configuration
  └─ config.ConnectDb()    // Connect to PostgreSQL
  └─ config.ConnectRedis() // Connect to Redis
  └─ routes.HandleRoutes() // Register API routes
  └─ http.ListenAndServe() // Start server

internal/handlers/routeHandlers.go

Contains:

  • URLRequest: Struct for incoming POST requests
  • CreateShortURL(): Handler for POST /api/shorten
  • RedirectURL(): Handler for GET /{short_code} and GET /

CreateShortURL Process:

  1. Decode JSON request body
  2. Insert long_url into database (auto-generate ID)
  3. Encode ID using Base62
  4. Update database with short_code
  5. Cache mapping in Redis
  6. Return shortened URL

RedirectURL Process:

  1. Extract short_code from URL path
  2. Try Redis cache first
  3. Fall back to database query
  4. Cache result if found
  5. Redirect or return error

internal/config/postgre.go

Global Variable:

var DB *sql.DB  // Connection pool

Function: ConnectDb()

  • Reads DATABASE_URL environment variable
  • Opens PostgreSQL connection pool with sql.Open()
  • Performs actual connection with DB.Ping()
  • Panics if connection fails

Key Concepts:

  • sql.Open() doesn't establish a connection, just initializes the pool
  • DB.Ping() performs actual TCP socket connection over the network
  • Supports localhost or remote PostgreSQL instances

internal/config/redis.go

Global Variable:

var Cache *redis.Client  // Redis connection

Function: ConnectRedis()

  • Reads REDIS_URL environment variable
  • Parses URL to extract connection parameters
  • Creates Redis client instance
  • Verifies connection with Ping()
  • Panics if connection fails

Important Notes:

  • No localhost fallback - must provide valid REDIS_URL
  • Designed for cloud Redis services (like Upstash)
  • Uses context.Background() for connection management
  • Context is Go's way of managing lifespans and cancellation signals

internal/routes/routes.go

Function: HandleRoutes()

  • Registers HTTP route handlers with multiplexer
  • Routes:
    • POST /api/shorten β†’ handlers.CreateShortURL
    • GET / β†’ handlers.RedirectURL

pkg/utils/base62.go

Function: Base62Encode(num uint64) string

Algorithm:

Input: 12345 (uint64)
       ↓
Alphabet: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
       ↓
Iterative Division by 62:
  12345 % 62 = 35 β†’ 'z'
  199 % 62 = 13 β†’ 'n'
  3 % 62 = 3 β†’ 'd'
       ↓
Reverse: ['z','n','d'] β†’ "dnz"
       ↓
Output: "dnz"

Performance Considerations

Caching Strategy

  • Redis TTL: Set to 0 (never expires) for persistent caching
  • Cache Population: Automatic on first access to any URL
  • Cache Hit Rate: Improves with repeated access patterns

Database Optimization

  • Add index on short_code column for O(1) lookups
  • Consider partitioning for massive scale (millions of URLs)

Scalability

  • Stateless handlers allow horizontal scaling
  • Database becomes bottleneck at scale (sharding recommended)
  • Redis cluster mode for distributed caching

Future Enhancements

Potential improvements for production deployment:

  • URL validation before shortening
  • Custom short code support
  • Analytics (click tracking, timestamps)
  • API authentication & rate limiting
  • URL expiration TTL
  • Bulk URL shortening
  • QR code generation
  • Link preview metadata
  • Admin dashboard
  • Prometheus metrics integration

Author

V3DxNT - GitHub Profile

License

This project is open source. Modify and use as needed.


Quick Reference

Task Command
Download dependencies go mod download
Run application go run cmd/main.go
Build binary go build -o goshort cmd/main.go
Check dependencies go mod graph

Last Updated: June 2026 Status: βœ… Active Development

About

A high-performance URL shortener built with Go, featuring a distributed architecture using PostgreSQL for persistence and Redis for O(1) redirect speeds. Built to demonstrate system design principles, custom Base62 encoding, and cloud-native infrastructure.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages