PHPackages                             utopia-php/replication - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. utopia-php/replication

ActiveLibrary[Database &amp; ORM](/categories/database)

utopia-php/replication
======================

A Swoole-native MySQL binlog replication reader for streaming row changes (CDC)

00PHP

Since Jun 19Pushed todayCompare

[ Source](https://github.com/utopia-php/replication)[ Packagist](https://packagist.org/packages/utopia-php/replication)[ RSS](/packages/utopia-php-replication/feed)WikiDiscussions main Synced today

READMEChangelog (2)DependenciesVersions (1)Used By (0)

Utopia Replication
==================

[](#utopia-replication)

Important

This repository is a read-only mirror of the [utopia-php monorepo](https://github.com/utopia-php/monorepo). Development happens in [`packages/replication`](https://github.com/utopia-php/monorepo/tree/main/packages/replication) — please open issues and pull requests there.

[![Build Status](https://github.com/utopia-php/replication/actions/workflows/tests.yml/badge.svg)](https://github.com/utopia-php/replication/actions/workflows/tests.yml)[![Total Downloads](https://camo.githubusercontent.com/891d58e8c63709b9dfd39df2d645609164a3bd33f0a8cc231c45d2351d752e52/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f75746f7069612d7068702f7265706c69636174696f6e2e737667)](https://camo.githubusercontent.com/891d58e8c63709b9dfd39df2d645609164a3bd33f0a8cc231c45d2351d752e52/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f75746f7069612d7068702f7265706c69636174696f6e2e737667)[![Discord](https://camo.githubusercontent.com/6e418910df1b6eb524c6cbd88dbaf5a5aa294316eeadcd963e11262a319f6321/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3536343136303733303834353135313234343f6c6162656c3d646973636f7264)](https://appwrite.io/discord)

Utopia Replication is a Swoole-native MySQL binlog reader. It streams row-level changes (change data capture) from a MySQL server over the replication protocol, so a consumer can react to writes — invalidate caches, build projections, fan out events — by tailing a server locally instead of relying on application-level messaging. This library is maintained by the [Appwrite team](https://appwrite.io).

Although this library is part of the [Utopia Framework](https://github.com/utopia-php/framework) project it is dependency free and can be used as standalone with any other PHP project or framework.

Getting Started
---------------

[](#getting-started)

Install using composer:

```
composer require utopia-php/replication
```

System Requirements
-------------------

[](#system-requirements)

Utopia Replication requires PHP 8.3 or later, and the [Swoole](https://github.com/swoole/swoole-src) extension (&gt;=6.0) for coroutine socket I/O. The [OpenSSL](https://www.php.net/manual/en/book.openssl.php) extension is required for `caching_sha2_password` full authentication and TLS.

### Source server

[](#source-server)

The MySQL source must be configured for GTID-based row replication:

```
binlog_format       = ROW
gtid_mode           = ON
enforce_gtid_consistency = ON
binlog_row_metadata = FULL   # optional: ships column names in the stream
```

`binlog_row_metadata = FULL` lets column names ride along in the binlog. When it is `MINIMAL` (the MySQL default, and what some managed providers are fixed to) the reader resolves names from `INFORMATION_SCHEMA` over a second connection instead — no configuration change required.

The connecting user needs the `REPLICATION SLAVE` and `REPLICATION CLIENT` privileges.

Usage
-----

[](#usage)

```
use Utopia\Replication\Adapter;
use Utopia\Replication\Adapter\MySQL;

// Adapter is the polymorphic interface; MySQL is the binlog implementation.
$replication = new MySQL(
    host: '127.0.0.1',
    port: 3306,
    username: 'replicator',
    password: 'secret',
    serverId: 1001,            // unique among replicas
    schema: 'appwrite',        // only emit changes for this database
    ssl: false,                // when true, TLS verifies the server cert by default
);

$replication->start($checkpoint ?? null);  // resume from a GTID set, or null for "now"

foreach ($replication->getChanges() as $change) {
    // $change->action  — Change::INSERT | UPDATE | DELETE
    // $change->table   — physical table name
    // $change->rows    — list of column => value maps (after-image for updates)
    // $change->gtid    — executed-GTID-set checkpoint (advance on commit)

    foreach ($change->rows as $row) {
        // react to the change ...
    }

    $checkpoint = $change->gtid;     // persist to resume after a restart
}
```

The reader runs inside a Swoole coroutine; `getChanges()` blocks (yielding the coroutine) while waiting for events. The GTID checkpoint advances on transaction commit, so a crash mid-transaction re-streams it — treat changes as idempotent.

Scope
-----

[](#scope)

Deliberately minimal: MySQL 8, ROW-format binlog, and the event types needed for CDC (TABLE\_MAP, WRITE/UPDATE/DELETE\_ROWS, GTID, ROTATE, XID). JSON column values are skipped (bytes advanced, not decoded). Column names come from FULL row metadata when available, otherwise from a single cached `INFORMATION_SCHEMA`lookup per table.

Tests
-----

[](#tests)

```
composer test        # unit (pure decoders — no server needed)
docker compose up -d --wait
composer test:e2e    # against a real MySQL 8 (basic CRUD, >16MiB rows,
                     # caching_sha2 full-auth, TLS)
```

Copyright and license
---------------------

[](#copyright-and-license)

The MIT License (MIT)

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/22452787?v=4)[Luke B. Silver](/maintainers/loks0n)[@loks0n](https://github.com/loks0n)

---

Top Contributors

[![loks0n](https://avatars.githubusercontent.com/u/22452787?v=4)](https://github.com/loks0n "loks0n (3 commits)")

### Embed Badge

![Health badge](/badges/utopia-php-replication/health.svg)

```
[![Health](https://phpackages.com/badges/utopia-php-replication/health.svg)](https://phpackages.com/packages/utopia-php-replication)
```

###  Alternatives

[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k116.5M113](/packages/jdorn-sql-formatter)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8351.6M87](/packages/propel-propel1)[yemenopensource/filament-excel

This package useful for importing excel files into models.

194.2k](/packages/yemenopensource-filament-excel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
