Emin Gevorgian
CV (PDF, opens in a new tab)Contact

Emin Gevorgian

Senior Software Engineer

I build real-time systems that stay correct under load.

Get in touchCV (PDF, opens in a new tab)

Skinrave.gg

A real-time iGaming platform on event-driven microservices, now generating over $3M in annual revenue.

The Skinrave.gg home page: promotional banners above the grid of game tiles.

TL;DR

Outcome
Over $3M in annual revenue
Role
Full-stack engineer, mostly backend; team lead
Context
iGaming product built at Milies

Context

Skinrave.gg is a real-time iGaming platform for in-game items: live game rounds, a marketplace with listings, auctions and peer-to-peer trades, and a wallet. It was one of two products my team at Milies worked on. The hard part was the backend. Many players act on the same state at once, and every balance has to stay correct while they do, with no lost updates and no double-spends. Results have to reach players live, and calls to the external item platform have to stay under its rate limits.

Architecture

ClientsAPI gatewayauthWebSocket gatewaylive pushSchedulercron · deadlinesMessage brokerrequest/reply · domain eventsDomain servicesgame · market · itemsWallet & paymentsledgerPayment providerswebhooksData storesrelational · in-memory · documentsexternalClientsAPI gatewayauthWebSocket gatewaylive pushSchedulercron · deadlinesMessage brokerrequest/reply · domain eventsDomain servicesgame · market · itemsData storesrelational · in-memory · documentsWallet & paymentsledgerPayment providerswebhooksexternal
Fig. 1Requests enter through the API gateway, live updates leave through the WebSocket gateway, and every balance change goes through the wallet service.

The backend is a set of TypeScript services on NestJS.

  • API gateway. The only public HTTP surface. It handles auth and calls the services request/reply over RabbitMQ.
  • Domain events. Every state change is published to one topic exchange. A WebSocket gateway subscribes and pushes the events to users and rooms over Socket.IO, so clients never poll.
  • Wallet and payments. The only service that changes a balance. Payment webhooks land here.
  • Data stores. PostgreSQL for money and users, MongoDB for settings and snapshots, Redis for hot game state and counters.
  • Scheduler. The single home for cron jobs and deadlines. Deadlines are persisted, so in-flight timers survive a server restart.

Decisions

One ledger service for every balance change. Other services send effects (add, spend, freeze, settle) instead of writing balances, and each effect runs in a transaction with a lock on the wallet row, exact decimal maths and an audit row. A wager freezes funds and the round settles later, so the available balance is right mid-round. I ruled out letting each service update balances itself, because that is where lost updates and double-spends come from.

Atomic increments, not read-modify-write. Reading a value, changing it and writing it back loses updates once several copies of a service work on the same value. I replaced read-modify-write with atomic increments across the scaled services, which eliminated the lost updates.

Idempotent webhooks, one pipeline. After the signature check, a conditional update marks a payment completed only if it isn’t already, and only the delivery that changed the row credits the wallet. Providers retry and send duplicates, so crediting on every delivery would pay twice; with this check, repeats do nothing.

Reject rather than risk the upstream. Calls to the external item platform are spread across a pool of workers, each under a rate cap, and a request past the cap is rejected. Pushing past the limit would risk the platform banning us.

Result

Skinrave.gg now generates over $3M in annual revenue, which is the whole team’s result. My own part included rebuilding leaderboard ranking from seconds to milliseconds and cutting roulette writes 95-99% at 2,000+ concurrent users.

My role

I was a full-stack engineer, mostly on the backend, and the team lead, leading a team of eight, engineers and designers, across two products. I architected the backend as event-driven microservices, built the persistent scheduling with full timer recovery, and integrated the crypto and fiat payment providers behind one idempotent webhook pipeline.

Contact

© 2026 Emin Gevorgian