Migrations
Article 6 shows the Cloud Architecture of Cool Maze - Push to Computer.
We sometimes replace components to modernize the system, improve performance, and optimize costs. Here are a few “bricks” we’ve migrated.
Application server

The backend was originally hosted on Google App Engine, a fantastic managed application server supporting the Go language.
We migrated to Cloud Run, which is even more powerful as it allows the deployment of arbitrary Docker containers.
App Engine and Cloud Run both rely on autoscaling, meaning server instances are automatically started or shut down as incoming traffic increases or decreases. For this architecture, it is crucial to design stateless instances: each instance must be able to process any incoming request without relying on local data. Instead, stateful data must be stored in a distributed memory component, or in a database.
Transient memory

Cool Maze - Push to Computer writes and reads short-lived action, such as “a web page is currently displaying a QR code and waiting for updates on channel C”.
App Engine included the built-in distributed memory system Memcache.
For Cloud Run, the closest equivalent would be Cloud Memorystore, which has a significant drawback: the cost of deploying and maintaining a running instance.
Instead, we switched to a hybrid approach involving Cloud Run in-memory data and Cloud Firestore.
- Cool Maze - Push to Computer usually requires a single Cloud Run instance. Thus, it is technically possible to keep an in-memory cache of data directly in the server’s memory. When information is already in the cache, reads are extremely fast. However, instances may be shut down at any time, so we cannot rely solely on server memory.
- We also write the short-lived data to Cloud Firestore. Reading from Firestore is less performant than from in-memory options, but the latency remains acceptable and is only needed as a fallback when the information is not found in the memory cache.
This strategy is only correct because our flow does not overwrite values and therefore does not cause any conflict between the state of the local memory and the state in Firestore.
File server

The primary file server for encrypted payloads in transit is Google Cloud Storage. If the payload is small enough, the Cool Maze - Push to Computer Android app is optimized to upload directly to Cloud Run, saving HTTPS requests.
Server push

The flow of sharing a photo via Cool Maze - Push to Computer requires the backend to notify the web page as soon as the data becomes available: first the lightweight preview, then the full picture.
We originally used the service Pusher.com to achieve this. While very reliable and performant, this service has a non-negligible cost when exceeding the initial free tier.
We switched to Cloud Firestore’s realtime updates feature. Firestore is a database, which is fundamentally different from a live messaging system. However, the realtime updates capability effectively lets the server notify clients when certain events occur, such as the modification of a document. We reimplemented server push over Firestore as follows:
- When the web page displays the QR code, it starts “listening” for updates to a specific, one-off Firestore document.
- When the mobile device sends data to the server, the server writes event information to the Firestore document. The web page immediately receives the update.
Cloud Firestore has a generous free tier, as well as attractive pricing.
Analytics database

The system uses a database in “write-only” mode to append facts such as “a user shared one file of size 190 kB at 9:25 am”. This data later enables powerful analysis of traffic and service quality.
We originally stored this data in a Cloud SQL database. This approach had two drawbacks:
- As the volume of data increased, the performance of complex SQL aggregate queries tended to deteriorate. Some could be improved by adding yet another index, but interactive querying in general was becoming slower each month.
- Cloud SQL is not “serverless”: the MySQL VM instance was running continuously, accounting for up to 80% of total cloud costs.
We solved both concerns by replacing Cloud SQL with BigQuery. BigQuery consistently handles heavy analytics SQL queries in about five seconds, requires no instance management, and has a generous free tier.