Zoidy's avatar
Level 1

Poll, event or broadcasting?

Hi, first time poster here :)

So I'm new to Laravel and have choosen a quite ambitious first project. Everything has gone pretty smoothly so far, but I want to implement this feature that I'm not sure what the best solution is.

So the application has "tournaments" that users can sign up for. When a tournament starts, I want to have a page where participants can view information and get real-time updates. The page should also have a countdown timer.

The tournament has a predetermined cycle. When the countdown reached zero, the page should update with new information and the countdown reset automatically. But the "organizer" of the tournament should also be able to control (start, pause, reset etc) the countdown timer when needed. And these actions needs to be synced/broadcasted to the other users on their devices.

What would the best approach be? I'm using the TALL stack.

0 likes
3 replies
Svennnn's avatar

Just some directions of thought from an general infrastructure point of view:

If you have many users, essentially receiving the very same information, both pulling and pushing is fine and come with their own challenges.

Pulling

When you pull (i.e many users make "is there something new"-requests via js), you want to cache the response a lot, so that you save app overhead (like fetching from db and stuff). Caching introduces the complexity of having to manage caches: i.e you need to invalidate the cache / you have to make sure that when the cache is cold (because you invalidated it or it reached its TTL), not all parrallel requests that you receive while the cache is cold make it so that your app is rewarming the cache for those requests individuelly. Pulling, in general, has the downside of having some kind of interval (eg every 5 sec), that makes it not realtime.

Solution A: Extra infra

Introduce something to your infra thats designed for exactly this. Varnish is, for example, an HTTP cache that is absurd fast and also has this feature named coalescending requests (so if many people want X, only one request reaches your app for X). It also can serve stale caches, while it refreshes them in the background (i.e against your app). It's great, but makes your infrastructure much more complex and has a learning curve

Solution B: Make it cheap to pull

You could also make it so that the piece that collects the fresh info, is run independently from the requests that access this info. For example you could have a Job/Scheduler that runs every few seconds and updates a cache-entry. Your route that handles the pull-requests can then just return whatever is cached. This still means you run laravel for every single request, but try to make it as quick as possible.

Pushing

Pushing has the big advantage of feeling more realtime. You push some info just as it happens. On the other hand, in HTTP there isn't really of way for a server to reach out to a client by itself. The connection had to be created by the client. Most websocket-solutions like Laravel Reverb are basicly a process that keeps running on your server, and keeps incomming connections to subscribers alive. So if you have 1k persons waiting for something to happen, you have 1k connections on your server blocked. If the information to be sent is super individual, pushing doesn't really save ressources. If everybody gets his custom message, you still have to run something for each individual person AND keep those connections open all the time. Maintaining this load and configuring your servers for Laravel Reverb isnt always too easy.

So in a nutshell

If you pull, you transmit a lot of wasted data (i.e when nothing changed), but free your ressources right after you send your new ping, while with pushing you send less but keep those connections open all the time. There are scenarios for both situations and it really depends on the number of users, how you are hosting your app and what is important from your users point of view (is waiting 1-5 seconds fine? how critical is data usage?)

If you just want to get going and have something quick and easy, I would suggest Pull B as a starting point.

1 like
Zoidy's avatar
Level 1

@Svennnn Thanks for your comprehensive answer! Great with the infrastructure PoV, since I have very little experience there. Not knowing what the cheapest solution is, in terms of resources and money.

Initially 100% of the updates will be general, down the line there could be individual updates to specific users. Users and hosting is unknown atm. I might give Laravel cloud a go.

I asked our AI overlords aswell and it suggested broadcasting with Pusher. I quickly googled Reverb vs Pusher but didn't find much other then Reverb is free but harder to set up?

Svennnn's avatar

@Zoidy both are broadcastingsolutions via Websockets and supported by laravel. One (reverb) is hosted by yourself (= you need to set it up, keep it running, etc), while the other is a hosted service where you just pay the service and they handle the hard stuff. Also keep in mind, that depending on your juristication (i.e EU), you might need a consent layer or data protection agreement for pusher, since your endusers make a connection to this external service and you let that service process your data.

Honestly, I really would suggest trying to build it the Pull-Way first. It's also a really good task to get into the mindset of async communication.

Please or to participate in this conversation.