Back to Home

A SaaS QR-based menu and ordering platform engineered to solve real-world performance challenges in hospitality.

The Problem

Cafes and restaurants needed a fast, zero-friction way for customers to view menus and place orders without waiting for a waiter. The catch? The system had to work flawlessly on slow mobile networks, prevent low-end devices from crashing on large menus, and sync orders to the kitchen instantly without overwhelming the database.

Architecture

I built ZaykaTap with a monolith-ready-for-microservices architecture on the backend, containerized via Docker and Nginx on a raw VPS. To enforce strict separation of concerns, I split the application across subdomains:

  • api.zaykatap.com: Core backend APIs and business logic.
  • app.zaykatap.com: The dashboard and core business management logic.
  • menu.zaykatap.com: The highly-optimized customer-facing interface.
  • auth.zaykatap.com: Isolated authentication and security.
  • static.zaykatap.com: Gzipped assets and WebP images, primed for future CDN integration.
          [ Customers (Mobile) ]        [ Kitchen (React Native) ]
                   |                                |
       (Subdomains: menu, static)             (Subdomain: app)
                   |                                |
            [ Nginx Reverse Proxy (Dockerized VPS) ]
                   |
      +------------+------------+-------------+
      |                         |             |
[ PHP Core APIs ]         [ Node.js ]    [ RabbitMQ ]
 (Business Logic)        (WebSockets)  (Async Webhooks &
      |                         ^        PDF Generation)
      v                         |
[ MariaDB DB ] <---(Pub/Sub)--- [ Redis ]

The architecture isolates heavy transactional workloads from real-time connections and asynchronous tasks.

Engineering for the Real World

When building ZaykaTap, I didn't just want it to work on a developer's fast Wi-Fi; I needed it to survive the chaos of a busy restaurant on a Saturday night.

To keep the menu buttery smooth for users, I implemented on-the-fly image conversion to WebP and a DOM virtualization strategy that prioritizes rendering the first 5 items instantly. On the backend, I swapped constant SQL polling for Redis-backed WebSockets, allowing instant kitchen updates while drastically reducing database load. Finally, I offloaded heavy tasks—like generating pixel-perfect PDF menus and handling payment webhooks—to RabbitMQ to ensure the main API never hangs.

Business & Technical Impact

< 1.5s
Time to Interactive (3G)

Reduced initial payload by 70-80% and lowered browser RAM usage by rendering only 4-5 items initially.

80-90%
Lower Database I/O

Routed real-time updates through Redis as a message broker instead of aggressive SQL polling.

~100%
Payment Reliability

Protected against duplicate billing via idempotency checks and RabbitMQ retries with <100ms API acknowledgment.

Zero
Deployment Downtime

Atomic deployments handled autonomously via GitHub Actions on a containerized Docker/Nginx VPS setup.

🏁

You've reached the end

Thanks for checking out the ZaykaTap case study.