A deep‑dive into the design of Subhams Secure Agent, a RAM‑only, WebSocket‑driven print service that eliminates disk footprints for sensitive Indian documents. The article walks through the problem of insecure public‑cloud printing, the real‑time socket bridge, hardware fingerprinting, and the scalability and consistency trade‑offs of the chosen architecture.
The Problem: Public‑Cloud Printing Leaves a Digital Trail
In many Indian towns, users still rely on internet cafés or neighborhood print shops to produce copies of Aadhaar cards, PAN cards, and bank statements. The usual workflow looks like this:
- The user sends the file via WhatsApp, email, or a simple web upload.
- The shop’s server stores the document on disk, often in an unencrypted folder.
- The document sits there until a staff member prints it, and then it may linger for days or weeks.
Each step creates a persistent copy that can be accessed by anyone with local access to the machine. For highly regulated personal data, that exposure is unacceptable. The goal of Subhams Secure Agent is to eliminate any permanent storage while still delivering a fast, user‑friendly printing experience.
Solution Overview: Real‑Time Sockets + RAM‑Only Processing
Instead of a classic request‑response API, the system uses a bidirectional WebSocket channel (via socket.io) to push documents directly from the client’s mobile device to the shop’s terminal. The flow is:
- Client establishes a Socket.io connection to the Node.js gateway.
- The user selects a file; the browser reads it into a
Bloband streams the binary payload over the socket. - The gateway receives the buffer, stores it in a node‑buffer allocated in RAM, and immediately forwards it to the authenticated printer agent.
- The printer agent writes the buffer to the printer’s spooler (most printers accept raw data via USB or network sockets). Once the printer acknowledges completion, the buffer is
zeroedand the garbage collector frees the memory. - If the session is cancelled, the buffer is wiped instantly.
Key Components
- Node.js + Express – lightweight HTTP server that only serves the initial HTML/JS bundle and handles authentication.
- Socket.io – provides fallback transports (polling) for environments where WebSocket is blocked, ensuring reliability.
- In‑memory store – a simple
Map<sessionId, Buffer>; no external cache like Redis is needed because the data never leaves the process. - Hardware fingerprinting – each printer agent registers a signed hardware ID (CPU serial, MAC address) with the gateway. The gateway validates the signature before accepting a print job.
- MongoDB Atlas – used solely for user accounts, session metadata, and audit logs; no document blobs are stored.

Scalability Implications
Horizontal Scaling
Because the payload never leaves the process memory, a single Node.js instance can handle a limited number of concurrent print jobs – roughly the amount of RAM you can allocate safely. To scale horizontally:
- Stateless front‑ends – the Express layer remains stateless; you can spin up additional instances behind a load balancer (e.g., Nginx or AWS ALB).
- Sticky sessions – Socket.io requires the client to stay on the same backend instance for the duration of the print job. Using session affinity on the load balancer solves this without a shared memory layer.
- Capacity planning – if each document averages 5 MB and you allocate 2 GB of heap per instance, you can safely process ~300 concurrent jobs. Beyond that, you either increase instance size or shard the workload across more nodes.
Consistency Model
Since the data lives only in RAM, the system follows an eventual consistency model for audit logs: once a job finishes, a tiny record ({sessionId, userId, printerId, timestamp, status}) is written to MongoDB. If the node crashes before the write, the print job is lost, but the document never persisted anywhere, preserving the zero‑retention guarantee. This trade‑off is acceptable because the primary security requirement is non‑persistence, not exactly‑once processing.
API Patterns and Security
Authentication Flow
- User logs in via a standard JWT endpoint (
POST /api/auth). - The JWT is sent as a query parameter when establishing the Socket.io connection (
io('wss://gateway.example.com', { query: { token } })). - The server validates the token and attaches the user ID to the socket context.
Authorization Checks
- Printer registration – each printer agent must present a signed token generated from a private key stored on the hardware. The server verifies the signature against a public key stored in MongoDB.
- Session scoping – a socket can only send a document to a printer that belongs to the same organization as the user. This prevents cross‑tenant leakage.
Zero‑Disk‑Retention Guarantees
- All buffers are allocated with
Buffer.allocUnsafeand overwritten withbuffer.fill(0)after use. - The Node.js process runs with the
--max-old-space-sizeflag to bound memory consumption and avoid swapping to disk. - The OS is configured with
tmpfsfor any temporary files (e.g., PDF conversion) to ensure they also reside in RAM.
Trade‑offs and Failure Modes
| Aspect | Benefit | Drawback |
|---|---|---|
| RAM‑only processing | No persistent copies; strong privacy guarantee. | Limited by available memory; large files can cause OOM if not throttled. |
| WebSocket bridge | Near‑real‑time delivery; no polling latency. | Requires sticky sessions; more complex load‑balancer configuration. |
| Hardware fingerprinting | Prevents rogue printers from hijacking jobs. | Adds operational overhead (key provisioning, rotation). |
| Stateless HTTP layer | Easy to scale horizontally for the UI. | Socket affinity means you cannot arbitrarily route sockets after the initial handshake. |
| MongoDB for metadata only | Simple schema, global distribution via Atlas. | Not suitable for storing large blobs; audit logs can become a write hotspot under heavy load. |
Mitigation Strategies
- Back‑pressure – the client throttles chunk size (e.g., 64 KB) and waits for an acknowledgment before sending the next chunk. This prevents the server from being overwhelmed.
- Circuit breaker – if the RAM usage crosses a configurable threshold, new connections are rejected with a clear error message, prompting the shop to upgrade hardware.
- Graceful degradation – when a printer agent goes offline, the gateway queues the job in an in‑memory FIFO for a configurable timeout (e.g., 30 seconds). If the timeout expires, the job is aborted and the user receives a failure event.
Lessons Learned from Real‑World Failures
- Memory leaks are fatal – early prototypes used
Array.pushto accumulate chunks, which never released memory after a failed print. Switching to a singleBuffer.concatwith explicitnullassignment solved the issue. - Network jitter can corrupt streams – without proper binary framing, a dropped packet caused the printer to receive a truncated PDF, leading to garbled prints. Adding a simple length‑prefix header for each chunk restored integrity.
- Clock skew broke audit ordering – printers in different time zones reported timestamps that conflicted with MongoDB’s server time. Normalizing all timestamps to UTC before persisting eliminated the inconsistency.
Where to Find the Code
- The gateway service lives in the
gateway/directory of the repo: https://github.com/VenkataPavanKumarAmarthaluri/subhams-secure-agent/tree/main/gateway - The printer agent (Node.js script that runs on the shop’s terminal) is under
agent/: https://github.com/VenkataPavanKumarAmarthaluri/subhams-secure-agent/tree/main/agent - Full deployment instructions, including Docker Compose files, are in the repository’s README.

Closing Thoughts
Subhams Secure Agent demonstrates that a carefully scoped architecture—real‑time sockets, RAM‑only buffers, and strict hardware authentication—can meet a stringent security requirement without sacrificing user experience. The trade‑offs are clear: you gain privacy at the cost of tighter memory constraints and the need for sticky session handling. For any team looking to build a low‑latency, zero‑retention pipeline (e.g., medical imaging, legal document handling), the patterns described here provide a solid starting point.
If you’re interested in extending the system—perhaps adding end‑to‑end encryption of the payload before it hits RAM, or integrating a serverless fallback for burst traffic—feel free to open an issue or submit a PR on GitHub. Collaboration is the fastest way to harden a system that protects people’s most sensitive data.
Image credits: featured screenshots of the Subhams Secure Agent dashboard.

Comments
Please log in or register to join the discussion