← projects
$ Image Service — Java & Go
Production-grade image processing service written in both Java and Go. The same functionality was implemented in both languages — the Go version is significantly more efficient in terms of memory management.
- →The service was written in both Java (Spring Boot) and Go. One of the core advantages of microservice architecture is the ability to write each service in the most suitable language for its needs. For memory-intensive operations like image processing, Go's low overhead and deterministic memory management offer a clear advantage over Java.
- →In the Java version, a Semaphore-based concurrency control limits processing to a maximum of 5 concurrent operations. The semaphore acquire timeout is configured to 30 seconds. This allows the system to process images sequentially under high load without entering uncontrolled memory consumption.
- →Pipeline architecture: incoming files pass through validation first (format, size, content-type). A temporary file record is then written to the Server, processing is performed, and the result is uploaded to storage. On failure, the temp record is marked 'failed'; on success, it is automatically cleaned up. The finally block ensures temp files are deleted under all conditions.
- →Two separate processing modes are available: Compress mode downscales to a maximum of 1280x720 and re-encodes at 80% quality. Optimize mode preserves original dimensions, strips metadata, and writes progressive JPEG — allowing large images to render faster over the network.
- →Image dimensions are extracted via ImageIO header parsing without reading the full file into memory, avoiding unnecessary heap allocation.
- →Temp file lifecycle is tracked throughout processing, and upon completion the image is uploaded to Cloudflare R2 for storage. Each temp record has a 30-minute TTL. A scheduled task periodically cleans up expired and failed temp files.
- →In the Go version, the same pipeline was rewritten using Go's native goroutines and channels. Without JVM heap overhead, memory usage for the same operation is significantly lower compared to the Java version. The difference becomes even more pronounced under high-concurrency scenarios.
- →The service is designed for independent deployment. Any microservice can consume image processing capabilities over HTTP or Kafka. The language-agnostic API design allows services written in Java, Go, or any other language to use the same image service.
JavaGoSpring BootImage ProcessingSemaphorePipelineHexagonal ArchitectureMicroservices