Inspiration
Every year, our smartphones capture thousands of irreplaceable memories—family milestones, travels, and everyday moments. But today, everyday users are backed into an uncomfortable corner by big tech cloud monopolies. Subscriptions for Google Photos and iCloud quietly increase in price, photos are compressed unless you pay a steep monthly tier, and our most intimate personal photos are scanned on remote corporate servers for algorithmic profiling and ad targeting.
On the other hand, traditional self-hosted tools often fall short on the actual mobile experience: background sync frequently breaks or drains battery, switching between family accounts corrupts the upload queue, and setups feel brittle.
We asked ourselves: Why should taking ownership of your personal data mean sacrificing the smooth, intelligent consumer experience of Google Photos?
We set out to build CloudPhotos to prove that total privacy, self-sovereignty, and flawless, battery-conscious mobile synchronization can coexist in a single, high-performance platform.
What It Does
CloudPhotos is a full-stack, privacy-centric photo storage and synchronization ecosystem designed to deliver a modern cloud experience without surrendering privacy:
- Seamless Background Mobile Backup: A native Flutter mobile app running resilient background synchronization via Android WorkManager foreground services. It automatically scans the camera roll and uploads original, uncompressed photos and 4K videos while respecting network (Wi-Fi only) and battery/charging constraints.
- Intelligent Multi-Account Isolation: Users can pause backups, switch accounts, or manage separate family vaults on a single handset. The underlying engine guarantees atomic unbind transitions so backup queues never bleed across accounts or cause duplicate uploads.
- Content-Addressable Deduplication: Client-side cryptographic SHA-256 hashing verifies media assets before initiating transfer, saving mobile data, battery life, and server disk space.
- Intelligent Semantic and Facial Search: Powered by local vector embeddings and machine learning microservices, users can find photos using natural language queries (such as sunset at beach, birthday celebration) or browse automatically clustered faces completely private on-premise without third-party API exposure.
- Unified Multi-Platform Suite: Complete ecosystem featuring a cross-platform mobile client, an ultra-fast responsive Web gallery, and an Administrative Console for multi-tenant user and storage quota governance.
How We Built It
We architected CloudPhotos as a decoupled, multi-tiered microservice platform built for rock-solid reliability, low latency, and horizontal scalability:
- Mobile Client (Flutter and Riverpod): Built with Flutter 3 for responsive cross-platform performance. We implemented a dedicated state machine managing backup isolates, communicating via IsolateNameServer to ensure file scanning and uploads never drop frames from the 60fps UI.
- Background Synchronization Engine: Engineered a background worker architecture utilizing Android WorkManager with custom foreground notification channels, chunked resumable streams, and a JSONL-based persistent state journal that guarantees atomic resumes even after system reboots.
- Backend and Media Microservices: Deployed containerized microservices orchestrating metadata extraction (EXIF/GPS), on-the-fly thumbnail transcoding (sharp/libvips), and machine learning pipelines for CLIP vectors and face recognition.
- Database and Vector Search (PostgreSQL and pgvector): Leveraged PostgreSQL 16 with the pgvector extension for sub-50ms high-dimensional semantic search and Redis for asynchronous job scheduling.
- Gateway and Infrastructure: Fronted by high-performance Nginx reverse proxies with automatic SSL termination, Docker container orchestration, and RESTful API authentication guards.
- Spec-Driven Engineering with Kiro: We leveraged Kiro's spec-driven development and agent steering workflows to rapidly design our multi-account backup state machine, systematically map edge-case failure modes, and generate rigorous cross-platform unit and integration test suites.
Challenges We Ran Into
Building a mobile backup system that matches commercial consumer apps presented real low-level systems engineering hurdles:
- Modern Mobile Background Execution Limits: Android 14+ aggressively terminates long-running background tasks to conserve battery. Off-the-shelf sync libraries frequently failed mid-batch. We resolved this by building a dedicated WorkManager foreground service pipeline with chunked batching and persistent state journals that cleanly resume from the exact asset offset upon wake.
- Multi-Account State Race Conditions: When a user with thousands of pending items pauses backup, signs out, and logs into a secondary account, naive implementations cause torn writes, orphaned isolates, or cross-account upload collisions. We designed a strict unbind-and-flush contract in our backup state store, tearing down active background workers and sanitizing pending queues before mounting the new account profile.
- Non-Blocking UI Cryptographic Hashing: Computing SHA-256 digests over gigabytes of raw 4K video files locally was prone to freezing the main Flutter thread. We refactored the scanning pipeline into isolated background worker isolates, keeping the UI completely fluid while processing high-throughput media ingestion.
Accomplishments That We're Proud Of
- Created a rock-solid background backup engine that does not drop tasks, drain unnecessary battery, or suffer from race conditions.
- Delivered a live, production-grade end-to-end ecosystem (Mobile App, Web Client, Admin Panel, and Media AI Backend) fully deployed on real infrastructure.
- Achieved bit-for-bit file integrity preservation: zero compression, zero stripped EXIF metadata, preserving RAW and 4K assets in their original capture format.
- Built a truly isolated multi-tenant architecture that allows family members to share a single host while keeping private photo libraries cryptographically separate.
What We Learned
- Deep low-level knowledge of mobile operating system lifecycle constraints, battery optimization states, and multi-isolate memory sharing in Dart and Flutter.
- The immense value of spec-driven architecture with Kiro: defining strict state contracts for asynchronous background jobs before writing code saved us countless hours of edge-case debugging.
- The practical mechanics of self-hosted high-dimensional vector search with pgvector and balancing inference latency on consumer-grade server hardware.
What's Next for CloudPhotos
- Zero-Knowledge Encrypted Shared Vaults: End-to-end client-side encryption for collaborative family albums where even the server administrator cannot decrypt the photos.
- Native Desktop Companion: Native Windows and macOS menu bar utilities built with Flutter Desktop for automated two-way folder synchronization from DSLR cameras and external drives.
- On-Device Edge ML: Shifting face detection and CLIP vector generation to run locally on the smartphone's NPU prior to upload, further minimizing server computational requirements.
- One-Click Cloud Migrators: Automated import utilities that pull historic photo libraries directly from Google Takeout and iCloud backups without requiring manual downloads.
Built With
- dart
- docker
- flutter
- immich
- kiro
- linux
- nginx
- node.js
- pgvector
- postgresql
- redis
- typescript
- workmanager