PHPackages                             elriseio/doctrine-shard-manager-bundle - 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. elriseio/doctrine-shard-manager-bundle

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

elriseio/doctrine-shard-manager-bundle
======================================

Symfony bundle for horizontal data sharding on top of Doctrine ORM and DBAL with pluggable strategies (hash, range, UUIDv7), transparent routing and PSR-6 cache layer.

v1.0.2(2d ago)00MITPHPPHP &gt;=8.3

Since Jul 21Pushed todayCompare

[ Source](https://github.com/elriseio/doctrine-shard-manager-bundle)[ Packagist](https://packagist.org/packages/elriseio/doctrine-shard-manager-bundle)[ Docs](https://github.com/elriseio/doctrine-shard-manager-bundle)[ RSS](/packages/elriseio-doctrine-shard-manager-bundle/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (11)Versions (3)Used By (0)

Doctrine Shard Manager Bundle for Symfony
=========================================

[](#doctrine-shard-manager-bundle-for-symfony)

[![CI](https://github.com/elriseio/doctrine-shard-manager-bundle/actions/workflows/itests-smoke.yml/badge.svg)](https://github.com/elriseio/doctrine-shard-manager-bundle/actions/workflows/itests-smoke.yml)[![Latest Stable Version](https://camo.githubusercontent.com/808f1f6b56eff6e64d8bb10490668046c30ef81c16352aefdd50d0a7d6a2a74f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f656c72697365696f2f646f637472696e652d73686172642d6d616e616765722d62756e646c652e737667)](https://packagist.org/packages/elriseio/doctrine-shard-manager-bundle)[![Total Downloads](https://camo.githubusercontent.com/4903c6c1af505e0dc6a47f3dfe3e49aad4aeecbe944c12696947742bb8e035e6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f656c72697365696f2f646f637472696e652d73686172642d6d616e616765722d62756e646c652e737667)](https://packagist.org/packages/elriseio/doctrine-shard-manager-bundle)[![License](https://camo.githubusercontent.com/7654552768778f9acf67bda26af19c756ab4a21bc9c1089ffe492799c839c34f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f656c72697365696f2f646f637472696e652d73686172642d6d616e616765722d62756e646c652e737667)](https://github.com/elriseio/doctrine-shard-manager-bundle/blob/master/LICENSE)

**Doctrine Shard Manager Bundle** is a Symfony bundle for horizontal data sharding on top of Doctrine ORM and DBAL. The bundle provides transparent routing of `Connection` and `EntityManager` per shard, pluggable resolution strategies (`hash`, `range`, `uuidv7`), a PSR-6 cache layer, and a CLI for greenfield provisioning and additive migrations.

Key Features
------------

[](#key-features)

- **Transparent sharding.** Callers write `ShardedRepository` calls or `ShardContext::withShard()` / `withEntity()` callbacks; the bundle selects the right `Connection` and `EntityManager` for the entity being touched.
- **Pluggable strategies.** Three concrete strategies ship out of the box — `hash` (SHA-256 modulo), `range` (binary search over a `range_table` partition), `uuid` (UUIDv7 with embedded shard index). Custom strategies register via the `app.shard_strategy` tag (see ADR-0002).
- **Dual configuration surface.** PHP `#[Sharding]` attribute on the entity class, OR YAML under `doctrine_shard.sharding_configs.`. Resolution precedence is YAML &gt; attribute (see `docs/architecture.md::I-RES1`).
- **Cache-first resolution.** Optional PSR-6 `CacheItemPoolInterface` per strategy and per resolver; cache failures degrade gracefully (logged + bypassed, never propagated).
- **Cross-shard reads.** `ShardedFinder::find(callable $query, array $shardIds)` fans out a read query to multiple shards lazily via `\Generator` (see ADR-0004).
- **Schema bootstrap.** `bin/console shard:add ` provisions a shard's schema from filtered entity metadata. `bin/console shard:migrate ` runs Doctrine Migrations on a single named shard and is additive (see ADR-0003).
- **Doctrine 3.3 + DBAL 4.2 compatibility**, PHP 8.3 strict types.

Architecture
------------

[](#architecture)

```
             +--------------------------+
             |   Symfony Application    |
             |     (consumer code)      |
             +------------+-------------+
                          |
               uses interfaces in src/Contract/
                          |
             +------------v-------------+
             |  ShardContext /          |
             |  ShardedRepository       |
             |  ShardedFinder (read)    |
             +------------+-------------+
                          |
             +------------v-------------+
             |   ShardResolver          |    true],
```

The bundle reads its configuration from `config/packages/doctrine_shard.yaml` (see [Configuration](#configuration) below) and registers all six public services automatically. No additional `services.yaml` wiring is required for the default strategies.

Configuration
-------------

[](#configuration)

`config/packages/doctrine_shard.yaml` example for a four-shard hash setup keyed by `userId`:

```
doctrine_shard:
  cache_ttl: 86400

  shard:
    hash:
      total_shards: 4
      shard_index_offset: 0
      shard_prefix: 'shard_'
    range:
      shard_prefix: 'shard_'
      shard_index_offset: 0
      range_table:
        - { min: 0,   max: 999_999,    shard: 'shard_0' }
        - { min: 1_000_000, max: 1_999_999, shard: 'shard_1' }
    uuid:
      total_shards: 16
      shard_index_offset: 0
      shard_prefix: 'shard_'
      shard_bits: 4

  sharding_configs:
    App\Entity\User:
      strategy: hash
      key: userId
      shardCount: 4
    App\Entity\Order:
      strategy: uuid
      key: id
      shardCount: 16

  resolver:
    cache:
      enabled: true
      pool_service_id: cache.app

  connections:
    shard_0: '@doctrine.dbal.default_shard_0_connection'
    shard_1: '@doctrine.dbal.default_shard_1_connection'
    shard_2: '@doctrine.dbal.default_shard_2_connection'
    shard_3: '@doctrine.dbal.default_shard_3_connection'

  entity_managers:
    shard_0: '@doctrine.orm.default_shard_0_entity_manager'
    shard_1: '@doctrine.orm.default_shard_1_entity_manager'
    shard_2: '@doctrine.orm.default_shard_2_entity_manager'
    shard_3: '@doctrine.orm.default_shard_3_entity_manager'
```

`doctrine.dbal.default_shard__connection` and `doctrine.orm.default_shard__entity_manager` are the standard Doctrine connection / EM service IDs that Symfony's `doctrine` bundle exposes when you declare `dbal: { connections: { default_shard_0: ~, default_shard_1: ~, ... } }` and `orm: { entity_managers: { default_shard_0: ~, default_shard_1: ~, ... } }` in `config/packages/doctrine.yaml`.

### The `#[Sharding]` attribute (alternative to YAML)

[](#the-sharding-attribute-alternative-to-yaml)

```
use Elrise\Bundle\DoctrineShardManager\Attribute\Sharding;

#[Sharding(
    strategy: 'hash',
    key: 'userId',
    shardCount: 4,
)]
class User
{
    // ...
}
```

The `key` parameter may also be `string[]` for composite keys:

```
#[Sharding(
    strategy: 'hash',
    key: ['tenantId', 'userId'],
    shardCount: 4,
)]
class User
{
    // ...
}
```

YAML `sharding_configs.` overrides the attribute when both are present.

Usage
-----

[](#usage)

### Through `ShardContext`

[](#through-shardcontext)

```
use Elrise\Bundle\DoctrineShardManager\Context\ShardContext;

final class UserService
{
    public function __construct(private ShardContext $shardContext) {}

    public function loadFromShard(int $userId): ?User
    {
        return $this->shardContext->withEntity(
            $this->buildStubUser($userId),
            function (EntityManagerInterface $em, string $shardId) use ($userId): ?User {
                return $em->getRepository(User::class)->find($userId);
            },
        );
    }
}
```

`withShard($shardId, fn)` is the explicit variant when the caller already knows the target shard (e.g. a cron job iterating every shard).

### Through `ShardedRepository`

[](#through-shardedrepository)

```
use Elrise\Bundle\DoctrineShardManager\Repository\ShardedRepository;

final class UserController
{
    public function __construct(private ShardedRepository $userRepo) {}

    public function show(int $userId): Response
    {
        $user = $this->userRepo->findOneById($userId, User::class);

        if (null === $user) {
            throw new NotFoundHttpException();
        }

        return new Response(sprintf('Hello, %s!', $user->getDisplayName()));
    }
}
```

`ShardedRepository::findBy`, `findOneBy`, `persistToShard`, `removeFromShard`, `flushShard` complete the surface; each call resolves the shard ID internally and routes the call to the right `EntityManager`.

### Cross-shard reads with `ShardedFinder`

[](#cross-shard-reads-with-shardedfinder)

```
use Elrise\Bundle\DoctrineShardManager\Finder\ShardedFinder;

final class ReportingService
{
    public function __construct(private ShardedFinder $finder) {}

    public function streamAllActiveUsers(): \Generator
    {
        $shardIds = ['shard_0', 'shard_1', 'shard_2', 'shard_3'];

        return $this->finder->find(
            static fn (Connection $c) => $c->iterateAssociative(
                'SELECT * FROM users WHERE active = 1 ORDER BY id',
            ),
            $shardIds,
        );
    }
}
```

`ShardedFinder` is sequential in v1 (per ADR-0004 §Decision). The generator holds one row at a time across the fan-out, so memory is bounded by the largest single-shard result set. Failures throw with the per-shard context framed in the message.

### Extending with a custom strategy

[](#extending-with-a-custom-strategy)

```
services:
    App\Infrastructure\Sharding\TenantPrefixedStrategy:
        tags:
            - { name: app.shard_strategy, alias: tenant }
```

```
use Elrise\Bundle\DoctrineShardManager\Strategy\AbstractShardStrategy;

final class TenantPrefixedStrategy extends AbstractShardStrategy
{
    #[\Override]
    public function resolveShardId(mixed $key, array $options = []): ?string
    {
        $tenantId = $this->normalizeKey($key);

        return 'tenant_'.$tenantId;
    }
}
```

Then reference it as `strategy: tenant` in `sharding_configs.` or `#[Sharding(strategy: 'tenant', ...)]`. The full worked example is in `docs/adr/0002-shard-strategy-extensibility.md`.

Console commands
----------------

[](#console-commands)

The bundle registers two Symfony Console commands on `build()`:

### `bin/console shard:add `

[](#binconsole-shardadd-id)

Provisions a new shard's schema. Filters entity metadata to `#[Sharding]`-annotated classes only and runs `SchemaTool::updateSchema($filteredMetadata, saveMode: true)`.

```
bin/console shard:add shard_3
```

> **Safety warning.** `shard:add` is **drop-and-recreate**, not additive migration. Run it on **greenfield shards only** — running it on an existing shard deletes the rows. For an existing shard, use `bin/console shard:migrate ` instead (Wave 2 / ADR-0003). See `docs/RUNBOOK.md::Failure Mode 10` for the full migration procedure.

### `bin/console shard:migrate `

[](#binconsole-shardmigrate-id)

Runs Doctrine Migrations on a single named shard. Additive; safe to run against an existing shard.

```
bin/console shard:migrate shard_3
bin/console shard:migrate shard_3 --dry-run            # print the plan without applying
bin/console shard:migrate shard_3 --migration-set=latest  # explicit version alias
```

Each command supports the standard `--dry-run`, `--migration-set=`, and exit-code conventions of the underlying Doctrine Migrations tooling.

Compatibility
-------------

[](#compatibility)

- PHP 8.3+
- Symfony 7.2 (`7.2.*` pin in `composer.json`)
- Doctrine DBAL 4.2+
- Doctrine ORM 3.3+
- Doctrine Migrations 3.7+
- PSR-6 `CacheItemPoolInterface` (optional but recommended for hot-path strategies)
- PSR-3 `LoggerInterface` (optional; graceful degradation when absent)

### Known compatibility gaps

[](#known-compatibility-gaps)

- The `doctrine/event-subscriber` path (modern replacement for the deprecated `ShardResolverListener`) is planned for Wave 1. Until then, the listener remains `@deprecated` but is wired in `services.yaml` for backward compatibility with legacy consumers.
- The three-tier testing infrastructure (unit + bench + itests; ADR-0001) is partially landed. `bench/` and `itests/` are now populated; the bounded-concurrency CI smoke (`DE-011-B`) is open and tracked under `Issues/open/developer/`.
- `phpstan` and `php-cs-fixer` are declared in `require-dev` but the CI-gated enforcement job (Wave 6 / `DE-019`) is open.

Benchmarks
----------

[](#benchmarks)

The bundle ships an in-process benchmark suite under `bench/` that exercises the hot path of every public strategy and orchestrator (see ADR-0001). It uses [PHPBench](https://github.com/phpbench/phpbench) and runs without a database by default — subjects that need a `Connection` opt in via `BENCH_DATABASE_URL`.

### Running

[](#running)

```
composer bench
```

The script invokes `phpbench run --report=aggregate`. The default `runner.path` (`bench/`) is configured in `phpbench.json`, so the positional `bench/` argument is no longer required. For custom runs (extra `--revs`, `--iterations`, `--filter`):

```
php vendor/bin/phpbench run --report=aggregate --revs=3 --iterations=2
# or, to filter a single subject:
php vendor/bin/phpbench run --report=aggregate --filter=ResolveCacheHit
```

The HTML report and per-subject memory samples are written to `bench/.bench/` (gitignored). Subjects honour `--filter=` for targeted re-runs.

### Latest results (2026-07-21, PHP 8.5.8 NTS, xdebug off, opcache off)

[](#latest-results-2026-07-21-php-858-nts-xdebug-off-opcache-off)

20 subjects, 0 failures, 0 errors. `mode` is the per-subject median; `rstdev` is the relative standard deviation across iterations.

SubjectModeRstdevWhat it measures`HashShardStrategyBench::benchResolveCacheMiss`78.063 ms±1.39 %SHA-256 modulo, cold PSR-6 cache`HashShardStrategyBench::benchResolveCacheHit`188.438 ms±19.48 %warm PSR-6 cache; high variance from pool overhead`HashShardStrategyBench::benchResolveKeyTypes`102.106 ms±5.85 %mixed key types (string / int / UUID string)`RangeShardStrategyBench::benchResolveHot`74.523 ms±3.59 %binary search over `range_table`, in-memory`RangeShardStrategyBench::benchResolveCold`659.241 ms±1.42 %range table re-parsed on every call (worst case)`UuidShardStrategyBench::benchResolve`74.659 ms±6.54 %UUIDv7 parse + shard-bit extraction`UuidShardStrategyBench::benchGenerateUuid`181.993 ms±6.09 %UUIDv7 generation with embedded shard index`ShardResolverBench::benchResolveFromEntity`34.833 µs±36.84 %reflection + attribute lookup, high variance`ShardResolverBench::benchResolveFromId`16.997 µs±9.80 %direct key path`ShardResolverBench::benchResolveFromCriteria`26.667 µs±11.25 %composite key extraction`ShardConnectionManagerBench::benchSwitchToShard4`8.496 µs±21.57 %`ShardConnectionManagerBench::benchSwitchToShard16`7.833 µs±6.38 %`ShardConnectionManagerBench::benchSwitchToShard64`11.333 µs±8.82 %`ShardConnectionManagerBench::benchGetConnectionForShard4`1.000 µs±0.00 %`ShardConnectionManagerBench::benchGetConnectionForShard16`1.000 µs±0.00 %`ShardConnectionManagerBench::benchGetConnectionForShard64`0.833 µs±20.00 %`ShardContextBench::benchWithShard`13.167 µs±3.80 %callback wrapping, no Doctrine round-trip`ShardContextBench::benchWithEntity`10.331 µs±12.90 %`ShardedRepositoryBench::benchFindOneById`388.528 µs±3.65 %end-to-end: resolve + DBAL fetch`ShardedFinderBench::benchFanOutOver16Shards1kRowsEach`2.036 ms±13.71 %16-shard fan-out, 1 000 rows per shard### Reading the table

[](#reading-the-table)

- `benchResolve*` subjects measure strategy hot paths — sub-millisecond per call in a single PHP process.
- `benchSwitchToShard*` and `benchGetConnectionForShard*` measure per-shard routing inside `ShardConnectionManager`; the lookup is amortised to ~1 µs because the manager keeps a `WeakMap` cache.
- `benchWithShard` and `benchWithEntity` measure `ShardContext` callback wrapping only — no Doctrine round-trip.
- `benchFindOneById` is the only end-to-end subject that touches a real `EntityManager`; the value is dominated by Doctrine hydration.
- `benchFanOutOver16Shards1kRowsEach` exercises `ShardedFinder` against a stubbed `Connection` per shard and serves as a regression guard for the fan-out state machine in ADR-0004.

Re-run after any change to `src/Strategy/*`, `src/Resolver/*`, `src/Manager/*`, or `src/Context/*` and update the table if any subject regresses by more than its published `rstdev`.

Integration tests
-----------------

[](#integration-tests)

`itests/` is the third tier of the testing infrastructure (ADR-0001): end-to-end scenarios that drive the bundle's real classes against real MySQL 8.4 and PostgreSQL 16 instances under controlled concurrency, with a fixed JSON envelope. The scenarios speak to DBAL directly — the bundle ships no Symfony app.

### Prerequisites

[](#prerequisites)

- Docker Engine with the Compose plugin.
- PHP extensions `pdo_mysql` and `pdo_pgsql` enabled (the in-repo `composer.json` runtime does not load them by default; see *Known issues* below).

### Bootstrap

[](#bootstrap)

```
make itests-up           # docker compose up -d --wait (mysql 8.4 + mariadb 10.11 + postgres 16)
bash itests/bin/migrate-up.sh
```

Default ports are offset (`33061` for MySQL, `33062` for MariaDB, `54321` for PostgreSQL) so the stack coexists with the dbal-manager project's stack on the same host. Credentials default to `root:itests` for MySQL and MariaDB, `itests:itests` for PostgreSQL.

### Running a scenario

[](#running-a-scenario)

```
php itests/scenarios/.php \
  --dsn="mysql://root:itests@127.0.0.1:33061/itests" \
  --vendor=mysql --rows=200 --chunk=50 --warmup --reset
```

Each scenario prints one JSON envelope line on `stdout` with `scenario`, `db_vendor`, `rows`, `chunk`, `duration_s`, `ops_per_sec`, `peak_rss_bytes`, and `errors`. The full envelope (including DB counters and latency percentiles) is produced by the `itests/bin/run-scenario.sh` wrapper; see `itests/README.md` for the CI smoke gate contract.

### Latest results (2026-07-22, PHP 8.5.8 NTS, rows=200, chunk=50, warmup+reset)

[](#latest-results-2026-07-22-php-858-nts-rows200-chunk50-warmupreset)

All 12 scenarios pass on MySQL, MariaDB, and PostgreSQL.

ScenarioMySQL 8.4MariaDB 10.11PostgreSQL 16`shard_resolution_hash`✅ 0.307 s, 650 ops/s, 0 errors✅ 0.590 s, 339 ops/s, 0 errors✅ 0.695 s, 287 ops/s, 0 errors`shard_resolution_range`✅ 1.945 s, 102 ops/s, 0 errors✅ 0.578 s, 345 ops/s, 0 errors✅ 0.702 s, 284 ops/s, 0 errors`shard_resolution_uuid`✅ 1.977 s, 101 ops/s, 0 errors✅ 0.584 s, 342 ops/s, 0 errors✅ 0.749 s, 267 ops/s, 0 errors`shard_resolution_custom_strategy`✅ 1.993 s, 100 ops/s, 0 errors✅ 0.584 s, 342 ops/s, 0 errors✅ 0.659 s, 303 ops/s, 0 errors`bulk_write_per_shard` (rows=400)✅ 1.605 s, 249 ops/s, 0 errors✅ 0.139 s, 2881 ops/s, 0 errors✅ 0.480 s, 833 ops/s, 0 errors`cross_shard_lookup`✅ 200 rows, 0 errors (re-run clean)✅ 200 rows, 0 errors✅ 200 rows, 0 errors (re-run clean)### Reading the table

[](#reading-the-table-1)

- `shard_resolution_*` subjects measure the strategy hot path under real DB I/O. MySQL is faster on the hash variant; PostgreSQL is consistently faster on the range and custom strategy variants; MariaDB sits between the two with low variance across all four.
- `bulk_write_per_shard` is a write-heavy workload that exercises the routing-table fan-out (`bench_itests_shard_routing`). MariaDB is the fastest at this profile (~2881 ops/s, ~11.5× faster than MySQL on the same workload); PostgreSQL is ~3.3× faster than MySQL.
- `cross_shard_lookup` validates that the shard ID resolved at write time matches the one resolved at read time across every fan-out shard — see `itests/README.md` for the cross-shard bleed detection contract.

### Known issues

[](#known-issues)

- **`itests/bin/run-scenario.sh` wrapper is unusable as-shipped.** The wrapper passes `--dsn ""` (whitespace-separated) to the underlying PHP CLI, but `runner_base.php` declares `getopt('', ['dsn::', …])` which silently drops the value for long options with optional arguments on PHP 8.5. The wrapper prints `"scenario did not emit JSON"` (rc=2) and exits. Workaround: invoke the scenario script directly with `--dsn=` (equals-sign form). Fix: either change `'dsn::'` to `'dsn:'` in `itests/runner/runner_base.php:52` or rework the wrapper to pass DSN via env.
- **`pdo_mysql` / `pdo_pgsql` are not auto-enabled.** The runtime image ships the `.so` files in `/usr/lib/php/modules/` but `/etc/php/conf.d/` is empty in the default install. Set `PHP_INI_SCAN_DIR=~/.php-confd` with one `extension=.so` line per file, or install the distro packages (`php-mysql`, `php-pgsql`).
- **`composer bench` is unusable as-shipped.** `phpbench.json` does not declare `runner.path`, so `composer bench` aborts with *"You must either specify or configure a path"*. Pass `bench/` explicitly, or add `"runner.path": "bench"` to `phpbench.json`.

Important notes
---------------

[](#important-notes)

- The `sharding_configs` array is always required even if you rely solely on `#[Sharding]` — an empty `[]` is the canonical declaration. The YAML-vs-attribute precedence test (`DE-013`, closed) lives in `tests/Resolver/ShardResolverTest.php`.
- `connections` and `entity_managers` are passed as Doctrine service IDs (e.g. `@doctrine.orm.default_shard_0_entity_manager`), but the per-shard connection and EM MUST also be declared in `config/packages/doctrine.yaml` so that Doctrine itself instantiates them.
- `ShardContext::withShard` and `withEntity` route the active `Connection` and `EntityManager` for the duration of the callback only. The previous routing is restored in `finally`. Cross-shard transactions are out of scope by design (see `docs/architecture.md::Non-Goals`).
- The deprecated `ShardResolverListener` class is kept for backward compatibility with consumers wiring `doctrine.event_listener`. New code should rely on `ShardedRepository` or `ShardContext` directly. The listener will be removed in 2.0.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE) for the full text.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 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.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

2d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/207833371?v=4)[Elrise IO](/maintainers/elriseio)[@elriseio](https://github.com/elriseio)

---

Top Contributors

[![alexk136](https://avatars.githubusercontent.com/u/21287520?v=4)](https://github.com/alexk136 "alexk136 (57 commits)")

---

Tags

databasesdoctrinehighloadormphpsymfonysymfonyormdoctrinedbalhashuuidSymfony Bundlerangeshardinguuidv7horizontal-sharding

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/elriseio-doctrine-shard-manager-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/elriseio-doctrine-shard-manager-bundle/health.svg)](https://phpackages.com/packages/elriseio-doctrine-shard-manager-bundle)
```

###  Alternatives

[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M215](/packages/sulu-sulu)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M754](/packages/sylius-sylius)[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M399](/packages/easycorp-easyadmin-bundle)[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

1189.8k](/packages/rcsofttech-audit-trail-bundle)[oro/platform

Business Application Platform (BAP)

645143.5k116](/packages/oro-platform)[contao/core-bundle

Contao Open Source CMS

1231.6M2.8k](/packages/contao-core-bundle)

PHPackages © 2026

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