diff --git a/src/models/repositories/note.ts b/src/models/repositories/note.ts
index 43caaf94b28636d705f503337e44eed9e760c79c..1fcedbd56fc1e4970d5a8c82251f19fc7d208c88 100644
--- a/src/models/repositories/note.ts
+++ b/src/models/repositories/note.ts
@@ -85,6 +85,7 @@ export class NoteRepository extends Repository<Note> {
 			detail?: boolean;
 			skipHide?: boolean;
 			_hint_?: {
+				emojis: Emoji[] | null;
 				myReactions: Map<Note['id'], NoteReaction | null>;
 			};
 		}
@@ -141,11 +142,43 @@ export class NoteRepository extends Repository<Note> {
 		 * @param reactionNames Note等にリアクションされたカスタム絵文字名 (:は含めない)
 		 */
 		async function populateEmojis(emojiNames: string[], noteUserHost: string | null, reactionNames: string[]) {
+			const customReactions = reactionNames?.map(x => decodeReaction(x)).filter(x => x.name);
+
 			let all = [] as {
 				name: string,
 				url: string
 			}[];
 
+			// 与えられたhintだけで十分(=新たにクエリする必要がない)かどうかを表すフラグ
+			let enough = true;
+			if (options?._hint_?.emojis) {
+				for (const name of emojiNames) {
+					const matched = options._hint_.emojis.find(x => x.name === name && x.host === noteUserHost);
+					if (matched) {
+						all.push({
+							name: matched.name,
+							url: matched.url,
+						});
+					} else {
+						enough = false;
+					}
+				}
+				for (const customReaction of customReactions) {
+					const matched = options._hint_.emojis.find(x => x.name === customReaction.name && x.host === customReaction.host);
+					if (matched) {
+						all.push({
+							name: `${matched.name}@${matched.host || '.'}`,	// @host付きでローカルは.
+							url: matched.url,
+						});
+					} else {
+						enough = false;
+					}
+				}
+			} else {
+				enough = false;
+			}
+			if (enough) return all;
+
 			// カスタム絵文字
 			if (emojiNames?.length > 0) {
 				const tmp = await Emojis.find({
@@ -164,8 +197,6 @@ export class NoteRepository extends Repository<Note> {
 				all = concat([all, tmp]);
 			}
 
-			const customReactions = reactionNames?.map(x => decodeReaction(x)).filter(x => x.name);
-
 			if (customReactions?.length > 0) {
 				const where = [] as {}[];
 
@@ -230,7 +261,12 @@ export class NoteRepository extends Repository<Note> {
 			id: note.id,
 			createdAt: note.createdAt.toISOString(),
 			userId: note.userId,
-			user: Users.pack(note.user || note.userId, meId),
+			user: Users.pack(note.user || note.userId, meId, {
+				detail: false,
+				_hint_: {
+					emojis: options?._hint_?.emojis || null
+				}
+			}),
 			text: text,
 			cw: note.cw,
 			visibility: note.visibility,
@@ -258,12 +294,12 @@ export class NoteRepository extends Repository<Note> {
 			_prId_: (note as any)._prId_ || undefined,
 
 			...(opts.detail ? {
-				reply: note.replyId ? this.pack(note.replyId, meId, {
+				reply: note.replyId ? this.pack(note.reply || note.replyId, meId, {
 					detail: false,
 					_hint_: options?._hint_
 				}) : undefined,
 
-				renote: note.renoteId ? this.pack(note.renoteId, meId, {
+				renote: note.renoteId ? this.pack(note.renote || note.renoteId, meId, {
 					detail: true,
 					_hint_: options?._hint_
 				}) : undefined,
@@ -314,10 +350,48 @@ export class NoteRepository extends Repository<Note> {
 			}
 		}
 
+		// TODO: ここら辺の処理をaggregateEmojisみたいな関数に切り出したい
+		let emojisWhere: any[] = [];
+		for (const note of notes) {
+			if (typeof note !== 'object') continue;
+			emojisWhere.push({
+				name: In(note.emojis),
+				host: note.userHost
+			});
+			if (note.renote) {
+				emojisWhere.push({
+					name: In(note.renote.emojis),
+					host: note.renote.userHost
+				});
+				if (note.renote.user) {
+					emojisWhere.push({
+						name: In(note.renote.user.emojis),
+						host: note.renote.userHost
+					});
+				}
+			}
+			const customReactions = Object.keys(note.reactions).map(x => decodeReaction(x)).filter(x => x.name);
+			emojisWhere = emojisWhere.concat(customReactions.map(x => ({
+				name: x.name,
+				host: x.host
+			})));
+			if (note.user) {
+				emojisWhere.push({
+					name: In(note.user.emojis),
+					host: note.userHost
+				});
+			}
+		}
+		const emojis = emojisWhere.length > 0 ? await Emojis.find({
+			where: emojisWhere,
+			select: ['name', 'host', 'url']
+		}) : null;
+
 		return await Promise.all(notes.map(n => this.pack(n, me, {
 			...options,
 			_hint_: {
-				myReactions: myReactionsMap
+				myReactions: myReactionsMap,
+				emojis: emojis
 			}
 		})));
 	}
diff --git a/src/models/repositories/notification.ts b/src/models/repositories/notification.ts
index a9fe5e7b4edf664c0f898aa708467191a141a0f2..1027155873ce228e3a6f7650ca840886bb9842b0 100644
--- a/src/models/repositories/notification.ts
+++ b/src/models/repositories/notification.ts
@@ -1,11 +1,13 @@
 import { EntityRepository, In, Repository } from 'typeorm';
-import { Users, Notes, UserGroupInvitations, AccessTokens, NoteReactions } from '..';
+import { Users, Notes, UserGroupInvitations, AccessTokens, NoteReactions, Emojis } from '..';
 import { Notification } from '../entities/notification';
 import { awaitAll } from '../../prelude/await-all';
 import { SchemaType } from '../../misc/schema';
 import { Note } from '../entities/note';
 import { NoteReaction } from '../entities/note-reaction';
 import { User } from '../entities/user';
+import { decodeReaction } from '../../misc/reaction-lib';
+import { Emoji } from '../entities/emoji';
 
 export type PackedNotification = SchemaType<typeof packedNotificationSchema>;
 
@@ -15,6 +17,7 @@ export class NotificationRepository extends Repository<Notification> {
 		src: Notification['id'] | Notification,
 		options: {
 			_hintForEachNotes_: {
+				emojis: Emoji[] | null;
 				myReactions: Map<Note['id'], NoteReaction | null>;
 			};
 		}
@@ -98,9 +101,47 @@ export class NotificationRepository extends Repository<Notification> {
 			myReactionsMap.set(target, myReactions.find(reaction => reaction.noteId === target) || null);
 		}
 
+		// TODO: ここら辺の処理をaggregateEmojisみたいな関数に切り出したい
+		let emojisWhere: any[] = [];
+		for (const note of notes) {
+			if (typeof note !== 'object') continue;
+			emojisWhere.push({
+				name: In(note.emojis),
+				host: note.userHost
+			});
+			if (note.renote) {
+				emojisWhere.push({
+					name: In(note.renote.emojis),
+					host: note.renote.userHost
+				});
+				if (note.renote.user) {
+					emojisWhere.push({
+						name: In(note.renote.user.emojis),
+						host: note.renote.userHost
+					});
+				}
+			}
+			const customReactions = Object.keys(note.reactions).map(x => decodeReaction(x)).filter(x => x.name);
+			emojisWhere = emojisWhere.concat(customReactions.map(x => ({
+				name: x.name,
+				host: x.host
+			})));
+			if (note.user) {
+				emojisWhere.push({
+					name: In(note.user.emojis),
+					host: note.userHost
+				});
+			}
+		}
+		const emojis = emojisWhere.length > 0 ? await Emojis.find({
+			where: emojisWhere,
+			select: ['name', 'host', 'url']
+		}) : null;
+
 		return await Promise.all(notifications.map(x => this.pack(x, {
 			_hintForEachNotes_: {
-				myReactions: myReactionsMap
+				myReactions: myReactionsMap,
+				emojis: emojis,
 			}
 		})));
 	}
diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts
index 3a6ab48c5f12c61aa6fff231e51f9cd5a8400136..19b0e54239c5e17edc404c63d4fdc9d00eb5c58e 100644
--- a/src/models/repositories/user.ts
+++ b/src/models/repositories/user.ts
@@ -5,6 +5,7 @@ import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMes
 import config from '../../config';
 import { SchemaType } from '../../misc/schema';
 import { awaitAll } from '../../prelude/await-all';
+import { Emoji } from '../entities/emoji';
 
 export type PackedUser = SchemaType<typeof packedUserSchema>;
 
@@ -149,6 +150,9 @@ export class UserRepository extends Repository<User> {
 		options?: {
 			detail?: boolean,
 			includeSecrets?: boolean,
+			_hint_?: {
+				emojis: Emoji[] | null;
+			};
 		}
 	): Promise<PackedUser> {
 		const opts = Object.assign({
@@ -166,6 +170,34 @@ export class UserRepository extends Repository<User> {
 		}) : [];
 		const profile = opts.detail ? await UserProfiles.findOneOrFail(user.id) : null;
 
+		let emojis: Emoji[] = [];
+		if (user.emojis.length > 0) {
+			// 与えられたhintだけで十分(=新たにクエリする必要がない)かどうかを表すフラグ
+			let enough = true;
+			if (options?._hint_?.emojis) {
+				for (const name of user.emojis) {
+					const matched = options._hint_.emojis.find(x => x.name === name && x.host === user.host);
+					if (matched) {
+						emojis.push(matched);
+					} else {
+						enough = false;
+					}
+				}
+			} else {
+				enough = false;
+			}
+
+			if (!enough) {
+				emojis = await Emojis.find({
+					where: {
+						name: In(user.emojis),
+						host: user.host
+					},
+					select: ['name', 'host', 'url', 'aliases']
+				});
+			}
+		}
+
 		const falsy = opts.detail ? false : undefined;
 
 		const packed = {
@@ -190,13 +222,7 @@ export class UserRepository extends Repository<User> {
 			} : undefined) : undefined,
 
 			// カスタム絵文字添付
-			emojis: user.emojis.length > 0 ? Emojis.find({
-				where: {
-					name: In(user.emojis),
-					host: user.host
-				},
-				select: ['name', 'host', 'url', 'aliases']
-			}) : [],
+			emojis: emojis,
 
 			...(opts.detail ? {
 				url: profile!.url,
diff --git a/src/server/api/endpoints/antennas/notes.ts b/src/server/api/endpoints/antennas/notes.ts
index 750fc080cf24c340c3bbeb5d7b5a2d93097f35ca..2ea3e437457e126558abb4a472717cd330b45cc0 100644
--- a/src/server/api/endpoints/antennas/notes.ts
+++ b/src/server/api/endpoints/antennas/notes.ts
@@ -74,6 +74,10 @@ export default define(meta, async (ps, user) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 		.andWhere(`note.id IN (${ antennaQuery.getQuery() })`)
 		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser')
 		.setParameters(antennaQuery.getParameters());
 
 	generateVisibilityQuery(query, user);
diff --git a/src/server/api/endpoints/channels/timeline.ts b/src/server/api/endpoints/channels/timeline.ts
index acb34f124d99b395df83d13628305e0fd4e75fdd..292f21b63dfbdcca8c390fa8953b70d1d83a626e 100644
--- a/src/server/api/endpoints/channels/timeline.ts
+++ b/src/server/api/endpoints/channels/timeline.ts
@@ -88,6 +88,10 @@ export default define(meta, async (ps, user) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
 		.andWhere('note.channelId = :channelId', { channelId: channel.id })
 		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser')
 		.leftJoinAndSelect('note.channel', 'channel');
 	//#endregion
 
diff --git a/src/server/api/endpoints/clips/notes.ts b/src/server/api/endpoints/clips/notes.ts
index 6a507e2036f00a90c32427c5ded4da6e289a02ca..86d1e507f4d8d61bf6932b9563c93fe0fcaaadd7 100644
--- a/src/server/api/endpoints/clips/notes.ts
+++ b/src/server/api/endpoints/clips/notes.ts
@@ -72,6 +72,10 @@ export default define(meta, async (ps, user) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 		.andWhere(`note.id IN (${ clipQuery.getQuery() })`)
 		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser')
 		.setParameters(clipQuery.getParameters());
 
 	if (user) {
diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts
index af49549d37a3add2619ba43001825ed1648c69b1..812a4bd1dd5a4f3596850df0004a21352b43d1b6 100644
--- a/src/server/api/endpoints/i/notifications.ts
+++ b/src/server/api/endpoints/i/notifications.ts
@@ -87,7 +87,11 @@ export default define(meta, async (ps, user) => {
 		.andWhere(`notification.notifieeId = :meId`, { meId: user.id })
 		.leftJoinAndSelect('notification.notifier', 'notifier')
 		.leftJoinAndSelect('notification.note', 'note')
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	query.andWhere(`notification.notifierId NOT IN (${ mutingQuery.getQuery() })`);
 	query.setParameters(mutingQuery.getParameters());
diff --git a/src/server/api/endpoints/notes.ts b/src/server/api/endpoints/notes.ts
index fab8455d78b4af2cb2a2704caadd2aecae634403..708ce38c0eb631b71c8d7c9e7865eb1dad4872b2 100644
--- a/src/server/api/endpoints/notes.ts
+++ b/src/server/api/endpoints/notes.ts
@@ -76,7 +76,11 @@ export default define(meta, async (ps) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 		.andWhere(`note.visibility = 'public'`)
 		.andWhere(`note.localOnly = FALSE`)
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	if (ps.local) {
 		query.andWhere('note.userHost IS NULL');
diff --git a/src/server/api/endpoints/notes/children.ts b/src/server/api/endpoints/notes/children.ts
index 0875e0f240a1ab1ef22fe963a5aef697a3b0dcf2..a8b239e4451b2a003bc7e43372acc5008ada10a8 100644
--- a/src/server/api/endpoints/notes/children.ts
+++ b/src/server/api/endpoints/notes/children.ts
@@ -64,7 +64,11 @@ export default define(meta, async (ps, user) => {
 				}));
 			}));
 		}))
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateVisibilityQuery(query, user);
 	if (user) generateMutedUserQuery(query, user);
diff --git a/src/server/api/endpoints/notes/featured.ts b/src/server/api/endpoints/notes/featured.ts
index 4dda7d0edb36a27487283189043b9427560ef3c6..6c416b1c044f8b719aeb95e19e083ce67c446953 100644
--- a/src/server/api/endpoints/notes/featured.ts
+++ b/src/server/api/endpoints/notes/featured.ts
@@ -49,7 +49,11 @@ export default define(meta, async (ps, user) => {
 		.andWhere(`note.score > 0`)
 		.andWhere(`note.createdAt > :date`, { date: new Date(Date.now() - day) })
 		.andWhere(`note.visibility = 'public'`)
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	if (user) generateMutedUserQuery(query, user);
 
diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts
index 6d99f1fdbce7c0a28eea4645026a9b4752271355..64c2f5851c137ae64f3509157d857bfe89c456fb 100644
--- a/src/server/api/endpoints/notes/global-timeline.ts
+++ b/src/server/api/endpoints/notes/global-timeline.ts
@@ -81,7 +81,11 @@ export default define(meta, async (ps, user) => {
 			ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
 		.andWhere('note.visibility = \'public\'')
 		.andWhere('note.channelId IS NULL')
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateRepliesQuery(query, user);
 	if (user) generateMutedUserQuery(query, user);
diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts
index 2b91b8c67b7f47b8c620578506a2896a24296bbd..c01e170aa94c765b45c72cb9faa98667004e4f08 100644
--- a/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -130,6 +130,10 @@ export default define(meta, async (ps, user) => {
 				.orWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)');
 		}))
 		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser')
 		.setParameters(followingQuery.getParameters());
 
 	generateChannelQuery(query, user);
diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts
index 51e35e62411d2107c4980b46496f2c44dd571dbe..31abb2688230a8cdeb4718c26aba90d9ad221d93 100644
--- a/src/server/api/endpoints/notes/local-timeline.ts
+++ b/src/server/api/endpoints/notes/local-timeline.ts
@@ -98,7 +98,11 @@ export default define(meta, async (ps, user) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'),
 			ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
 		.andWhere('(note.visibility = \'public\') AND (note.userHost IS NULL)')
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateChannelQuery(query, user);
 	generateRepliesQuery(query, user);
diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts
index 1e3014bd467ff7a3d0776e99a50380dbc36a7e2f..83e890d9ad5d4df1edbe9366d4c8ac26b990eb6b 100644
--- a/src/server/api/endpoints/notes/mentions.ts
+++ b/src/server/api/endpoints/notes/mentions.ts
@@ -63,7 +63,11 @@ export default define(meta, async (ps, user) => {
 			.where(`:meId = ANY(note.mentions)`, { meId: user.id })
 			.orWhere(`:meId = ANY(note.visibleUserIds)`, { meId: user.id });
 		}))
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateVisibilityQuery(query, user);
 	generateMutedUserQuery(query, user);
diff --git a/src/server/api/endpoints/notes/renotes.ts b/src/server/api/endpoints/notes/renotes.ts
index 31c24f294ac17b6ae599d21691f4a858ecd4dacd..f528197220ea9cda8eff518ff62007eae7bcdb53 100644
--- a/src/server/api/endpoints/notes/renotes.ts
+++ b/src/server/api/endpoints/notes/renotes.ts
@@ -68,7 +68,11 @@ export default define(meta, async (ps, user) => {
 
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 		.andWhere(`note.renoteId = :renoteId`, { renoteId: note.id })
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateVisibilityQuery(query, user);
 	if (user) generateMutedUserQuery(query, user);
diff --git a/src/server/api/endpoints/notes/replies.ts b/src/server/api/endpoints/notes/replies.ts
index 9fad74c78e84c04312892929d8dccda852014d34..5ac663d77a55c823a9202ad26497da02f9a4faa4 100644
--- a/src/server/api/endpoints/notes/replies.ts
+++ b/src/server/api/endpoints/notes/replies.ts
@@ -59,7 +59,11 @@ export const meta = {
 export default define(meta, async (ps, user) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 		.andWhere('note.replyId = :replyId', { replyId: ps.noteId })
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateVisibilityQuery(query, user);
 	if (user) generateMutedUserQuery(query, user);
diff --git a/src/server/api/endpoints/notes/search-by-tag.ts b/src/server/api/endpoints/notes/search-by-tag.ts
index e0f7f4d62c3124943a9028574ac5397c9ec62f27..d878f379c3ae8752327524575eadba72e7b22730 100644
--- a/src/server/api/endpoints/notes/search-by-tag.ts
+++ b/src/server/api/endpoints/notes/search-by-tag.ts
@@ -95,7 +95,11 @@ export const meta = {
 
 export default define(meta, async (ps, me) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateVisibilityQuery(query, me);
 	if (me) generateMutedUserQuery(query, me);
diff --git a/src/server/api/endpoints/notes/search.ts b/src/server/api/endpoints/notes/search.ts
index 1aca056299f0527961db4bcf92a9f5a6d000a4ec..ae0e9242a6708a40016987686188345ba6c16c45 100644
--- a/src/server/api/endpoints/notes/search.ts
+++ b/src/server/api/endpoints/notes/search.ts
@@ -79,7 +79,11 @@ export default define(meta, async (ps, me) => {
 
 		query
 			.andWhere('note.text ILIKE :q', { q: `%${ps.query}%` })
-			.leftJoinAndSelect('note.user', 'user');
+			.leftJoinAndSelect('note.user', 'user')
+			.leftJoinAndSelect('note.reply', 'reply')
+			.leftJoinAndSelect('note.renote', 'renote')
+			.leftJoinAndSelect('reply.user', 'replyUser')
+			.leftJoinAndSelect('renote.user', 'renoteUser');
 
 		generateVisibilityQuery(query, me);
 		if (me) generateMutedUserQuery(query, me);
diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts
index f09f3d1733fdcaa85d072d0f7f2512219463015d..c91bea0c1f660be3fa6d18604e7c629d3e592dbf 100644
--- a/src/server/api/endpoints/notes/timeline.ts
+++ b/src/server/api/endpoints/notes/timeline.ts
@@ -123,6 +123,10 @@ export default define(meta, async (ps, user) => {
 			if (hasFollowing) qb.orWhere(`note.userId IN (${ followingQuery.getQuery() })`);
 		}))
 		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser')
 		.setParameters(followingQuery.getParameters());
 
 	generateChannelQuery(query, user);
diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts
index b0ff499d955c49ad98842f25c1f7a6347c813961..040f017fd56fd47615fe72e23291e06c72b4e8b1 100644
--- a/src/server/api/endpoints/notes/user-list-timeline.ts
+++ b/src/server/api/endpoints/notes/user-list-timeline.ts
@@ -131,6 +131,10 @@ export default define(meta, async (ps, user) => {
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 		.andWhere(`note.userId IN (${ listQuery.getQuery() })`)
 		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser')
 		.setParameters(listQuery.getParameters());
 
 	generateVisibilityQuery(query, user);
diff --git a/src/server/api/endpoints/users/notes.ts b/src/server/api/endpoints/users/notes.ts
index 33e3ecb03f60dffa9d9803141804a2138908fcde..91d1d7f4ddec194486c1339d0f63b627af7e0467 100644
--- a/src/server/api/endpoints/users/notes.ts
+++ b/src/server/api/endpoints/users/notes.ts
@@ -131,7 +131,11 @@ export default define(meta, async (ps, me) => {
 	//#region Construct query
 	const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)
 		.andWhere('note.userId = :userId', { userId: user.id })
-		.leftJoinAndSelect('note.user', 'user');
+		.leftJoinAndSelect('note.user', 'user')
+		.leftJoinAndSelect('note.reply', 'reply')
+		.leftJoinAndSelect('note.renote', 'renote')
+		.leftJoinAndSelect('reply.user', 'replyUser')
+		.leftJoinAndSelect('renote.user', 'renoteUser');
 
 	generateVisibilityQuery(query, me);
 	if (me) generateMutedUserQuery(query, me, user);