announcements

flowthing 2025-10-30T07:26:41.645639Z

Initial alpha release (2025-10-30.9-alpha) of https://github.com/eerohele/muutos, a zero-dependency library for reacting to changes in your PostgreSQL database. You give Muutos a callback function. Muutos subscribes to a PostgreSQL logical replication stream and calls your callback function on every logical replication message PostgreSQL sends it. You can use https://www.postgresql.org/docs/current/logical-replication-publication.html to specify which changes you're interested in. Muutos uses the pgoutput logical decoding output plugin built into PostgreSQL, and therefore requires no additional dependencies on the PostgreSQL server, either. See the https://github.com/eerohele/muutos/blob/main/README.md#example for a minimal example of what using Muutos looks like, and the https://github.com/eerohele/muutos/blob/main/docs/INDEX.md#rationale.

👍 13
👍🏽 1
👀 1
🔥 11
🎉 11
flowthing 2025-11-04T11:34:38.243909Z

(I added a brief note on reliability under Rationale.)

DenisMc 2025-11-23T20:46:12.517379Z

Looking into muutos, looks great. Quick question if I may. I’m looking to enable server sent events for users, and the events are trigered on update to a particular table. Different SSE sessions for different users will be connected to different K8s pods in my architecture. In this design, do I need to create a replication slot per pod (e.g. if I have 3 pods I need 3 slots, so the particular pod that a user happens to be connected to, can see the updates of interest and ignore/ack the rest) - or is there some other pattern that I haven’t thought of that works for this sort of architecture?

flowthing 2025-11-24T07:09:32.678369Z

Having a replication slot per pod is one option. However, it's not necessarily very scalable (what if there's a traffic spike and you need more than three pods, for example?). Also, three (permanent) replication slots will obviously consume more disk space and other resources on the database server. Another option would be to put a separate pod running Muutos between the database and the web app pods, and have the Muutos pod propagate changes to the web app pods. The method of communication between the Muutos pod and the web app pods depends on your existing infrastructure. For example, if you're already running some sort of message queue, you could use that. Otherwise, you could look into using SSE there as well, or have the Muutos pod https://clojure.org/reference/repl_and_main#_launching_a_socket_server and ship EDN or Transit to the web app pods, or some other method. In any case, you might want to look into whether https://www.postgresql.org/docs/current/functions-admin.html#PG-CREATE-LOGICAL-REPLICATION-SLOT are suitable for your use case (to moderate resource use on the database server). Also, you'll probably want to https://www.morling.dev/blog/mastering-postgres-replication-slots/#_use_column_and_row_filters at the publication level (exclude irrelevant columns and rows).

DenisMc 2025-11-24T07:19:55.866189Z

Thanks for the comprehensive reply, much appreciated.

👍 1
flowthing 2025-11-24T07:40:46.004969Z

If you decide to proceed with Muutos and hit any roadblocks (or successes 🙂), I'd be interested in hearing about them!

tatut 2025-10-30T08:34:47.835269Z

so you are speaking pg wire protocol directly? (zero deps would suggest that)

flowthing 2025-10-30T08:35:01.662859Z

Yes.

tatut 2025-10-30T08:35:34.518349Z

nice, this will come in handy with Ripley

👍 2
flowthing 2025-10-30T08:36:43.164439Z

Very interested in hearing how it goes! And if you hit any roadblocks.

tatut 2025-10-30T09:35:26.957919Z

the main thing of interest is how fast the replication callbacks come... like is it fast enough for "real time" work

igrishaev 2025-10-30T09:39:58.860799Z

It's a real Postgres client written from scratch. Cool!

👍 3
flowthing 2025-10-30T09:43:06.412889Z

PostgreSQL sends the logical replication message immediately once a transaction has successfully committed (and only if it does commit successfully -- if it is rolled back, PostgreSQL doesn't send a message). I don't think there's a faster approach for real-time work.

flowthing 2025-10-30T09:48:46.344949Z

Also, pgoutput emits binary data, so decoding it is quite fast.

flowthing 2025-10-30T10:04:16.799839Z

> It's a real Postgres client written from scratch. Cool! It's certainly drawn inspiration from pg/pg2, so kudos for making them. 🙂 Before seeing them, I didn't know anything about the PostgreSQL wire protocol.

ts1503 2025-10-30T10:09:01.224029Z

is it a replacement for Debezium?

flowthing 2025-10-30T10:12:59.600419Z

Certainly not a replacement for Debezium proper, since Debezium includes/requires Kafka Connect and has way more features (and introduces way more operational overhead). 🙂 Perhaps a (Clojure-oriented) alternative to https://debezium.io/documentation/reference/stable/development/engine.html. Check out the documentation for more details.

flowthing 2025-10-30T10:26:19.215669Z

I see Muutos more as a building block in your own change data capture solution.

Dustin Getz (Hyperfiddle) 2025-10-30T10:30:35.027219Z

dude amazing

🙏 1
tatut 2025-10-30T10:58:23.151719Z

the pg wire protocol is actually pretty nice as binary protocols go, I recently did stuff with it for xtdb 2

flowthing 2025-10-30T10:58:40.527089Z

Definitely, no complaints. 👍

Eugen 2025-11-03T20:18:17.755049Z

nice, we have a use case where we need to sync a PostgreSQL table to an ElasticSearch index - so this seems like a good fit. what happens to the events if you client is down ? If I remember my PostgreSQL logical replication, the WALL files (and events) should pile up on disk untill they are processed. If this is true, it means you should not lose any events / data. Can you please confirm? This info would best be put in the docs - I think it's important.

Eugen 2025-11-03T20:19:07.487929Z

(reading the rationale now - it might be explained there 😄 )

flowthing 2025-11-03T20:35:12.510709Z

nice, we have a use case where we need to sync a PostgreSQL table to an ElasticSearch index - so this seems like a good fit.Yes, this is precisely the sort of problem Muutos is designed to solve. Making any kind of derived view into the data in your PostgreSQL database, informing downstream consumers (e.g. via a message queue), etc. > what happens to the events if you client is down ? PostgreSQL retains WAL entries until the replication slot consumer (i.e. Muutos) has sent it an acknowledgement message saying that it has successfully processed them. That happens when you call the ack function that is the second argument to the handler function you give Muutos. > If this is true, it means you should not lose any events / data. Correct, you will not lose any data. This is in contrast to LISTEN/NOTIFY. If you NOTIFY but no one's LISTENing, PostgreSQL will discard the message. > This info would best be put in the docs - I think it's important. I don't recall whether I mention that explicitly in the docs. The docs might assume some sort of familiarity with logical replication. I'll double-check when I get the chance -- thanks for the suggestion. 👍

❤️ 1
Roman Liutikov 2025-10-30T13:24:17.906229Z

🎙️ State of ClojureScript 2025 Survey is live https://state-of-clojurescript.com/ The survey goes in-depth on how people use ClojureScript to build stuff. If you ever wondered what's happening in cljs world, this is your chance to contribute and learn back from the community. Take a few minutes to fill out the survey and share it in your circles. Results will be shared in January, 2026. This year's survey is updated based on feedback from last year survey respondents. 2024 survey results can be viewed here https://state-of-clojurescript.com/2024

6
🙏 2
✅ 8
srihari 2025-10-30T15:18:34.636929Z

I wanted a way to see what’s in my context. Both when doing agentic code search, and when building AI applications. “Design is about pulling things apart”. But there appears to be no “pulling apart” of the LLM’s context, even though there’s a lot of talk about “context engineering”. So I built a tool that does this: https://github.com/nilenso/context-viewer It’s not Clojure (happy to remove this post if it’s not relevant for this reason) but it’s still been super interesting for me to build this. I especially like how UI, and processes such as this are becoming malleable with AI capabilities. It’s like realising that “programmable by product people” goals that seemed un-attainable with even fancy UIs.

❤️ 4
srihari 2025-10-30T15:18:52.721899Z

The blog post has a lot more detail: https://blog.nilenso.com/blog/2025/10/29/fight-context-rot-with-context-observability/

seancorfield 2025-10-30T15:51:40.684199Z

Given that nilenso is fairly Clojure-centric as a company (at least, that's my impression from libraries and posts here), I'm curious why you went with TS?

srihari 2025-10-30T16:02:53.827239Z

Ohey @seancorfield, good question. Yes, we still write quite a bit of production Clojure at nilenso. • I wanted something browser-first, and without a backend component, for privacy sake. So it had to be something that compiled down to JS. • Secondly, from what I’ve seen, LLMs have been much better at generating TS when compared to clojurescript. • Thirdly, this is a bit of an exploratory project. If I were to do this seriously, and for scale, I would reexamine my tech stack.

srihari 2025-10-30T16:04:12.725949Z

I’ve managed to capture almost all my prompts https://github.com/nilenso/context-viewer/blob/main/docs/prompts.md, so I might just indulge in changing the https://github.com/nilenso/context-viewer/blob/main/docs/tech-stack.md, and redoing all this with cljs 😁

seancorfield 2025-10-30T16:16:13.440419Z

Maybe a good opportunity to try Squint? 😄

💯 3
Larry Jones 2025-10-30T16:38:55.511919Z

+1 for implementing in ClojureScript (but I’m biased).

phronmophobic 2025-10-30T17:27:27.577889Z

> • I wanted something browser-first, and without a backend component, for privacy sake. So it had to be something that compiled down to JS. Why browser-first? Is it because of familiarity with the tech stack? What about a desktop app? > Observability for contexts. Given a coversation log (messages), this tool will provide a breakdown of its components and their sizes. What do you mean by size? Is that just token count or are there other measures? I believe token counts can be done locally without a provider.

srihari 2025-10-30T17:44:37.136919Z

> Why browser-first? Is it because of familiarity with the tech stack? What about a desktop app? Well, I just wanted to prioritise the user interface, because it’s important for observability to be able to visualise the slices and dices. I guess it could be a desktop app too. > What do you mean by size? Is that just token count or are there other measures? I believe token counts can be done locally without a provider. Yeah, token counts are done using tiktoken, no AI there. It’s the “pulling apart” that needs some AI to chunk all the text in the context to meaningful components. That blog post I linked to above has some videos that show what it can do.

phronmophobic 2025-10-30T17:46:51.907429Z

oh ok. I'll check out the blog post 👍 . I suspect you could also do that locally if you have a GPU (or are verrry patient).

srihari 2025-10-30T17:47:34.168759Z

Ha yes, I’ve mentioned that you could definitely run this against a local model. It doesn’t need very fancy big model skills. gpt-oss models might suffice.

2025-10-30T21:17:32.389859Z

Did you know that CUDA has been available in Clojure for the last 9 years, and GPU programming through OpenCL for more than 10? I almost forgot about these anniversaries. Why not celebrate that by opening the REPL, and coding your first Hello World application on the GPU? https://dragan.rocks/articles/25/Get-Ready-Clojure-GPU-AI-2026-CUDA-13

27
13
🚀 16
Pavel Filipenco 2025-12-01T12:24:36.433019Z

@blueberry have you tried it out on your machine?

2025-11-18T10:55:54.237029Z

reminder

👍 1
Pavel Filipenco 2025-11-18T13:20:42.235179Z

cruel shifts as a barista 🥲

Pavel Filipenco 2025-11-18T14:08:27.384709Z

Here you go @blueberry. Sorry that it's a zip file and not some repo, I don't know how ok it is to upload the onnx model and video file used for the example to github. Nix flake included, even though you probably won't be able to use it since cloudflare is down and cachix relies on that. Steps: 1. Jack in with cider 2. Eval example.clj file 3. Eval the expressions in the comment form step by step 4. There's a comment saying when to run inspect and what exactly to click in the inspector window. Hopefully you'll be able to reproduce it on your machine!

Pavel Filipenco 2025-11-16T18:03:03.693989Z

When I tried to inspect the seemingly "2 values" output from the function that is returned when calling the network on input-tz, REPL crashed. Is that because it's huge, or because it's actually 2 values? how even

Pavel Filipenco 2025-11-16T18:03:54.211609Z

Apparently that's how it prints tensors: a map with some arbitrary amount of values after it

2025-11-16T23:06:39.284149Z

Can you share a minimal project with example code that crashes the repl, so I can test it and see what might be the issue?

👍 1
Pavel Filipenco 2025-11-17T06:36:17.982169Z

yes, when i get home