Live data from Hacker News

My thoughts about Fly.io (so far) and other newish technology I'm getting into

blog.hartleybrody.com

61–70 of 111 posts

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#61
> It seems like this would add a whole new class of bugs, like “I just submitted a form to change a setting and when the page reloaded, it still showed my previous value in the form” – since the write hadn’t propagated to the local read replica yet.

There's a very solid solution to this that isn't as widely known as it should be.

Read after write consistency is extremely important. If a user makes an edit to their content and then can't see that edit in the next page they load they will assume things are broken, and that the site has lost their content. This is really bad!

The best fix for this is to make sure that all reads from that user are directed to the lead database for a short period of time after they make an edit.

The Fly replay header is perfect for this. Here's what to do:

Any time a user performs a write (which should involve a POST request), set a cookie with a very short time expiry - 5s perhaps, though monitor your worst case replica lag to pick the right value.

I have trust issues with clocks in user's browsers, so I like to do this by including a value of the cookie that's the server-time when it should expire.

In your application's top-level middleware, look for that cookie. If a user has it and the court time has not been reached yet, send a Fly replay header that internally redirects the request to the lead region.

This guarantees that users who have just performed a write won't see stale data from a lagging replica. And the implementation is a dozen or so lines of code.

Obviously this won't work for every product - if you're building a chat app where every active user writes to the database every few seconds implementing this will send almost every piece of traffic to your leaders leaving your replicas with not much to do.

But if your application fits the common pattern where 95% of traffic are reads and only a small portion of your users are causing writes at any one time I would expect this to be extremely effective.

Fly replay headers are explained in detail here: https://fly.io/blog/globally-distributed-postgres/

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#62

> But despite how much I want to learn the fly.io platform – it has been a bit tricky for me wrap my head around a good use-case for this type of distributed hosting service. Worth noting that you don't have to use the distributed aspect. I have my site hosted on a single one of a fly.io's smallest instances (which one can get 3 of for free), and even like this the performance is excellent (50ms response times), and…

Same. I'm really impressed with the experience on there now that I finally spent a day trying it out. The geodistribution stuff had no interest to me so I'd avoided them till now, but it's really the underlying tooling and experience that has won me over.

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#63
One of the points about read replicas and read-your-own-writes is correct to call out, but on the Elixir side we have an answer to that:

> It seems like this would add a whole new class of bugs, like “I just submitted a form to change a setting and when the page reloaded, it still showed my previous value in the form” – since the write hadn’t propagated to the local read replica yet.

Elixir is distributed out of the box, so nodes can message each other. This allowed us to easily ship a `fly_postgres_elixir` library that guarantees read-your-own-writes: https://github.com/superfly/fly_postgres_elixir

It does this by sending writes to the primary region over RPC (via distributed elixir). The write is performed on a primary instance adjacent to the DB, then the result, and the postgres log-sequence-number, is sent back to the remote node. When the library gets a result of the RPC write, it blocks locally until its local read replica matches an LSN >= write LSN, then the result is returned to the caller

This gives us read-your-own-writes for the end-user, and the calling code remains unchanged for standard code paths. This doesn't solve all classes of race conditions – for example you may broadcast a message over Phoenix.PubSub that causes a read on the remote node for data that isn't yet replicated, but typically you'd avoid an N query problem from pubsub in general by populating the data in the message on the publisher beforehand.

There's no completely avoiding the fact you have a distributed system where the speed of light matters, but it's Fly's (and Phoenix's) goal to push those concerns back as far as possible. For read heavy apps, or apps that use caching layers for reads, developers already face these kinds of problems. If you think of your read-replicas as cache with a convenient SQL interface, you can avoid most foot guns.

I'm happy to answer other questions as it relates to Phoenix, Fly or what Phoenix + Fly enables from my perspective.

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#64
post #42

I think his stack is a little confused. He's got HTMX and Phoenix in there. If you are using Phoenix then LiveView is the obvious approach to dynamically updating a page based on server stuff. It's a similar-ish architecture to HTMX, but integrated into the framework. The page is rendered on the server as normal, then when it loads on the client a web-socket is opened to a task on the server (page includes the LiveVi…

Thanks for this explainer. This is the missing “here is when it’s redundant” guideline when investigating whether to add to your stack.

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#65

Do many companies actually need databases geolocated near users? I'm working on big and small projects/companies and that has never been any concern of ours. I always imagined it to be something only the very very big players care about. And as a big player I would usually bet on a big partner like AWS, GCP, Azure. Or am I missing something?

Companies start to get a lot more interested in this when their business truly goes global. Users in Australia have money to spend and get pretty poor performance from apps hosted in the USA due to speed of light issues.

I've looked at implementing this in the past and always found it to be SO difficult that the benefit would not be worth the cost.

Fly has changed that equation for me. It has moved this problem from "I'd love to do it if I could but it's just too hard" to "This is a thing I could do with small enough engineering effort that it would be worthwhile".

This is my favourite type of technology: I love things that move something from the "too expensive" to the "now feasible to implement" bucket!

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#66
post #61

> It seems like this would add a whole new class of bugs, like “I just submitted a form to change a setting and when the page reloaded, it still showed my previous value in the form” – since the write hadn’t propagated to the local read replica yet. There's a very solid solution to this that isn't as widely known as it should be. Read after write consistency is extremely important. If a user makes an edit to their co…

There's another, more sophisticated trick that works for some databases: tracking a global transaction counter of some sort, persisting that in a cookie when a user makes a write and redirecting the user to the lead database if the replica they are talking to hasn't made it to that point yet.

Chris McCord describes how Elixir does that with PostgreSQL here: https://news.ycombinator.com/item?id=31434094

Wikipedia implements this trick on top of PHP and MySQL global transaction IDs (GTIDs) so it definitely scales!

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#67

One of the points about read replicas and read-your-own-writes is correct to call out, but on the Elixir side we have an answer to that: > It seems like this would add a whole new class of bugs, like “I just submitted a form to change a setting and when the page reloaded, it still showed my previous value in the form” – since the write hadn’t propagated to the local read replica yet. Elixir is distributed out of the…

That's very cool. Presumably as well this could be opt out if you had specific operations (perhaps from a write-only API) that don't need to wait to do further writes?

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#68
post #8
post #3

An unrelated, yet honest question. There have been many posts hitting the HN frontpage regarding fly.io recently. Is it healthy to have so much content about a single PAAS platform showing up here so often now?

Generally, it is all YC hype. HN is biased towards YC startups. There are other alternatives like Render.com, railway.app, etc but it is clear that fly.io is unsurprisingly overhyped by the HN crowd, especially if you are looking for a Heroku alternative. It’s like asking a barber if you need a haircut.

Give credit where it's due:

fly.io spends a tremendous amount of time on creating interesting technical content that attracts this type of attention. The company is intentional about this as a customer acquisition strategy. They have an illustrator on staff for their unique art style, for example. Their founder and senior technical staff engage with these posts and answer questions, etc.. It's not YC favoritism, it's a deep understanding of the developer first mindset / ecosystem and targeting it as a company strategy.

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#69

One of the points about read replicas and read-your-own-writes is correct to call out, but on the Elixir side we have an answer to that: > It seems like this would add a whole new class of bugs, like “I just submitted a form to change a setting and when the page reloaded, it still showed my previous value in the form” – since the write hadn’t propagated to the local read replica yet. Elixir is distributed out of the…

That's very cool. Presumably as well this could be opt out if you had specific operations (perhaps from a write-only API) that don't need to wait to do further writes?

Yeah we expose interfaces to ignore blocking on the LSN, but the way this works is by proxying the Ecto Repo interface with our own Repo. So you could call your underlying Repo directly if you wanted to perform a write without blocking on the LSN as well.

Re: My thoughts about Fly.io (so far) and other newish technology I'm getting into

#70
post #65

Do many companies actually need databases geolocated near users? I'm working on big and small projects/companies and that has never been any concern of ours. I always imagined it to be something only the very very big players care about. And as a big player I would usually bet on a big partner like AWS, GCP, Azure. Or am I missing something?

Companies start to get a lot more interested in this when their business truly goes global. Users in Australia have money to spend and get pretty poor performance from apps hosted in the USA due to speed of light issues. I've looked at implementing this in the past and always found it to be SO difficult that the benefit would not be worth the cost. Fly has changed that equation for me. It has moved this problem from…

Yeah, and I guess all my Australian hosted things are slow for you Americans who have even more money to spend
Post reply on HN