diff --git a/README.md b/README.md
index 7292407..29d1b1d 100644
--- a/README.md
+++ b/README.md
@@ -340,6 +340,29 @@ $runner->createSchemaTable();
 $runner->apply();
 ```
 
+
+#### Connection-Targeted Migrations
+
+In multi-database architectures, you can restrict a migration to specific named connections. This is useful when different databases serve different purposes (e.g., one for user data, another for reporting):
+
+```php
+class CreateReportsTable extends AbstractMigration {
+    public function getTargetConnections(): array {
+        return ['reporting-db']; // Only runs against the 'reporting-db' connection
+    }
+
+    public function up(Database $db): void {
+        // ...
+    }
+
+    public function down(Database $db): void {
+        // ...
+    }
+}
+```
+
+Migrations with an empty `getTargetConnections()` (the default) run on all connections. The connection name comes from `ConnectionInfo::getName()`.
+
 ### Database Seeders
 
 Populate your database with sample data:
diff --git a/WebFiori/Database/Schema/DatabaseChange.php b/WebFiori/Database/Schema/DatabaseChange.php
index 1bee24f..354f325 100644
--- a/WebFiori/Database/Schema/DatabaseChange.php
+++ b/WebFiori/Database/Schema/DatabaseChange.php
@@ -114,6 +114,18 @@ public function getName(): string {
         return static::class;
     }
 
+    /**
+     * Get the target connections where this change should be executed.
+     * 
+     * Override this method to restrict execution to specific named connections.
+     * Uses the logical connection name from ConnectionInfo::getName().
+     * 
+     * @return array Array of connection names. Empty array means all connections.
+     */
+    public function getTargetConnections(): array {
+        return [];
+    }
+
     /**
      * Get the type of database change.
      * 
diff --git a/WebFiori/Database/Schema/SchemaRunner.php b/WebFiori/Database/Schema/SchemaRunner.php
index 6d77cad..50f7452 100644
--- a/WebFiori/Database/Schema/SchemaRunner.php
+++ b/WebFiori/Database/Schema/SchemaRunner.php
@@ -156,6 +156,12 @@ public function apply(): DatabaseChangeResult {
                     continue;
                 }
 
+                if (!$this->shouldRunForConnection($change)) {
+                    $processed[$name] = true;
+                    $result->addSkipped($change, 'Connection mismatch');
+                    continue;
+                }
+
                 if (!$this->areDependenciesSatisfied($change)) {
                     continue; // Don't mark as processed - may be satisfied later
                 }
@@ -211,6 +217,10 @@ public function applyOne(): ?DatabaseChange {
                     continue;
                 }
 
+                if (!$this->shouldRunForConnection($change)) {
+                    continue;
+                }
+
                 if (!$this->areDependenciesSatisfied($change)) {
                     continue;
                 }
@@ -364,6 +374,10 @@ public function getPendingChanges(bool $withQueries = false): array {
                 continue;
             }
 
+            if (!$this->shouldRunForConnection($change)) {
+                continue;
+            }
+
             $info = ['change' => $change, 'queries' => []];
 
             if ($withQueries) {
@@ -581,6 +595,10 @@ public function skipAll(): array {
                 continue;
             }
 
+            if (!$this->shouldRunForConnection($change)) {
+                continue;
+            }
+
             $this->getRepository()->recordSkipped($change, $batch);
             $skipped[] = $change;
         }
@@ -613,6 +631,10 @@ public function skipNext(int $count = 1): array {
                 continue;
             }
 
+            if (!$this->shouldRunForConnection($change)) {
+                continue;
+            }
+
             $this->getRepository()->recordSkipped($change, $batch);
             $skipped[] = $change;
         }
@@ -647,6 +669,14 @@ public function skipUpTo(string $changeName): array {
                 continue;
             }
 
+            if (!$this->shouldRunForConnection($change)) {
+                if ($change->getName() === $changeName) {
+                    break;
+                }
+
+                continue;
+            }
+
             $this->getRepository()->recordSkipped($change, $batch);
             $skipped[] = $change;
 
@@ -741,6 +771,18 @@ private function resolveClassName(\SplFileInfo $file, string $basePath, string $
         return null;
     }
 
+    private function shouldRunForConnection(DatabaseChange $change): bool {
+        $targets = $change->getTargetConnections();
+
+        if (empty($targets)) {
+            return true;
+        }
+
+        $connInfo = $this->getConnectionInfo();
+
+        return $connInfo !== null && in_array($connInfo->getName(), $targets);
+    }
+
     private function shouldRunInEnvironment(DatabaseChange $change): bool {
         $environments = $change->getEnvironments();
 
diff --git a/examples/06-migrations/CreateReportsTableMigration.php b/examples/06-migrations/CreateReportsTableMigration.php
new file mode 100644
index 0000000..c0180e3
--- /dev/null
+++ b/examples/06-migrations/CreateReportsTableMigration.php
@@ -0,0 +1,51 @@
+<?php
+
+use WebFiori\Database\ColOption;
+use WebFiori\Database\Database;
+use WebFiori\Database\DataType;
+use WebFiori\Database\Schema\AbstractMigration;
+
+/**
+ * Migration that only runs against the 'reporting-db' connection.
+ *
+ * In multi-database architectures, some tables belong to specific databases.
+ * For example, a reporting database might have aggregation tables that don't
+ * belong in the main application database.
+ *
+ * By overriding getTargetConnections(), this migration will be skipped
+ * when running against any connection other than 'reporting-db'.
+ */
+class CreateReportsTableMigration extends AbstractMigration {
+    public function getTargetConnections(): array {
+        return ['reporting-db'];
+    }
+
+    public function up(Database $db): void {
+        $db->createBlueprint('daily_reports')->addColumns([
+            'id' => [
+                ColOption::TYPE => DataType::INT,
+                ColOption::PRIMARY => true,
+                ColOption::AUTO_INCREMENT => true
+            ],
+            'report-date' => [
+                ColOption::TYPE => DataType::DATE,
+                ColOption::NULL => false
+            ],
+            'total-orders' => [
+                ColOption::TYPE => DataType::INT,
+                ColOption::DEFAULT => 0
+            ],
+            'revenue' => [
+                ColOption::TYPE => DataType::DECIMAL,
+                ColOption::SIZE => 10
+            ]
+        ]);
+
+        $db->table('daily_reports')->createTable();
+        $db->execute();
+    }
+
+    public function down(Database $db): void {
+        $db->raw("DROP TABLE IF EXISTS daily_reports")->execute();
+    }
+}
diff --git a/examples/06-migrations/README.md b/examples/06-migrations/README.md
index aec4f2f..8a2a3d2 100644
--- a/examples/06-migrations/README.md
+++ b/examples/06-migrations/README.md
@@ -1,33 +1,35 @@
-# Database Migrations
-
-This example demonstrates how to create and run database migrations using WebFiori's migration system.
-
-## What This Example Shows
-
-- Creating migration classes that extend AbstractMigration
-- Implementing up() and down() methods for schema changes
-- Running migrations using SchemaRunner
-- Rolling back migrations
-
-## Files
-
-- [`example.php`](example.php) - Main example code
-- [`CreateUsersTableMigration.php`](CreateUsersTableMigration.php) - Migration to create users table
-- [`AddEmailIndexMigration.php`](AddEmailIndexMigration.php) - Migration to add email index
-
-## Running the Example
-
-```bash
-php example.php
-```
-
-## Expected Output
-
-The example will create migration classes, run them to modify the database schema, and demonstrate rollback functionality.
-
-
-## Related Examples
-
-- [03-table-blueprints](../03-table-blueprints/) - Define table structures
-- [07-seeders](../07-seeders/) - Populate data after migrations
-- [05-transactions](../05-transactions/) - Understand rollback behavior
+# Database Migrations
+
+This example demonstrates how to create and run database migrations using WebFiori's migration system.
+
+## What This Example Shows
+
+- Creating migration classes that extend AbstractMigration
+- Implementing up() and down() methods for schema changes
+- Running migrations using SchemaRunner
+- Rolling back migrations
+- Connection-targeted migrations (restricting migrations to specific databases)
+
+## Files
+
+- [`example.php`](example.php) - Main example code
+- [`CreateUsersTableMigration.php`](CreateUsersTableMigration.php) - Migration to create users table
+- [`AddEmailIndexMigration.php`](AddEmailIndexMigration.php) - Migration to add email index
+- [`CreateReportsTableMigration.php`](CreateReportsTableMigration.php) - Migration targeting a specific connection
+
+## Running the Example
+
+```bash
+php example.php
+```
+
+## Expected Output
+
+The example will create migration classes, run them to modify the database schema, and demonstrate rollback functionality.
+
+
+## Related Examples
+
+- [03-table-blueprints](../03-table-blueprints/) - Define table structures
+- [07-seeders](../07-seeders/) - Populate data after migrations
+- [05-transactions](../05-transactions/) - Understand rollback behavior
diff --git a/examples/06-migrations/example.php b/examples/06-migrations/example.php
index dadbbc4..0158d07 100644
--- a/examples/06-migrations/example.php
+++ b/examples/06-migrations/example.php
@@ -91,7 +91,44 @@
     echo "\n";
 
     echo SEP;
-    echo "7. Cleanup:\n";
+    echo "7. Connection-Targeted Migrations:\n";
+    echo "   In multi-database setups, migrations can target specific connections.\n\n";
+
+    // Simulate running against 'main-app' connection (not 'reporting-db')
+    $mainAppConn = new ConnectionInfo('mysql', 'root', '123456', 'testing_db');
+    $mainAppConn->setName('main-app');
+
+    $runner2 = new SchemaRunner($mainAppConn);
+    require_once __DIR__.'/CreateReportsTableMigration.php';
+    $runner2->register('CreateReportsTableMigration');
+    $runner2->createSchemaTable();
+
+    $result2 = $runner2->apply();
+
+    foreach ($result2->getSkipped() as $skipped) {
+        echo "   ⊘ Skipped: ".$skipped['change']->getName()." (".$skipped['reason'].")\n";
+    }
+
+    // Now simulate running against 'reporting-db' connection
+    $reportingConn = new ConnectionInfo('mysql', 'root', '123456', 'testing_db');
+    $reportingConn->setName('reporting-db');
+
+    $runner3 = new SchemaRunner($reportingConn);
+    $runner3->register('CreateReportsTableMigration');
+    $runner3->createSchemaTable();
+
+    $result3 = $runner3->apply();
+
+    foreach ($result3->getApplied() as $applied) {
+        echo "   ✓ Applied: ".$applied->getName()." (connection matches)\n";
+    }
+
+    $runner3->rollbackUpTo(null);
+    $runner3->dropSchemaTable();
+    echo "\n";
+
+    echo SEP;
+    echo "8. Cleanup:\n";
     $runner->dropSchemaTable();
     echo "   ✓ Schema tracking table dropped\n";
 } catch (Exception $e) {
diff --git a/tests/WebFiori/Tests/Database/Schema/ConnectionTargetTest.php b/tests/WebFiori/Tests/Database/Schema/ConnectionTargetTest.php
new file mode 100644
index 0000000..d5c9748
--- /dev/null
+++ b/tests/WebFiori/Tests/Database/Schema/ConnectionTargetTest.php
@@ -0,0 +1,272 @@
+<?php
+namespace WebFiori\Tests\Database\Schema;
+
+use PHPUnit\Framework\TestCase;
+use WebFiori\Database\ConnectionInfo;
+use WebFiori\Database\Database;
+use WebFiori\Database\Schema\AbstractMigration;
+use WebFiori\Database\Schema\AbstractSeeder;
+use WebFiori\Database\Schema\SchemaRunner;
+
+// --- Fixtures ---
+
+class MigrationForAllConnections extends AbstractMigration {
+    public function down(Database $db): void {
+    }
+    public function up(Database $db): void {
+        $db->table('schema_changes')->select(['id'])->limit(1)->execute();
+    }
+}
+
+class MigrationForReportingDb extends AbstractMigration {
+    public function down(Database $db): void {
+    }
+    public function getTargetConnections(): array {
+        return ['reporting-db'];
+    }
+
+    public function up(Database $db): void {
+        $db->table('schema_changes')->select(['id'])->limit(1)->execute();
+    }
+}
+
+class MigrationForMasterDb extends AbstractMigration {
+    public function down(Database $db): void {
+    }
+    public function getTargetConnections(): array {
+        return ['master-db'];
+    }
+
+    public function up(Database $db): void {
+        $db->table('schema_changes')->select(['id'])->limit(1)->execute();
+    }
+}
+
+class MigrationForMultipleConnections extends AbstractMigration {
+    public function down(Database $db): void {
+    }
+    public function getTargetConnections(): array {
+        return ['reporting-db', 'master-db'];
+    }
+
+    public function up(Database $db): void {
+        $db->table('schema_changes')->select(['id'])->limit(1)->execute();
+    }
+}
+
+class SeederForReportingDb extends AbstractSeeder {
+    public function getTargetConnections(): array {
+        return ['reporting-db'];
+    }
+
+    public function run(Database $db): void {
+        $db->table('schema_changes')->select(['id'])->limit(1)->execute();
+    }
+}
+
+// --- Tests ---
+
+class ConnectionTargetTest extends TestCase {
+    // Test: applyOne respects connection filtering
+    public function testApplyOneSkipsMismatch() {
+        try {
+            $runner = $this->createRunner('master-db');
+            $runner->register(MigrationForReportingDb::class);
+            $runner->register(MigrationForAllConnections::class);
+            $runner->createSchemaTable();
+
+            $applied = $runner->applyOne();
+            // Should skip reporting-db migration and apply the all-connections one
+            $this->assertNotNull($applied);
+            $this->assertEquals(MigrationForAllConnections::class, $applied->getName());
+
+            $runner->rollbackUpTo(null);
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: getTargetConnections() returns declared connections
+    public function testDeclaredTargetConnections() {
+        $migration = new MigrationForReportingDb();
+        $this->assertEquals(['reporting-db'], $migration->getTargetConnections());
+    }
+
+    // Test: getTargetConnections() defaults to empty array
+    public function testDefaultTargetConnections() {
+        $migration = new MigrationForAllConnections();
+        $this->assertEquals([], $migration->getTargetConnections());
+    }
+
+    // Test: getPendingChanges respects connection filtering
+    public function testGetPendingChangesFiltered() {
+        try {
+            $runner = $this->createRunner('master-db');
+            $runner->register(MigrationForAllConnections::class);
+            $runner->register(MigrationForReportingDb::class);
+            $runner->createSchemaTable();
+
+            $pending = $runner->getPendingChanges();
+            // Only the all-connections migration should be pending
+            $this->assertCount(1, $pending);
+            $this->assertEquals(MigrationForAllConnections::class, $pending[0]['change']->getName());
+
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: Migration targeting 'reporting-db' runs when connection is 'reporting-db'
+    public function testMatchingConnectionRuns() {
+        try {
+            $runner = $this->createRunner('reporting-db');
+            $runner->register(MigrationForReportingDb::class);
+            $runner->createSchemaTable();
+
+            $result = $runner->apply();
+            $this->assertCount(1, $result->getApplied());
+
+            $runner->rollbackUpTo(null);
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: Migration targeting 'reporting-db' is skipped when connection is 'master-db'
+    public function testMismatchedConnectionSkipped() {
+        try {
+            $runner = $this->createRunner('master-db');
+            $runner->register(MigrationForReportingDb::class);
+            $runner->createSchemaTable();
+
+            $result = $runner->apply();
+            $this->assertCount(0, $result->getApplied());
+            $this->assertCount(1, $result->getSkipped());
+
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: Mixed - some match, some don't
+    public function testMixedConnectionTargeting() {
+        try {
+            $runner = $this->createRunner('reporting-db');
+            $runner->register(MigrationForAllConnections::class);
+            $runner->register(MigrationForReportingDb::class);
+            $runner->register(MigrationForMasterDb::class);
+            $runner->createSchemaTable();
+
+            $result = $runner->apply();
+            // All-connections + reporting-db should run, master-db should be skipped
+            $this->assertCount(2, $result->getApplied());
+            $this->assertCount(1, $result->getSkipped());
+
+            $runner->rollbackUpTo(null);
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: Migration targeting multiple connections runs on any of them
+    public function testMultipleTargetConnections() {
+        try {
+            $runner = $this->createRunner('master-db');
+            $runner->register(MigrationForMultipleConnections::class);
+            $runner->createSchemaTable();
+
+            $result = $runner->apply();
+            $this->assertCount(1, $result->getApplied());
+
+            $runner->rollbackUpTo(null);
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: Migration with no target runs on any connection
+    public function testNoTargetRunsOnAnyConnection() {
+        try {
+            $runner = $this->createRunner('some-random-db');
+            $runner->register(MigrationForAllConnections::class);
+            $runner->createSchemaTable();
+
+            $result = $runner->apply();
+            $this->assertCount(1, $result->getApplied());
+
+            $runner->rollbackUpTo(null);
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: Seeder respects getTargetConnections
+    public function testSeederConnectionFiltering() {
+        try {
+            $runner = $this->createRunner('master-db');
+            $runner->register(SeederForReportingDb::class);
+            $runner->createSchemaTable();
+
+            $result = $runner->apply();
+            $this->assertCount(0, $result->getApplied());
+            $this->assertCount(1, $result->getSkipped());
+
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    // Test: Skipped reason is 'Connection mismatch'
+    public function testSkippedReason() {
+        try {
+            $runner = $this->createRunner('master-db');
+            $runner->register(MigrationForReportingDb::class);
+            $runner->createSchemaTable();
+
+            $result = $runner->apply();
+            $skipped = $result->getSkipped();
+            $this->assertCount(1, $skipped);
+            $this->assertEquals('Connection mismatch', $skipped[0]['reason']);
+
+            $runner->dropSchemaTable();
+        } catch (\PHPUnit\Framework\AssertionFailedError $ex) {
+            throw $ex;
+        } catch (\Exception $ex) {
+            $this->markTestSkipped('Database connection failed: '.$ex->getMessage());
+        }
+    }
+
+    private function createRunner(string $connectionName = 'reporting-db'): SchemaRunner {
+        return new SchemaRunner($this->getConnectionInfo($connectionName));
+    }
+    private function getConnectionInfo(string $name = 'reporting-db'): ConnectionInfo {
+        $info = new ConnectionInfo('mysql', 'root', getenv('MYSQL_ROOT_PASSWORD') ?: '123456', 'testing_db', '127.0.0.1');
+        $info->setName($name);
+
+        return $info;
+    }
+}
