Why Go for a European Video Platform
ViralVidVault serves trending video content from 7 European regions. When we needed an API that handles spiky traffic (a viral video in Poland can drive sudden request surges), Go's efficient concurrency model and small memory footprint made it the clear choice.
Server Architecture
package main
import (
"context"
"encoding/json"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
type Video struct {
VideoID string `json:"video_id"`
Title string `json:"title"`
Channel string `json:"channel_title"`
Views int64 `json:"views"`
Likes int64 `json:"likes"`
Thumbnail string `json:"thumbnail_url"`
Regions []string `json:"regions"`
Language string `json:"content_language"`
Engagement float64 `json:"engagement_rate"`
}
type APIServer struct {
pool *pgxpool.Pool
router *http.ServeMux
cache *RegionCache
}
var validRegions = map[string]string{
"US": "United States", "GB": "United Kingdom",
"PL": "Poland", "NL": "Netherlands",
"SE": "Sweden", "NO": "Norway", "AT": "Austria",
}
func NewAPIServer(pool *pgxpool.Pool) *APIServer {
s := &APIServer{
pool: pool,
router: http.NewServeMux(),
cache: NewRegionCache(3 * time.Hour),
}
s.routes()
return s
}
func (s *APIServer) routes() {
s.router.HandleFunc("GET /api/trending/{region}", s.handleTrending)
s.router.HandleFunc("GET /api/search", s.handleSearch)
s.router.HandleFunc("GET /api/regions", s.handleRegions)
s.router.HandleFunc("GET /health", s.handleHealth)
}
Connection Pooling with pgx
pgx is the fastest PostgreSQL driver for Go. Its connection pool handles concurrent requests efficiently:
func initDB() (*pgxpool.Pool, error) {
config, err := pgxpool.ParseConfig(os.Getenv("DATABASE_URL"))
if err != nil {
return nil, err
}
config.MaxConns = 20
config.MinConns = 5
config.MaxConnLifetime = 30 * time.Minute
config.MaxConnIdleTime = 5 * time.Minute
pool, err := pgxpool.NewWithConfig(context.Background(), config)
if err != nil {
return nil, err
}
if err := pool.Ping(context.Background()); err != nil {
return nil, err
}
return pool, nil
}
20 max connections handles substantial concurrent load. Each goroutine borrows a connection, runs the query, and returns it. No connection leaks, no manual management.
Request Handlers
func (s *APIServer) handleTrending(w http.ResponseWriter, r *http.Request) {
region := r.PathValue("region")
if _, ok := validRegions[region]; !ok {
writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid region"})
return
}
// Check cache first
if cached, ok := s.cache.Get(region); ok {
w.Header().Set("X-Cache", "HIT")
writeJSON(w, http.StatusOK, cached)
return
}
rows, err := s.pool.Query(r.Context(), `
SELECT v.video_id, v.title, v.channel_title, v.views, v.likes,
v.thumbnail_url, array_agg(DISTINCT vr.region) as regions
FROM videos v
JOIN video_regions vr ON v.video_id = vr.video_id
WHERE vr.region = $1
GROUP BY v.video_id, v.title, v.channel_title, v.views, v.likes, v.thumbnail_url
ORDER BY v.views DESC
LIMIT 25
`, region)
if err != nil {
log.Printf("trending query error: %v", err)
writeJSON(w, http.StatusInternalServerError, map[string]string{"error": "database error"})
return
}
defer rows.Close()
var videos []Video
for rows.Next() {
var v Video
if err := rows.Scan(&v.VideoID, &v.Title, &v.Channel,
&v.Views, &v.Likes, &v.Thumbnail, &v.Regions); err != nil {
continue
}
if v.Views > 0 {
v.Engagement = float64(v.Likes) / float64(v.Views) * 100
}
videos = append(videos, v)
}
response := map[string]any{
"region": region,
"region_name": validRegions[region],
"videos": videos,
"total": len(videos),
}
s.cache.Set(region, response)
w.Header().Set("X-Cache", "MISS")
writeJSON(w, http.StatusOK, response)
}
func writeJSON(w http.ResponseWriter, status int, data any) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Cache-Control", "public, max-age=3600")
w.WriteHeader(status)
json.NewEncoder(w).Encode(data)
}
Middleware Stack
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
sw := &statusWriter{ResponseWriter: w, status: 200}
next.ServeHTTP(sw, r)
log.Printf("%s %s %d %v", r.Method, r.URL.Path, sw.status, time.Since(start))
})
}
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "https://viralvidvault.com")
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
if r.Method == "OPTIONS" {
w.WriteHeader(204)
return
}
next.ServeHTTP(w, r)
})
}
type statusWriter struct {
http.ResponseWriter
status int
}
func (w *statusWriter) WriteHeader(code int) {
w.status = code
w.ResponseWriter.WriteHeader(code)
}
Benchmarks
Serving trending feeds for ViralVidVault's 7 regions:
wrk -t4 -c100 -d30s http://localhost:8080/api/trending/PL
Requests/sec: 14,200 (cache hit)
Requests/sec: 3,800 (cache miss, DB query)
P99 Latency: 8ms (cache hit) / 15ms (cache miss)
Memory: 22MB
Binary size: 9MB
The cache hit rate in production is above 85%, meaning the vast majority of requests never touch PostgreSQL. For a platform serving European viral content with predictable update cycles, this architecture handles traffic spikes effortlessly.
This article is part of the Building ViralVidVault series. Check out ViralVidVault to see these techniques in action.
Top comments (0)