Performance
Speed is a critical feature of Cool Maze. This post explains how we drastically minimize latency and make the transfers feel instantaneous.
Sending a picture involves multiple steps:
- The mobile camera opens and lets the user aim at the QR code to scan it,
- The mobile extracts the text content from the scanned QR code,
- The mobile encrypts the picture using a first secret key,
- The mobile uploads the encrypted data to the server,
- The mobile encrypts the first secret key using a second secret key obtained from the QR code, and sends the encrypted first key to the server,
- The server notifies the target web page on the computer,
- The target web page downloads the encrypted data,
- The web page decrypts the data with the second secret key, then with the first secret key,
- The web page displays the picture.
Downscaling
A high-resolution photo in a mobile phone is typically 4000x3000 pixels and weighs 3MB, which takes 4s to upload over wifi, or 7s to upload over a mobile network.
However, in most use cases the full resolution is not needed! Our human eye does not see much difference when viewing the same picture with a 2000x1500 resolution only. Thus by default, Cool Maze reduces the resolution to 2000x1500, which results in a mere 400kB of data to upload.
![]() |
![]() |
---|---|
Original photo (heavy) | Resized photo (lightweight) |
This optimization saves 2.3s on wifi upload, 4.6s on mobile network upload, and 1s on download.
Upload early
It takes a few seconds for the user to aim their mobile at the QR code and have the mobile detect it. This is the perfect time to start uploading the encrypted data, in the background! We can’t deliver the data to the destination web page yet, because the mobile has not read the QR yet, and does not know the recipient. The recipient has a routing ID which is encoded in the QR code. However, we can send the data to the server, which provides a significant head start because the upload step from the mobile is often the primary bottleneck.
This is making the end-to-end encryption flow a bit more complicated, involving one mobile-generated first secret key, and one target-generated second secret key.
In many cases, the encrypted data is already fully uploaded when the mobile successfully detects the QR code. This optimization saves from 1.5s to 4s.
Shorter QR code
As explained in the article QR code data: shorter is better, we’ve meticulously designed our QR code content to be as concise as possible, thus as fast to detect as possible.
This optimization saves 2s of user frustration time. Remember the last time you had to scan a complex QR code, but your mobile had trouble finding the proper focus on a dense matrix of tiny black squares?
Display a preview
Sometimes the transfer is not instant. For example, when the mobile internet signal is weak. Or when the user decides to transfer the original high-resolution 3MB photo, because they want to print it. This is where fast feedback is important, even if the full process is slow. To make the interface more responsive, we added a bit of extra work in the pipeline:
- The mobile computes a Preview, which is a very low-resolution version of the picture, weighing only 10kB.
- The Preview is fast to create, encrypt and transfer. It is uploaded first, ahead of the picture itself.
- The target computer web page displays the blurry Preview, while the picture itself is still being uploaded and downloaded.
![]() |
![]() |
---|---|
Preview during transfer | Transfer complete |
This feature saves zero milliseconds on the total latency. However, it is very important to acknowledge the user intent early, and let them know that the web page was successfully reached and is actively working on retrieving the encrypted data. Displaying “something” fast on the target computer is more important for the user experience than the exact number of seconds of the full transfer!
Cryptography performance
Encrypting and decrypting data using a symmetric AES algorithm turns out to be fast: less than 100ms. This is not the bottleneck and we have not tried to optimize the crypto steps.
Result
Does this look fast enough?