{"id":28387344,"url":"https://github.com/event-driven-io/blumchen","last_synced_at":"2025-09-08T18:32:44.239Z","repository":{"id":79310898,"uuid":"264643176","full_name":"event-driven-io/Blumchen","owner":"event-driven-io","description":"Blumchen - Push-based Outbox for PostgreSQL","archived":false,"fork":false,"pushed_at":"2024-10-24T11:47:15.000Z","size":144,"stargazers_count":100,"open_issues_count":16,"forks_count":13,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-06T20:54:28.108Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/event-driven-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["event-driven-io"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-05-17T10:58:24.000Z","updated_at":"2025-05-30T05:59:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"f721233b-dab3-4482-98c7-0eb3b8d83865","html_url":"https://github.com/event-driven-io/Blumchen","commit_stats":null,"previous_names":["event-driven-io/blumchen"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/event-driven-io/Blumchen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/event-driven-io%2FBlumchen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/event-driven-io%2FBlumchen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/event-driven-io%2FBlumchen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/event-driven-io%2FBlumchen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/event-driven-io","download_url":"https://codeload.github.com/event-driven-io/Blumchen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/event-driven-io%2FBlumchen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274229373,"owners_count":25245188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-30T17:11:29.987Z","updated_at":"2025-09-08T18:32:44.213Z","avatar_url":"https://github.com/event-driven-io.png","language":"C#","funding_links":["https://github.com/sponsors/event-driven-io"],"categories":[],"sub_categories":[],"readme":"# Blumchen - Push-based Outbox for PostgreSQL\nOutbox Pattern with CDC and .NET based on [Postgres logical replication](https://www.postgresql.org/docs/current/logical-replication.html) with [Npgsql integration](https://www.npgsql.org/doc/replication.html).\n\nRead more details in:\n- [Push-based Outbox Pattern with Postgres Logical Replication](https://event-driven.io/en/push_based_outbox_pattern_with_postgres_logical_replication/?utm_source=github_outbox_cdc).\n- [How to get all messages through Postgres logical replication](https://event-driven.io/en/how_to_get_all_messages_through_postgres_logical_replication/?utm_source=github_outbox_cdc).\n\n## Features:\n\n- Publication filter [is enabled](https://www.postgresql.org/docs/current/sql-createpublication.html#SQL-CREATEPUBLICATION-WITH) to trigger only INSERTed rows;\n- AOT compliant compilation enforced by design\n\nMain logic is placed in [EventsSubscription](./src/Blumchen/Subscriptions/Subscription.cs).\n\n## Running source code locally\n\n1. Start Postgres with WAL enabled from Docker image.\n```shell\ndocker-compose up\n```\n2. Run(order doesn't matter) Publisher and Subscriber apps, under 'demo' folder, from vs-studio, and follow Publisher instructions.\n\n## Testing (against default docker instance)\n\nRun tests\n```shell\ndotnet test\n```\n\n## Links\n\n### Postgres Logical Replication\n- [Postgres Docs - Postgres logical replication](https://www.postgresql.org/docs/current/logical-replication.html)\n- [Npgsql - Logical Replication](https://www.npgsql.org/doc/replication.html)\n- [Robert Treat - Logical Replication...LIVE!](https://www.youtube.com/watch?v=YpsJu2mtBKA)\n- [Dmitry Narizhnykh - PostgreSQL Change Data Capture and Golang Sample Code](https://hackernoon.com/postgresql-change-data-capture-and-golang-sample-code)\n\n### WAL\n- [Devrim Gündüz -WAL: Everything you want to know](https://www.youtube.com/watch?v=feTihjJJs3g)\n- [Postgres Documentation - Write Ahead Log](https://www.postgresql.org/docs/13/runtime-config-wal.html)\n- [The Internals of PostgreSQL - Write Ahead Logging — WAL](https://www.interdb.jp/pg/pgsql09.html)\n- [Hevo - Working With Postgres WAL Made Easy](https://hevodata.com/learn/working-with-postgres-wal/)\n\n### Logical Replication\n\n#### General Introduction\n- [Gunnar Morling - The Wonders of Postgres Logical Decoding Messages](https://www.infoq.com/articles/wonders-of-postgres-logical-decoding-messages/)\n- [Gunnar Morling - Open-source Change Data Capture With Debezium - video](https://www.youtube.com/watch?v=G7TvRzPQH-U)\n- [Gunnar Morling - Open-source Change Data Capture With Debezium - slides](https://speakerdeck.com/gunnarmorling/open-source-change-data-capture-with-debezium?slide=21)\n- [Several9s - Using PostgreSQL Logical Replication to Maintain an Always Up-to-Date Read/Write TEST Server](https://severalnines.com/blog/using-postgresql-logical-replication-maintain-always-date-readwrite-test-server/)\n- [Matt Tanner - PostgreSQL CDC: A Comprehensive Guide](https://www.arcion.io/learn/postgresql-cdc)\n\n#### Other\n- [Dmitry Narizhnykh - PostgreSQL Change Data Capture and Golang Sample Code](https://hackernoon.com/postgresql-change-data-capture-and-golang-sample-code)\n- [Fujistsu - How PostgreSQL 15 improved communication in logical replication](https://www.postgresql.fastware.com/blog/how-postgresql-15-improved-communication-in-logical-replication)\n- [Kinsta - PostgreSQL Replication: A Comprehensive Guide](https://kinsta.com/blog/postgresql-replication/)\n- [Amit Kapila  - Replication Improvements In PostgreSQL-14](https://amitkapila16.blogspot.com/2021/09/logical-replication-improvements-in.html)\n- [Postgresql Wiki - Logical Decoding Plugins](https://wiki.postgresql.org/wiki/Logical_Decoding_Plugins)\n- [Npgsql - Logical Replication](https://www.npgsql.org/doc/replication.html)\n- [Konstantin Evteev - Recovery use cases for Logical Replication in PostgreSQL 10](https://medium.com/avitotech/recovery-use-cases-for-logical-replication-in-postgresql-10-a1e6bab03072)\n- [EDB - PostgreSQL Write-Ahead Logging (WAL) Trade-offs: Bounded vs. Archived vs. Replication Slots](https://www.enterprisedb.com/blog/postgresql-wal-write-ahead-logging-management-strategy-tradeoffs)\n- [Percona - The 1-2-3 for PostgreSQL Logical Replication Using an RDS Snapshot](https://www.percona.com/blog/postgresql-logical-replication-using-an-rds-snapshot/)\n- [2nd Quadrant - Basics of Tuning Checkpoints](https://www.2ndquadrant.com/en/blog/basics-of-tuning-checkpoints/)\n- [Thiago - How to use Change Data Capture (CDC) with Postgres](https://dev.to/thiagosilvaf/how-to-use-change-database-capture-cdc-in-postgres-37b8)\n- [Ramesh naik E - Change Data Capture(CDC) in PostgreSQL](https://medium.com/@ramesh.esl/change-data-capture-cdc-in-postgresql-7dee2d467d1b)\n- [Wal2Json - JSON output plugin for changeset extraction](https://github.com/eulerto/wal2json)\n- [AWS Database Blog - Using logical replication to replicate managed Amazon RDS for PostgreSQL and Amazon Aurora to self-managed PostgreSQL](https://aws.amazon.com/blogs/database/using-logical-replication-to-replicate-managed-amazon-rds-for-postgresql-and-amazon-aurora-to-self-managed-postgresql/)\n- [AWS Database Blog - Stream changes from Amazon RDS for PostgreSQL using Amazon Kinesis Data Streams and AWS Lambda](https://aws.amazon.com/blogs/database/stream-changes-from-amazon-rds-for-postgresql-using-amazon-kinesis-data-streams-and-aws-lambda/)\n- [PGDeltaStream - Streaming Postgres logical replication changes atleast-once over websockets](https://github.com/hasura/pgdeltastream)\n- [Hrvoje Milković - Replicate PostreSQL data to Elasticsearch via Logical replication slots](http://staging.kraken.hr/blog/2018/postgresql-replication-elasticsearch)\n- [Azure - Azure Database for PostgreSQL : Logical Replication](https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/azure-database-for-postgresql-logical-replication/ba-p/3799509)\n- [Azure Database for PostgreSQL—Logical decoding and wal2json for change data capture](https://azure.microsoft.com/en-us/updates/azure-database-for-postgresql-logical-decoding-and-wal2json-for-change-data-capture/)\n- [Amit Langote - Postgresql To Kinesis For Java - Disney Streaming](https://github.com/disneystreaming/pg2k4j)\n\n#### Queue\n- [Adriano Caloiaro - Choose Postgres queue technology](https://adriano.fyi/posts/2023-09-24-choose-postgres-queue-technology/)\n\n#### Performance\n- [2ndQuadrant - Performance limits of logical replication solutions](https://www.2ndquadrant.com/en/blog/performance-limits-of-logical-replication-solutions/)\n- [Some benchmarking techniques](https://fluca1978.github.io/2021/07/15/PostgreSQLWalTraffic2.html)\n\n#### Snapshots\n- [Christos Christoudias - Creating a Logical Replica from a Snapshot in RDS Postgres](https://tech.instacart.com/creating-a-logical-replica-from-a-snapshot-in-rds-postgres-886d9d2c7343)\n\n#### Ordering\n- [Virender Singla - Postgres — Logical Replication and long running transactions](https://virender-cse.medium.com/postgres-logical-replication-and-long-running-transactions-81a69b7ac470)\n- [Ordering with Advisory Locks](https://www.postgresql.org/message-id/CACjxUsMKA6k-mDOdkos3k0i-KE4HFRwkd=PXPArYy4UabTd-LA@mail.gmail.com)\n\n#### Partitioning\n- [Postgres: partitioned tables can now be replicated](https://amitlan.com/2020/05/14/partition-logical-replication.html)\n\n### Locks\n- [Depesz - Picking task from queue – revisit](https://www.depesz.com/2016/05/04/picking-task-from-queue-revisit/)\n- [Alvaro Herrera - Waiting for 9.5 – Implement SKIP LOCKED for row-level locks](https://www.depesz.com/2014/10/10/waiting-for-9-5-implement-skip-locked-for-row-level-locks/)\n- [Chris Hanks - Turning PostgreSQL into a queue serving 10,000 jobs per second](https://gist.github.com/chanks/7585810)\n- [Vlad Mihalcea - How do PostgreSQL advisory locks work](https://vladmihalcea.com/how-do-postgresql-advisory-locks-work/)\n- [Marco Slot - When Postgres blocks: 7 tips for dealing with locks](https://www.citusdata.com/blog/2018/02/22/seven-tips-for-dealing-with-postgres-locks/)\n- [Marco Slot - PostgreSQL rocks, except when it blocks: Understanding locks](https://www.citusdata.com/blog/2018/02/15/when-postgresql-blocks/)\n- [Nickolay Ihalainen - PostgreSQL locking, Part 1: Row Locks](https://www.percona.com/blog/2018/10/16/postgresql-locking-part-1-row-locks/)\n- [Nickolay Ihalainen - PostgreSQL locking, part 2: heavyweight locks](https://www.percona.com/blog/2018/10/24/postgresql-locking-part-2-heavyweight-locks/)\n- [Nickolay Ihalainen - PostgreSQL locking, part 3: lightweight locks](https://www.percona.com/blog/2018/10/30/postgresql-locking-part-3-lightweight-locks/)\n\n### Outbox implementations\n- [Robert Kawecki - esdf2-eventstore-pg](https://github.com/rkaw92/esdf2-eventstore-pg/blob/a49f88cd1f10d4f06a12ef0982293a8c7abb4ff9/src/PostgresEventStore.ts#L116)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevent-driven-io%2Fblumchen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevent-driven-io%2Fblumchen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevent-driven-io%2Fblumchen/lists"}