diff --git a/server/src/enum.ts b/server/src/enum.ts
index a4d2d21274..e49f1636a0 100644
--- a/server/src/enum.ts
+++ b/server/src/enum.ts
@@ -567,6 +567,7 @@ export enum DatabaseLock {
   Library = 1337,
   GetSystemConfig = 69,
   BackupDatabase = 42,
+  MemoryCreation = 777,
 }
 
 export enum SyncRequestType {
diff --git a/server/src/services/memory.service.ts b/server/src/services/memory.service.ts
index 3d3d10540b..1ccd311790 100644
--- a/server/src/services/memory.service.ts
+++ b/server/src/services/memory.service.ts
@@ -4,9 +4,8 @@ import { OnJob } from 'src/decorators';
 import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
 import { AuthDto } from 'src/dtos/auth.dto';
 import { MemoryCreateDto, MemoryResponseDto, MemorySearchDto, MemoryUpdateDto, mapMemory } from 'src/dtos/memory.dto';
-import { JobName, MemoryType, Permission, QueueName, SystemMetadataKey } from 'src/enum';
+import { DatabaseLock, JobName, MemoryType, Permission, QueueName, SystemMetadataKey } from 'src/enum';
 import { BaseService } from 'src/services/base.service';
-import { OnThisDayData } from 'src/types';
 import { addAssets, getMyPartnerIds, removeAssets } from 'src/utils/asset.util';
 
 const DAYS = 3;
@@ -16,55 +15,61 @@ export class MemoryService extends BaseService {
   @OnJob({ name: JobName.MEMORIES_CREATE, queue: QueueName.BACKGROUND_TASK })
   async onMemoriesCreate() {
     const users = await this.userRepository.getList({ withDeleted: false });
-    const userMap: Record<string, string[]> = {};
-    for (const user of users) {
-      const partnerIds = await getMyPartnerIds({
-        userId: user.id,
-        repository: this.partnerRepository,
-        timelineEnabled: true,
-      });
-      userMap[user.id] = [user.id, ...partnerIds];
-    }
+    const usersIds = await Promise.all(
+      users.map((user) =>
+        getMyPartnerIds({
+          userId: user.id,
+          repository: this.partnerRepository,
+          timelineEnabled: true,
+        }),
+      ),
+    );
 
-    const start = DateTime.utc().startOf('day').minus({ days: DAYS });
+    await this.databaseRepository.withLock(DatabaseLock.MemoryCreation, async () => {
+      const state = await this.systemMetadataRepository.get(SystemMetadataKey.MEMORIES_STATE);
+      const start = DateTime.utc().startOf('day').minus({ days: DAYS });
+      const lastOnThisDayDate = state?.lastOnThisDayDate ? DateTime.fromISO(state.lastOnThisDayDate) : start;
 
-    const state = await this.systemMetadataRepository.get(SystemMetadataKey.MEMORIES_STATE);
-    const lastOnThisDayDate = state?.lastOnThisDayDate ? DateTime.fromISO(state.lastOnThisDayDate) : start;
-
-    // generate a memory +/- X days from today
-    for (let i = 0; i <= DAYS * 2; i++) {
-      const target = start.plus({ days: i });
-      if (lastOnThisDayDate >= target) {
-        continue;
-      }
-
-      const showAt = target.startOf('day').toISO();
-      const hideAt = target.endOf('day').toISO();
-
-      for (const [userId, userIds] of Object.entries(userMap)) {
-        const memories = await this.assetRepository.getByDayOfYear(userIds, target);
-
-        for (const { year, assets } of memories) {
-          const data: OnThisDayData = { year };
-          await this.memoryRepository.create(
-            {
-              ownerId: userId,
-              type: MemoryType.ON_THIS_DAY,
-              data,
-              memoryAt: target.set({ year }).toISO(),
-              showAt,
-              hideAt,
-            },
-            new Set(assets.map(({ id }) => id)),
-          );
+      // generate a memory +/- X days from today
+      for (let i = 0; i <= DAYS * 2; i++) {
+        const target = start.plus({ days: i });
+        if (lastOnThisDayDate >= target) {
+          continue;
         }
-      }
 
-      await this.systemMetadataRepository.set(SystemMetadataKey.MEMORIES_STATE, {
-        ...state,
-        lastOnThisDayDate: target.toISO(),
-      });
-    }
+        try {
+          await Promise.all(users.map((owner, i) => this.createOnThisDayMemories(owner.id, usersIds[i], target)));
+        } catch (error) {
+          this.logger.error(`Failed to create memories for ${target.toISO()}`, error);
+        }
+        // update system metadata even when there is an error to minimize the chance of duplicates
+        await this.systemMetadataRepository.set(SystemMetadataKey.MEMORIES_STATE, {
+          ...state,
+          lastOnThisDayDate: target.toISO(),
+        });
+      }
+    });
+  }
+
+  private async createOnThisDayMemories(ownerId: string, userIds: string[], target: DateTime) {
+    const showAt = target.startOf('day').toISO();
+    const hideAt = target.endOf('day').toISO();
+    const memories = await this.assetRepository.getByDayOfYear([ownerId, ...userIds], target);
+    await Promise.all(
+      memories.map(({ year, assets }) =>
+        this.memoryRepository.create(
+          {
+            ownerId,
+            type: MemoryType.ON_THIS_DAY,
+            data: { year },
+            memoryAt: target.set({ year }).toISO()!,
+            showAt,
+            hideAt,
+          },
+          new Set(assets.map(({ id }) => id)),
+        ),
+      ),
+    );
   }
 
   @OnJob({ name: JobName.MEMORIES_CLEANUP, queue: QueueName.BACKGROUND_TASK })
diff --git a/server/test/medium/specs/services/memory.service.spec.ts b/server/test/medium/specs/services/memory.service.spec.ts
index 445434d60a..8489e6bcc9 100644
--- a/server/test/medium/specs/services/memory.service.spec.ts
+++ b/server/test/medium/specs/services/memory.service.spec.ts
@@ -15,6 +15,7 @@ describe(MemoryService.name, () => {
       database: db || defaultDatabase,
       repos: {
         asset: 'real',
+        database: 'real',
         memory: 'real',
         user: 'real',
         systemMetadata: 'real',