top | item 46259289

(no title)

stephen | 2 months ago

Can you description the deployment setup, somewhere in the docs/maybe with a diagram?

I get this is a backend library, which is great, but like does it use postgres replication slots? Per the inherited queries, do they all live on 1 machine, and we just assume that machine needs to be sufficiently beefy to serve all currently-live queries?

Do all of my (backend) live-queries live/run on that one beefy machine? What's the life cycle for live-queries? Like how can I deploy new ones / kill old ones / as I'm making deployments / business logic changes that might change the queries?

This is all really hard ofc, so apologies for all the questions, just trying to understand -- thanks!

discuss

order

phrasecode|2 months ago

Great questions — happy to clarify how deployment and lifecycle work today.

Let me begin by answering: what exactly is this engine? It's simply a computation + cache layer that lives in the same process as the calling code, not a server on its own.

Think of a LinkedQL instance (new PGClient()) and its concept of a "Live Query" engine as simply a query client (e.g. new pg.Client()) with an in-memory compute + cache layer.

---

1. Deployment model (current state)

The Live Query engine runs as part of your application process — the same place you’d normally run a Postgres/MySQL client.

For Postgres, yes: it uses one logical replication slot per LinkedQL engine instance. The live query engine instantiates on top of that slot and uses internal "windows" to dedupe overlapping queries, so 500 queries that are only variations of "SELECT * FROM users" still map to one main window; and 500 of such "windows" still run over the same replication slot.

The concept of query windows and the LinkedQL inheritance model is fully covered here: https://linked-ql.netlify.app/engineering/realtime-engine

---

2. Do all live queries “live” on one machine?

As hinted at above, yes; each LinkedQL instance (new PGClient()) runs on the same machine as the running app (just as you'd have it with new pg.Client()) – and maps to a single Live Query engine under the hood.

  That engine uses a single replication slot. You specify the slot name like:

  new PGClient({ ..., walSlotName: 'custom_slot_name' }); // default is: "linkedql_default_slot" – as per https://linked-ql.netlify.app/docs/setup#postgresql

  A second LinkedQL instance would require another slot name:
  
  new PGClient({ ..., walSlotName: 'custom_slot_name_2' });
We’re working toward multi-instance coordination (multiple engines sharing the same replication stream + load balancing live queries). That’s planned, but not started yet.

---

3. Lifecycle of live queries

The Live Query engine runs on-demand and not indefinitely. It begins to exist when at least one client subscribes ({ live: true }) and effectively cleans up and disappears the moment the last subscriber disconnects (result.abort()). Calling client.disconnect() also ends all subscriptions and does clean up.

---

4. Deployments / code changes

Deploying new code doesn’t require “migrating” live queries.

When you restart the application:

• the Live Query starts on a clean slate with the first subscribing query (client.query('...', { live: true })).

• if you have provided a persistent replication slot name (the default being ephemeral), LinkedQL moves the position to the slot's current position and runs from there.

In other words: nothing persists across deploys; everything starts clean as your app starts.

---

5. Diagram / docs

A deployment diagram is a good idea — I’ll add one to the docs.

---

Well, I hope that helps — and no worries about the questions. This space is hard, and happy to explain anything in more detail.

sureglymop|2 months ago

Does it have an "optimization step" where it e.g. groups multiple queries into the same transactions and things of that nature?

stephen|2 months ago

Thanks for the reply! That all makes sense!

As a potential user, I'd probably be thinking through things like: if I have a ~small-fleet of 10 ECS tasks serving my REST/API endpoints, would I run `client.query`s on these same machines, or would it be better to have a dedicated pool of "live query" machines that are separate from most API serving, so that maybe I get more overlap of inherited queries.

...also I think there is a limit on WAL slots? Or at least I'd probably want not each of my API servers to be consuming their own WAL slots.

Totally makes sense this is all "things you worry about later" (where later might be now-/soon-ish) given the infra/core concepts you've got working now -- looking really amazing!