diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
index 228fc51667744..18a75e61b1c1b 100644
--- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
@@ -596,6 +596,11 @@ public function copyFromStorage(
 
 	public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, ?ICacheEntry $sourceCacheEntry = null): bool {
 		$sourceCache = $sourceStorage->getCache();
+		if ($sourceStorage->instanceOfStorage(ObjectStoreStorage::class) && $sourceStorage->getObjectStore()->getStorageId() === $this->getObjectStore()->getStorageId()) {
+			$this->getCache()->moveFromCache($sourceCache, $sourceInternalPath, $targetInternalPath);
+			// Do not import any data when source and target bucket are identical.
+			return true;
+		}
 		if (!$sourceCacheEntry) {
 			$sourceCacheEntry = $sourceCache->get($sourceInternalPath);
 		}
diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStoragesDifferentBucketTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStoragesDifferentBucketTest.php
new file mode 100644
index 0000000000000..1915460777cf0
--- /dev/null
+++ b/tests/lib/Files/ObjectStore/ObjectStoreStoragesDifferentBucketTest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Files\ObjectStore;
+
+use Test\Files\Storage\StoragesTest;
+
+/**
+ * @group DB
+ */
+class ObjectStoreStoragesDifferentBucketTest extends StoragesTest {
+	/**
+	 * @var \OCP\Files\ObjectStore\IObjectStore
+	 */
+	private $objectStore1;
+
+	/**
+	 * @var \OCP\Files\ObjectStore\IObjectStore
+	 */
+	private $objectStore2;
+
+	protected function setUp(): void {
+		parent::setUp();
+
+		$baseStorage1 = new Temporary();
+		$this->objectStore1 = new StorageObjectStore($baseStorage1);
+		$config['objectstore'] = $this->objectStore1;
+		$this->storage1 = new ObjectStoreStorageOverwrite($config);
+
+		$baseStorage2 = new Temporary();
+		$this->objectStore2 = new StorageObjectStore($baseStorage2);
+		$config['objectstore'] = $this->objectStore2;
+		$this->storage2 = new ObjectStoreStorageOverwrite($config);
+	}
+}
diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStoragesSameBucketTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStoragesSameBucketTest.php
new file mode 100644
index 0000000000000..71011451a531c
--- /dev/null
+++ b/tests/lib/Files/ObjectStore/ObjectStoreStoragesSameBucketTest.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Files\ObjectStore;
+
+use Test\Files\Storage\StoragesTest;
+
+/**
+ * @group DB
+ */
+class ObjectStoreStoragesSameBucketTest extends StoragesTest {
+	/**
+	 * @var \OCP\Files\ObjectStore\IObjectStore
+	 */
+	private $objectStore;
+
+	protected function setUp(): void {
+		parent::setUp();
+
+		$baseStorage = new Temporary();
+		$this->objectStore = new StorageObjectStore($baseStorage);
+		$config['objectstore'] = $this->objectStore;
+		// storage1 and storage2 share the same object store.
+		$this->storage1 = new ObjectStoreStorageOverwrite($config);
+		$this->storage2 = new ObjectStoreStorageOverwrite($config);
+	}
+}
diff --git a/tests/lib/Files/Storage/StoragesTest.php b/tests/lib/Files/Storage/StoragesTest.php
new file mode 100644
index 0000000000000..a7578c24e3db7
--- /dev/null
+++ b/tests/lib/Files/Storage/StoragesTest.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\Files\Storage;
+
+use Test\TestCase;
+
+abstract class StoragesTest extends TestCase {
+	/**
+	 * @var \OC\Files\Storage\Storage
+	 */
+	protected $storage1;
+
+	/**
+	 * @var \OC\Files\Storage\Storage
+	 */
+	protected $storage2;
+
+	protected function tearDown(): void {
+		if (is_null($this->storage1) && is_null($this->storage2)) {
+			return;
+		}
+		$this->storage1->getCache()->clear();
+		$this->storage2->getCache()->clear();
+
+		parent::tearDown();
+	}
+
+	public function testMoveFileFromStorage() {
+		$source = 'source.txt';
+		$target = 'target.txt';
+		$storage2->file_put_contents($source, 'foo');
+
+		$storage1->moveFromStorage($storage2, $source, $target);
+
+		$this->assertTrue($storage1->file_exists($target), $target.' was not created');
+		$this->assertFalse($storage2->file_exists($source), $source.' still exists');
+		$this->assertEquals('foo', $storage1->file_get_contents($target));
+	}
+
+	public function testMoveDirectoryFromStorage() {
+		$storage2->mkdir('source');
+		$storage2->file_put_contents('source/test1.txt', 'foo');
+		$storage2->file_put_contents('source/test2.txt', 'qwerty');
+		$storage2->mkdir('source/subfolder');
+		$storage2->file_put_contents('source/subfolder/test.txt', 'bar');
+
+		$storage1->moveFromStorage($storage2, 'source', 'target');
+
+		$this->assertTrue($storage1->file_exists('target'));
+		$this->assertTrue($storage1->file_exists('target/test1.txt'));
+		$this->assertTrue($storage1->file_exists('target/test2.txt'));
+		$this->assertTrue($storage1->file_exists('target/subfolder'));
+		$this->assertTrue($storage1->file_exists('target/subfolder/test.txt'));
+
+		$this->assertFalse($storage2->file_exists('source'));
+		$this->assertFalse($storage2->file_exists('source/test1.txt'));
+		$this->assertFalse($storage2->file_exists('source/test2.txt'));
+		$this->assertFalse($storage2->file_exists('source/subfolder'));
+		$this->assertFalse($storage2->file_exists('source/subfolder/test.txt'));
+
+		$this->assertEquals('foo', $storage1->file_get_contents('target/test1.txt'));
+		$this->assertEquals('qwerty', $storage1->file_get_contents('target/test2.txt'));
+		$this->assertEquals('bar', $storage1->file_get_contents('target/subfolder/test.txt'));
+	}
+
+	public function testCopyFileFromStorage() {
+		$source = 'source.txt';
+		$target = 'target.txt';
+		$storage2->file_put_contents($source, 'foo');
+
+		$storage1->copyFromStorage($storage2, $source, $target);
+
+		$this->assertTrue($storage1->file_exists($target), $target.' was not created');
+		$this->assertTrue($storage2->file_exists($source), $source.' was deleted');
+		$this->assertEquals('foo', $storage1->file_get_contents($target));
+	}
+
+	public function testCopyDirectoryFromStorage() {
+		$storage2->mkdir('source');
+		$storage2->file_put_contents('source/test1.txt', 'foo');
+		$storage2->file_put_contents('source/test2.txt', 'qwerty');
+		$storage2->mkdir('source/subfolder');
+		$storage2->file_put_contents('source/subfolder/test.txt', 'bar');
+
+		$storage1->copyFromStorage($storage2, 'source', 'target');
+
+		$this->assertTrue($storage1->file_exists('target'));
+		$this->assertTrue($storage1->file_exists('target/test1.txt'));
+		$this->assertTrue($storage1->file_exists('target/test2.txt'));
+		$this->assertTrue($storage1->file_exists('target/subfolder'));
+		$this->assertTrue($storage1->file_exists('target/subfolder/test.txt'));
+
+		$this->assertTrue($storage2->file_exists('source'));
+		$this->assertTrue($storage2->file_exists('source/test1.txt'));
+		$this->assertTrue($storage2->file_exists('source/test2.txt'));
+		$this->assertTrue($storage2->file_exists('source/subfolder'));
+		$this->assertTrue($storage2->file_exists('source/subfolder/test.txt'));
+
+		$this->assertEquals('foo', $storage1->file_get_contents('target/test1.txt'));
+		$this->assertEquals('qwerty', $storage1->file_get_contents('target/test2.txt'));
+		$this->assertEquals('bar', $storage1->file_get_contents('target/subfolder/test.txt'));
+	}
+}