diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts
index 9ce5c3e8b05cd1441f5926efded2ece92737c18a..01bbe98a8503f723e56606645c4a59e318a06304 100644
--- a/packages/backend/src/misc/cache.ts
+++ b/packages/backend/src/misc/cache.ts
@@ -48,7 +48,32 @@ export class Cache<T> {
 
 		// Cache MISS
 		const value = await fetcher();
-		this.set(key, value);
+		return value;
+	}
+
+	/**
+	 * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します
+	 * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします
+	 */
+	public async fetchMaybe(key: string | null, fetcher: () => Promise<T | undefined>, validator?: (cachedValue: T) => boolean): Promise<T | undefined> {
+		const cachedValue = this.get(key);
+		if (cachedValue !== undefined) {
+			if (validator) {
+				if (validator(cachedValue)) {
+					// Cache HIT
+					return cachedValue;
+				}
+			} else {
+				// Cache HIT
+				return cachedValue;
+			}
+		}
+
+		// Cache MISS
+		const value = await fetcher();
+		if (value !== undefined) {
+			this.set(key, value);
+		}
 		return value;
 	}
 }
diff --git a/packages/backend/src/remote/activitypub/db-resolver.ts b/packages/backend/src/remote/activitypub/db-resolver.ts
index 3d61296bf5ae740ca4a58c2ce8f1af0bd3c2d3fb..ef07966e42820964b297b050c05a72fcc254ab91 100644
--- a/packages/backend/src/remote/activitypub/db-resolver.ts
+++ b/packages/backend/src/remote/activitypub/db-resolver.ts
@@ -1,14 +1,14 @@
 import escapeRegexp from 'escape-regexp';
 import config from '@/config/index.js';
 import { Note } from '@/models/entities/note.js';
-import { User, IRemoteUser, CacheableRemoteUser } from '@/models/entities/user.js';
+import { User, IRemoteUser, CacheableRemoteUser, CacheableUser } from '@/models/entities/user.js';
 import { UserPublickey } from '@/models/entities/user-publickey.js';
 import { MessagingMessage } from '@/models/entities/messaging-message.js';
 import { Notes, Users, UserPublickeys, MessagingMessages } from '@/models/index.js';
 import { IObject, getApId } from './type.js';
 import { resolvePerson } from './models/person.js';
 import { Cache } from '@/misc/cache.js';
-import { userByIdCache } from '@/services/user-cache.js';
+import { uriPersonCache, userByIdCache } from '@/services/user-cache.js';
 
 const publicKeyCache = new Cache<UserPublickey | null>(Infinity);
 const publicKeyByUserIdCache = new Cache<UserPublickey | null>(Infinity);
@@ -59,19 +59,19 @@ export default class DbResolver {
 	/**
 	 * AP Person => Misskey User in DB
 	 */
-	public async getUserFromApId(value: string | IObject): Promise<User | null> {
+	public async getUserFromApId(value: string | IObject): Promise<CacheableUser | null> {
 		const parsed = this.parseUri(value);
 
 		if (parsed.id) {
-			return await Users.findOneBy({
+			return await userByIdCache.fetchMaybe(parsed.id, () => Users.findOneBy({
 				id: parsed.id,
-			});
+			}).then(x => x ?? undefined)) ?? null;
 		}
 
 		if (parsed.uri) {
-			return await Users.findOneBy({
+			return await uriPersonCache.fetch(parsed.uri, () => Users.findOneBy({
 				uri: parsed.uri,
-			});
+			}));
 		}
 
 		return null;
diff --git a/packages/backend/src/remote/activitypub/kernel/block/index.ts b/packages/backend/src/remote/activitypub/kernel/block/index.ts
index 23cee81d5bcb17e248d55dc05f0a7d0fc421b68c..5e230ad7b7bedb27bc2b993989263443a8907295 100644
--- a/packages/backend/src/remote/activitypub/kernel/block/index.ts
+++ b/packages/backend/src/remote/activitypub/kernel/block/index.ts
@@ -18,6 +18,6 @@ export default async (actor: CacheableRemoteUser, activity: IBlock): Promise<str
 		return `skip: ブロックしようとしているユーザーはローカルユーザーではありません`;
 	}
 
-	await block(await Users.findOneByOrFail({ id: actor.id }), blockee);
+	await block(await Users.findOneByOrFail({ id: actor.id }), await Users.findOneByOrFail({ id: blockee.id }));
 	return `ok`;
 };
diff --git a/packages/backend/src/services/blocking/delete.ts b/packages/backend/src/services/blocking/delete.ts
index f3a509bb02c825398030b6c8e5a00893fce3c20d..d7b5ddd5ff76d5c492047c86af11aa795bdee54b 100644
--- a/packages/backend/src/services/blocking/delete.ts
+++ b/packages/backend/src/services/blocking/delete.ts
@@ -3,12 +3,12 @@ import renderBlock from '@/remote/activitypub/renderer/block.js';
 import renderUndo from '@/remote/activitypub/renderer/undo.js';
 import { deliver } from '@/queue/index.js';
 import Logger from '../logger.js';
-import { User } from '@/models/entities/user.js';
+import { CacheableUser, User } from '@/models/entities/user.js';
 import { Blockings, Users } from '@/models/index.js';
 
 const logger = new Logger('blocking/delete');
 
-export default async function(blocker: User, blockee: User) {
+export default async function(blocker: CacheableUser, blockee: CacheableUser) {
 	const blocking = await Blockings.findOneBy({
 		blockerId: blocker.id,
 		blockeeId: blockee.id,
diff --git a/packages/backend/src/services/following/requests/accept.ts b/packages/backend/src/services/following/requests/accept.ts
index fc9d4062e37f50a2ead828aac72d34a4a5a442ee..20829f70c7f30b5a209f471140377c8dffc2b658 100644
--- a/packages/backend/src/services/following/requests/accept.ts
+++ b/packages/backend/src/services/following/requests/accept.ts
@@ -4,11 +4,11 @@ import renderAccept from '@/remote/activitypub/renderer/accept.js';
 import { deliver } from '@/queue/index.js';
 import { publishMainStream } from '@/services/stream.js';
 import { insertFollowingDoc } from '../create.js';
-import { User, ILocalUser } from '@/models/entities/user.js';
+import { User, ILocalUser, CacheableUser } from '@/models/entities/user.js';
 import { FollowRequests, Users } from '@/models/index.js';
 import { IdentifiableError } from '@/misc/identifiable-error.js';
 
-export default async function(followee: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }, follower: User) {
+export default async function(followee: { id: User['id']; host: User['host']; uri: User['host']; inbox: User['inbox']; sharedInbox: User['sharedInbox']; }, follower: CacheableUser) {
 	const request = await FollowRequests.findOneBy({
 		followeeId: followee.id,
 		followerId: follower.id,