Flow: Waiting Queue (Mobile App Only)¶
Actor¶
Fan trying to purchase tickets for a high-demand match.
Context¶
For high-demand matches, HNS expects significant load:
- Expected Users: 100,000+ fans attempting to purchase
- Available Tickets: ~20,000 (after quota allocations)
- Goal: Control access to seat selection & checkout to maintain fairness and system stability
Preconditions¶
- Match is on sale (sales activate at scheduled time, e.g., 12:00)
- User is logged into the HNS mobile app
- Waiting queue microservice is active (auto-enabled based on traffic demand, not a per-match setting)
Technical Notes¶
Match Activation Timing:
- Sales open at a predefined time (e.g., 12:00) configured by admin
- Mobile app activates "Buy Tickets" / "Join Queue" button at the scheduled time
- Server-side validation prevents early access (to prevent time spoofing on client)
- App may use combination of:
- Client-side timer that activates UI at scheduled time
- Server validation on queue join request to verify sale is active
- Push notification at sale start time: "Ticket sales for [Match] are now open!"
Potential Bottleneck - Login/Registration:
- 100,000+ users may attempt to login/register immediately before ticket release
- Consider implementing queue for authentication endpoints during high-demand periods
- Pre-registration campaigns can reduce login surge at sale time
Flow Steps¶
-
Join Queue
- User opens match page in the mobile app
- App shows status: "High Demand – Join Queue"
- User taps "Join Waiting Queue"
- Backend assigns:
- Queue position
- Estimated wait time
- Total queue size
- A persistent queue banner appears inside the app
-
Queue Position Display
- User sees their position: "You are #2,547 in queue"
- Position updates:
- Local countdown decrements position every second (smoother UX)
- Server sync every 60 seconds corrects the actual position
- This provides responsive feel while maintaining accuracy
- Displays:
- Estimated wait time
- Total queue members
- Progress indicator
- User can leave the match screen — the queue remains active
As built (HNSTIK-22, Oct 2026). Estimated wait time, total queue members and the progress indicator are not built: the queue screen and the banner show the fan's position only. Whether to build them or strike them from this flow is open in HNSTIK-350.
A fan holds one place at a time. Opening another match's queue while waiting for (or buying in) one asks first: go back to that queue, or leave it and join this one. Nothing is given up silently, because an abandoned place would still take an admission slot nobody uses.
-
Continue Shopping
- User can browse the HNS shop while waiting
- Queue banner remains visible globally:
- Match pages
- Merchandise shop
- Home screen
- The queue maintains:
- Active WebSocket/Firebase connection
- OR background polling fallback
-
Queue Advancement
- Backend advances queue when:
- Users complete purchases
- Purchase time expires (20 minutes from queue entry)
- Inventory is released
- Admins add more quota
- Backend safely "drip-feeds" users to avoid:
- Seat allocation spikes
- Payment load spikes
- Backend advances queue when:
-
Progressive Notifications
- Push notifications for:
- Position change: "You're now #500 in queue"
- Near position: "You're almost at the front (#50). Get ready!" (as built: the position is an admin setting, defaulting to 50, and the wording is editable in the admin portal — Postavke → Obavijesti u redu čekanja; that wording is used for the push only, while the in-app text follows the app's language. Sent once per fan, the first time they reach it. A fan who joins already inside that band is told as soon as they can receive it: by push at join time when the device registered for push, otherwise when the app's live connection opens.)
- Your turn: "It's your turn! Buy tickets for Croatia vs Portugal"
- User has 20 minutes total from entering the purchase flow to complete the entire transaction (zone selection, checkout, payment)
- Push notifications for:
-
Purchase Window Opens
- Tap on push notification or return to the app
- Deep-link directly to zone selection
- User sees Standard Ticket Purchase
As built (HNSTIK-22, Oct 2026). The turn often comes while the fan is browsing another screen (step 3). The app then tells them at once: a message "It's your turn!" and the queue banner turns into "It's your turn — buy tickets" with the purchase time left, leading to the purchase. The purchase window is already open for them at that point, so nothing is lost by being elsewhere when it starts. The same holds when the app is reopened during the window.
- Complete Purchase
- User completes checkout
- Next queue user is notified
- If the user fails to complete within 20 minutes:
- Seats return to inventory
- Next queue user is notified
- User loses queue position and must rejoin at the end of the queue
Alternative Flows¶
A1: User Misses Purchase Window
- User loses their queue position
- Must rejoin at the end of the queue (treated as new user)
- Notification: "Your purchase window has expired. Please rejoin the queue to try again."
A2: User Leaves Queue
- User clicks "Leave Queue"
- Confirmation prompt displayed
- Position is lost permanently
- Rejoining sends them to back of queue
A3: All Tickets Sold
- Backend closes queue
- Push notification: "Match sold out."
- Queue disbanded automatically
As built (HNSTIK-22, Sep 2026). Closing a queue broadcasts
queue_closedto everyone still waiting, carrying the reason the backend sent —sold_out,match_cancelledormatch_closed— so the app can say which. It is sent over the WebSocket and as a push, because it matters precisely when the app is in the background. Waiting tickets are not cancelled: they lapse on their own TTL, so a queue closed by mistake can be reopened without anyone having lost their place. A fan who is already inside their purchase window is not told and not interrupted — closing the queue to newcomers is not a reason to cut a purchase short.
A4: Connection Lost
- Queue position persists for 30 minutes
- On reconnect:
- App restores position
- Message: "Welcome back! You're still #127 in queue"
As built (HNSTIK-22, Sep 2026). A dropped WebSocket is treated as a non-event: mobile OSes close it within seconds of an app going to the background, so a disconnect never transitions the ticket. The position is held for the ticket's whole TTL — 24 hours as the ticketing backend provisions match queues — which puts the 30-minute grace period a long way inside it. On return the app reads its stored ticket and picks the same place back up. Per Tamer (23 Sep) the "Welcome back" message is not required: the queue simply still being there, showing the same number, is the expected behaviour.
The app reconnects by itself, and keeps trying — after 1 s, then with growing pauses up to 30 s — for as long as the waiting room cannot be reached (a restart or deploy during a sale). It stops only when the waiting room says the ticket no longer exists. A fan admitted meanwhile is taken to the purchase as soon as the connection is back.
A5: Multiple Devices
- Same user ID = same queue position
- Device switch transfers the queue session
- Secondary device shows: "Queue transferred to another device"
As built (HNSTIK-22, Sep 2026) — this flow said what the second device shows but never what the first one does, which is what QA reported missing (Domagoj, 18 Sep). Decided behaviour:
- A ticket has one live connection. The newest device owns it; the previous one is handed a
transferredevent and its socket is closed (code 4001), so it says "the queue moved to another device" instead of quietly freezing on a stale number.- It is a hand-over, not a second place in line: both devices are the same ticket, so there is only ever one position and one purchase window.
- If the second device leaves the queue, the ticket is gone for both. Leaving is explicit and confirmed, and the first device gets back in the ordinary way — by joining again, at the end of the queue. The first device can also simply take the ticket back by reopening the queue screen, which makes it the live connection again.
- Logging the fan out of the first device was considered and rejected: the queue is one feature, and one device per account would change how the whole app behaves.
Last Updated: January 2026