Fork me on GitHub
#hyperfiddle
<
2024-07-28
>
braai engineer12:07:35

how many Fly machines should I temporarily scale my Electric app to and which edge regions to use for a US-centric ProductHunt / Show HN listing? main annoyance is replicating Datalevin data to each edge node because volume is machine-bound.

Dustin Getz12:07:31

that is not a question we can answer. The only electric app that ever hit the front page is the electric y combinator essay, which stayed up, but is not interactive and the only thing it did on the server was read the file system

Dustin Getz12:07:45

i think it had 50 concurrent users for 1-2 min sessions

πŸ‘ 1
Dustin Getz12:07:24

oh and we used big fly instances in 5 regions, it cost a few hundred bucks for a couple days

πŸ‘ 1
braai engineer12:07:15

thanks – that helps. I haven't done any benchmarking. I don't expect my app to do more numbers than your essay and I'm not doing anything DB intensive in ExplainGame. I see that Fly has a concurrency soft_limit and hard_limit. Assume I need to raise these?

braai engineer12:07:28

Dustin, do you have if any "rule of thumb" ideas about how many concurrent users Electric can handle on Fly, memory-wise or CPU wise before you run into problems?

braai engineer13:07:35

Put differently: have you measured how much additional memory pressure (in KB?) each concurrent user places on an Electric backend instance? Or is that affected by component complexity?

Dustin Getz13:07:21

we have not measured anything and it likely depends on your app, you should measure

Dustin Getz13:07:35

the cost of an empty websocket is low, there are blog posts about scaling websockets on other platforms such as liveview. One really big box can get you into 10,000s of connections. Above that you will have the same ops challenges that other websocket based platforms have - which you will have money to solve from your millions of monthly active users resulting in 10,000s of concurrent connections

πŸ‘ 1
Dustin Getz13:07:15

beyond the incremental cost of a websocket connection, the rest is up to what your app is doing per connection

πŸ‘ 1
Dustin Getz13:07:03

one liveview shop hit 100k+ connections per box, you can find details on hacker news in one of the electric discussions

πŸ™ 2
Vincent13:07:11

Awesome. 100k+ is a new figure, I was estimating at least 55k+ πŸ˜ƒ

Vincent13:07:34

Sounds like maybe can do with one fly instance? i guess geographically centralized for your userbase?

Vincent13:07:43

(if database replication is a task)

Vincent13:07:47

(why do it)

braai engineer13:07:02

latency to US East vs West Coast and UK

Dustin Getz14:07:08

i also don’t think fly is the right architecture for single box database apps, we use fly because our demos are viewed globally

braai engineer14:07:43

in my case Fly is a good fit because http://explaingame.com is a social party game played in the same room so each game state can live on the nearest edge, as long as the card database is replicated to all nodes

Dustin Getz14:07:24

> as long as the card database is replicated to all nodes

braai engineer14:07:46

by cards or deck I mean the terms used to populate freshly drawn cards in a given hand, which is a long list that is practically read-only - could even be hardcoded.

Vincent05:07:48

read-only, yeah that makes sense

wei17:07:13

is there a better way to write this?

#?(:cljs (defonce !last-tick-client-time (atom 0)))
#?(:cljs (defonce !last-tick-server-time (atom 0)))
(e/def last-tick-server-time (e/watch (e/client !last-tick-server-time)))
(e/def last-tick-client-time (e/watch (e/client !last-tick-client-time)))

(e/def ms-since-last-tick
  (e/client
   (when (not= last-tick-server-time server-timestamp)
     (reset! !last-tick-server-time server-timestamp)
     (reset! !last-tick-client-time e/system-time-ms))
   (- e/system-time-ms last-tick-client-time)))
i'm writing a game that runs on server ticks (~1 second per tick), and it's useful to have the time since the last tick for client-side interpolation

Dustin Getz18:07:42

in missionary (m/reductions -), in electric (- a (delay a)) idk if we include a delay operator try searching missionary channel for discussion of delay

πŸ™ 1
Dustin Getz18:07:56

or this channel

braai engineer09:07:45

@U066TMAKS I do something similar in BraaiSim where energy transferred to food items = heat * time-elapsed, so I have a (defn next-state [db time-elapsed] (let [last-tick (:last-tick query-db)] ...)) fn that returns DataScript txes. Caller passes current rounded time to (handle-frame! conn time) fn that runs every 100ms, i.e. pass in time as (* 100 (round (/ e/system-time-ms 100.0))) and transacts new state from my entrypoint component, while the game is in a running state (not paused).

wei17:07:28

thanks for the answers! think i have it sorted πŸ™

πŸ‘ 1