A high-performance, containerized REST API for AI-based image upscaling using Real-ESRGAN (ncnn-vulkan).
I wrote this "upscale service" to handle huge images (e.g., 10,000x10,000 pixels) that require significant compute power to upscale even further.
This server is not primarily meant for small images; there are plenty of existing tools for that. The goal is to utilize a high-powered server (GPU) to process massive files asynchronously without blocking the client.
The Workflow:
- Upload a massive file to the server.
- Poll the status endpoint while the server processes the job.
- Retrieve the final image once processing is complete.
- AI Upscaling: High-quality 2x, 3x, and 4x image upscaling.
- Models: Includes
realesrgan-x4plus,realesrgan-x4plus-anime, andrealesr-animevideov3. - Performance: Optimized for GPU (Vulkan) with CPU fallback.
- API: Modern, asynchronous REST API with job tracking and swagger documentation.
- Production Ready: Docker support, health checks, metrics, and rate limiting.
- Linux/macOS (Windows requires WSL2)
- Go 1.24+ (for building locally)
- Task (recommended) or Make
- Docker & Docker Compose (optional, for containerized deployment)
- Vulkan Driver (optional, for GPU acceleration)
git clone <repository-url>
cd mlcupscaleThis step is required for both local and Docker usage. It downloads the Real-ESRGAN models and the realesrgan-ncnn-vulkan binary from the upstream repository.
Note on the Binary:
The default setup uses pre-compiled binaries for convenience. If you need to build realesrgan-ncnn-vulkan from source (e.g., for optimized Vulkan shaders, specific hardware support, or non-standard architectures), please follow the Real-ESRGAN Build Instructions. After building, place your custom executable in the bin/ directory (or bin/ inside the app bundle for macOS).
Using Task:
task download-modelsUsing Make:
make modelsBuild and start the server:
Using Task:
task runUsing Make:
make runThe server will start at http://localhost:8089.
The included deployments/docker/Dockerfile builds a production-ready container image.
Build and run using Docker Compose:
make docker-runTo stop the service:
make docker-stopNote on GPU Support in Docker: Running this application in Docker with GPU acceleration requires the specific GPU runtime drivers for your hardware (e.g., NVIDIA Container Toolkit). Without mounting the GPU and proper drivers, the application will fall back to CPU processing, which is significantly slower. The default Dockerfile does not include proprietary driver layers.
If you have SSH access to a macOS machine (e.g., Apple Silicon), you can build a native .app and .dmg remotely.
Prerequisites on the Mac:
- Go 1.24+ installed
real-esrgan-ncnn-vulkanbinary available (downloaded by the build script)
Command:
# Deploys code to Mac, builds App/DMG, and downloads artifacts back to ./build/macos
task macos:buildYou can also run the service remotely on the Mac:
# Sync and run
task macos:start
# View logs
task macos:logs
# Stop service
task macos:stopThe API is fully documented with OpenAPI/Swagger. Once the server is running, visit http://localhost:8089/api/v1/docs for the interactive UI.
Documentation resources:
- API User Guide: Detailed endpoint documentation and examples.
- OpenAPI Specification: Raw Swagger/OpenAPI definition.
- Swagger UI HTML: Standalone Swagger UI viewer.
# 1. Submit Job
curl -X POST http://localhost:8089/api/v1/upscale \
-F "image=@photo.jpg" \
-F "scale=4" \
-F "model_name=realesrgan-x4plus"
# Response: {"success": true, "job_id": "123...", ...}
# 2. Check Status
curl http://localhost:8089/api/v1/status/123...
# 3. Download (when status is "completed")
curl -O http://localhost:8089/api/v1/download/123...curl http://localhost:8089/api/v1/modelsThe project includes a CLI client for easy interaction with the API.
make build-client
./build/upscale-client -input image.jpg -output upscaled.png -scale 4Configuration is managed via config/config.yaml. Key settings include:
- Server: Port, timeouts.
- Security (Production):
auth_token: Set a strong string here to enable Bearer Token authentication.api_prefix: Adjust the global API prefix (default:/api/v1). Useful when running behind reverse proxies like Traefik (e.g., set to/upscaler/v1).
- Upscaler: GPU enable/disable, thread count, model path.
- Storage: Upload/output directories, cleanup policies.
- Limits: Concurrency, queue size.
For Docker, see config/config.docker.yaml.
cmd/: Entry points for server and client.internal/: Core logic (API handlers, upscaler, storage).deployments/: Docker configurations.models/: AI models (downloaded viamake models).bin/: External binaries (ncnn-vulkan).data/: Storage for uploads and output images.
MIT License - Copyright (c) 2026 Michael Lechner