DEV Community

Cover image for How hating to stand in line to get my documents printed led to Building a Zero-Friction Printing Network for Campuses.
Prakhar Shukla
Prakhar Shukla

Posted on

How hating to stand in line to get my documents printed led to Building a Zero-Friction Printing Network for Campuses.

Origin of the Problem and Initial Motivation

During my third year of college, I along with two of my batchmates embarked on building an end‑to‑end printing automation system for academic campuses. To be transparent, I didn’t begin with the intention of creating a multi‑platform infrastructure project. I mostly wanted to avoid standing in printing lines and watching shopkeepers fumble between USB drives and WhatsApp attachments while I stressed about getting to the next lecture. The system evolved gradually, as my technical ambitions repeatedly exceeded my original expectations.

Defining the Core Solution Concept

The initial goal was straightforward: allow students to upload files remotely, specify their print settings, and pay digitally, such that by the time they arrived at the print shop, their documents would already be printed. The corresponding shop‑side goal was equally important: eliminate the friction of manually receiving files from multiple channels, manually configuring print preferences for each job, and relying on shop employees who had to be computer‑fluent just to operate the printing workflow.

System Architecture and Platform Design

Building the system required creating multiple components that had to function in close coordination. The user‑facing experience existed through a React Native application and a web interface, both enabling document upload, print configuration, shop selection, and payment handling. On the printing side, the Electron‑based desktop client served as the execution node, directly connected to one or more physical printers. The backend acted as the traffic controller for all operations, driven by Redis, websockets, and an event‑oriented architecture that had to be reliable despite eventual network inconsistencies.

Document Processing Pipeline

File handling became a critical element early on. Every uploaded file was immediately converted to PDF where necessary. Instead of storing print preferences as independent sets of flags and configurations, I encoded them as bit‑compressed configuration identifiers. This was admittedly something I pieced together experimentally at first, but it turned out to drastically reduce the amount of data needed to transmit and interpret printing options on the shop side.

Redis as the Core Coordination Mechanism

Redis effectively became the backbone of the system. Each shop operated with its own job queue on the server side, allowing full isolation of failures and preventing cascading issues. When a user completed payment, the backend triggered an immediate dispatch event to the relevant shop’s client. I remember initially worrying whether having a queue per shop might create operational overhead, but in practice it did the opposite—processing remained cleanly compartmentalized, and failures never propagated laterally.

Shop Lookup and Geospatial Optimization

The discovery of active shops and their distances to users was handled through Redis geospatial indexing. One key outcome of this design was that user-side shop lookups virtually never hit the database for reads. The geospatial store in Redis held canonical shop coordinates, cached online/offline availability, and even prefiltered lists of frequently requested regions. Only in exceptional fallback scenarios would the system consult the database—but during the entire lifecycle of my involvement, that fallback never actually triggered. This turned what could have been a slow database-bound query into a sub‑millisecond in‑memory operation.

A similar effect applied to other data paths as well: when the user uploaded a document, the temporary object references, configuration encodings, and job metadata were kept in cache for the duration of processing. The database was effectively used as a durable ledger of record, but not a request‑serving engine. This dramatically reduced read-load and made most user interactions feel instantaneous, even when multiple shops and multiple jobs were being handled concurrently.

IoT Deployment and Raspberry Pi Integration

One of the more difficult—yet rewarding—extensions of the system was supporting shops without an available laptop. The Raspberry‑Pi‑based IoT module emerged from that need. I adapted the core functionality of the Electron client into a headless Pi‑hosted daemon. During setup, the Pi exposed a configuration network the shopkeeper could join via phone. Once credentials were saved, the Pi joined the shop WiFi and permanently became a connected endpoint. I still remember the first successful remote dispatch into a Pi‑controlled printer; it felt like witnessing my own system operate outside of any GUI or keyboard, which was both thrilling and unnerving.

Deployment and User Adoption

The system was deployed experimentally across several campuses. Students very quickly adapted to the behavior of uploading their documents in advance. Shopkeepers were relieved to skip the constant file‑handling and settings adjustments. Each successful transaction reinforced the feeling that this was solving a tangible, real‑world inefficiency.

Transition and Organizational Exit

Eventually, I stepped away from the organizational side of the project due to shifting involvement and internal changes. The system is still functional in some form, continued by the remaining members of the team. As much as I occasionally wish I could have carried it further myself, the experience of building it shaped my technical intuition in a major way.

Technical Reflection and Lessons Learned

Looking back, I realize how much of the system I learned as I went along. I built distributed queues before fully understanding the theoretical underpinnings, implemented geospatial caching before feeling academically qualified to do so, and created an IoT hardware‑software pipeline by stubborn experimentation rather than established training. Yet, in practice, the system worked, and it worked well.

That lesson — that a student can build something operationally real through incremental learning and persistent iteration — has become a foundational part of how I now approach engineering challenges.

As for the present, I am now in my last semester of CS degree, working independently again, continuing to build and experiment with new systems and ideas. I’m actively looking to connect with engineers, developers, and technically curious people who enjoy exploring ambitious software problems. I’m also open to professional opportunities where I can contribute to engineering teams, particularly in roles involving backend systems, distributed infrastructure, or IoT-driven interfaces. I’m eager to keep building things that step out of the theoretical and into the tangible.

Top comments (0)