Featured Article

ANPR/ALPR: A Cloud-Native License Plate Recognition SaaS Platform

A deep dive into building a production ready Automatic Number Plate Recognition (ANPR) SaaS platform. Learn how to leverage Go, PaddleDetection, and PostgreSQL to create a scalable solution for parking operators, access control, and fleet management.

Henok Wehibe
#Go #Computer Vision #SaaS #PaddlePaddle #PostgreSQL #Docker #ANPR #Python
~8 min read

View Source Code

Introduction

Cloud native, subscription-based platform that brings enterprise grade license plate recognition to everyone. By combining the performance of Go with the flexibility of SaaS, deliver a robust, compliant, and easy to deploy solution that grows with your business.

Traditional ANPR systems come with significant pain points:

Challenge Traditional Solutions MicroANPR Approach
High upfront costs £100,000+ hardware + software licenses Pay-as-you-go subscription
Complex installation Weeks of on-site setup Deploy in minutes
Vendor lock-in Proprietary formats Open APIs, export anytime
Limited scalability Buy new hardware Scale instantly in the cloud
️ Maintenance burden On-site IT support required Managed updates, zero downtime

⚡ The Stack: Go + PaddleDetection

The Go Backend Advantage

I chose Go for the core platform for several reasons:

// Concurrent processing of multiple camera streams
g := errgroup.Group{}

// HTTP server for plate detection API (port 8080)
g.Go(func() error {
    return http.ListenAndServe(":8080", alprdRouter)
})

// HTTPS server for web dashboard (port 5000)
g.Go(func() error {
    return http.ListenAndServe(":5000", router)
})

Performance Benefits:

Go Feature Performance Impact
Goroutines Handle thousands of concurrent camera connections
Low memory footprint Runs efficiently on minimal cloud instances
Fast compilation Rapid deployment cycles

PaddleDetection for UK Plates

For the actual plate recognition, I integrated PaddlePaddle’s detection pipeline, specifically tuned for UK license plates:

# UK plate format validation
standard_formats = [
    r'^[A-Z]{2}[0-9]{2}\s?[A-Z]{3}$',  # AB12 CDE (post-2001)
    r'^[A-Z][0-9]{1,3}\s?[A-Z]{3}$',    # M123 ABC (prefix)
    r'^[A-Z]{3}\s?[0-9]{1,3}[A-Z]$',    # ABC 123D (suffix)
]

The system achieves 97%+ accuracy on standard UK plates, supporting all major formats:

Supported Format Example
🆕 Post-2001 AB12 CDE
⏮️ Prefix Style A123 ABC
⏭️ Suffix Style ABC 123A
🏛️ Dateless 1 ABC
🌍 International EU & Middle East Support

️ Cloud-Native SaaS Architecture

Multi-Tenant Design

The platform is built from the ground up as a multi-tenant SaaS:

Architecture Diagram

Multi-Tenant Cloud Platform
🅿️
Tenant A
Parking Operator
🏠
Tenant B
Gated Community
🚛
Tenant C
Fleet Manager
🛒
Tenant D
Retail Car Park
API Gateway
Go + Gin Framework
👁️
Plate Detector
PaddleDetection
🗄️
Database
PostgreSQL
💾
Media Storage
Object Store

Key SaaS Features

📡

Real-Time Streaming Dashboard

Server-Sent Events (SSE) for instant updates

// HandleStream manages Server-Sent Events (SSE) connections for real-time plate detection updates
// This allows the dashboard to receive instant notifications when a new plate is detected
// without polling or WebSocket overhead
func (h *StreamHandler) HandleStream(c *gin.Context) {
  // Configure response headers for SSE protocol
  c.Writer.Header().Set("Content-Type", "text/event-stream")  // Tell browser this is an event stream
  c.Writer.Header().Set("Cache-Control", "no-cache")          // Prevent caching of events
  c.Writer.Header().Set("Connection", "keep-alive")           // Maintain persistent connection
  
  // Stream creates a long-lived HTTP connection that pushes events to the client
  c.Stream(func(w io.Writer) bool {
    // Listen for new plate detections on the client-specific channel
    if msg, ok := <-clientChan; ok {
      // Send the plate detection data (format: "plate|uuid")
      // The uuid can be used to fetch the full plate image and metadata
      c.SSEvent("message", msg)
      return true  // Keep connection alive for more events
    }
    return false  // Close connection if channel is closed
  })
}
🛡️

Group-Based Access Control

Granular permissions for parking management

Flexible Data Export

Full data ownership with no vendor lock-in

CSV / Excel
Spreadsheet analysis
PDF Reports
Professional documentation
SQL Dump
Full database migration
JSON API
Programmatic access

Built-In Tariff Calculator

Integrated fee calculation engine

Flexible Deployment Options

Choose the deployment model that fits your infrastructure, compliance, and budget requirements from fully managed cloud to complete on-premise control.

POPULAR
☁️

Fully Managed (SaaS)

Zero infrastructure overhead.

🏢

Self-Hosted License

Full control for strict data residency.

Hybrid Deployment

Edge processing on-site with cloud.

On-Premise
📹
Camera + Edge
Local Detection
HTTPS / TLS
Cloud
☁️
MicroANPR Cloud
API & Dashboard

API-First Design

Every feature is accessible via REST API, enabling seamless integrations with your existing systems.

Quick Start

Upload a video and detect plates

# Detect plate from video upload
curl -X POST -F "file=@parking-entry.mp4" \
  https://api.MicroANPR.io/v1/upload \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response
{
  "job_id": "abc123",
  "status": "processing",
  "webhook_url": "https://your-app.com/webhook"
}
{
  "event": "plate.detected",
  "timestamp": "2025-12-06T14:30:00Z",
  "data": {
    "plate": "AB12 CDE",
    "confidence": 0.98,
    "image_url": "https://api.MicroANPR.io/images/uuid.jpg",
    "camera_id": "entrance-1",
    "group_match": {
      "group": "Staff Parking",
      "member": "John Smith",
      "permit_id": "STAFF001"
    }
  }
}

Real-World Use Cases

MicroANPR powers a variety of applications across different industries.

🅿️

Parking Management

  • Automatic barrier control
  • Permit validation
  • Overstay detection
  • Revenue tracking
🏠

Gated Communities

  • Resident/visitor recognition
  • Delivery vehicle logging
  • Security alerts for unknown plates
  • Guest pre-registration
🚛

Fleet Management

  • Vehicle check-in/check-out
  • Mileage tracking
  • Unauthorized usage alerts
  • Maintenance scheduling
🛒

Retail & Shopping Centres

  • Loyalty program integration
  • VIP customer recognition
  • Parking duration analytics
  • Peak time reporting

Complete Technical Stack

Component Technology Why
Backend Go + Gin Performance, concurrency
Database PostgreSQL Reliability, JSON support
Detection PaddleDetection Accuracy, CPU-friendly
OCR PaddleOCR UK plate optimization
Frontend Nextjs Full-stack React, SEO-friendly
Deployment Docker + Ansible Reproducible, scalable
CDN Cloudflare Global edge caching

Roadmap & Future

Upcoming features and enhancements planned for MicroANPR.

Mobile App
iOS/Android monitoring
Edge Devices
Raspberry Pi & Jetson
Multi-Language Plates
EU & Asian formats
AI Analytics
Traffic predictions
Stripe Integration
Self-service billing
SSO Support
SAML & OAuth

The best enterprise solutions don't have to be complex or expensive. By combining Go's performance with modern AI/ML capabilities and wrapping it in a user-friendly subscription model, we can make enterprise-grade technology accessible to businesses of all sizes.

Whether you're managing a 10-space car park or a multi-site enterprise operation, MicroANPR scales with your needs and you only pay for what you use.


Have questions about ANPR systems or building SaaS products? Feel free to reach out or check out my other articles on computer vision and infrastructure automation.