diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7b3260cc..d679a4c01 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -77,6 +77,7 @@ You should also include the user name that made the change.
 - 非モデレーターでも、権限を持つロールをアサインされたユーザーはインスタンスの招待コードを発行できるように @syuilo
 - 非モデレーターでも、権限を持つロールをアサインされたユーザーはカスタム絵文字の追加、編集、削除を行えるように @syuilo
 - クリップおよびクリップ内のノートの作成可能数を設定可能に @syuilo
+- ユーザーリストおよびユーザーリスト内のユーザーの作成可能数を設定可能に @syuilo
 - ハードワードミュートの最大文字数を設定可能に @syuilo
 - Webhookの作成可能数を設定可能に @syuilo
 - Server: signToActivityPubGet is set to true by default @syuilo
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index fbb7633a1..d4fba3674 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -966,6 +966,8 @@ _role:
     webhookMax: "Webhookの作成可能数"
     clipMax: "クリップの作成可能数"
     noteEachClipsMax: "クリップ内のノートの最大数"
+    userListMax: "ユーザーリストの作成可能数"
+    userEachUserListsMax: "ユーザーリスト内のユーザーの最大数"
   _condition:
     isLocal: "ローカルユーザー"
     isRemote: "リモートユーザー"
diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts
index 39413e2a5..0ddcb44ca 100644
--- a/packages/backend/src/core/RoleService.ts
+++ b/packages/backend/src/core/RoleService.ts
@@ -25,6 +25,8 @@ export type RoleOptions = {
 	webhookLimit: number;
 	clipLimit: number;
 	noteEachClipsLimit: number;
+	userListLimit: number;
+	userEachUserListsLimit: number;
 };
 
 export const DEFAULT_ROLE: RoleOptions = {
@@ -39,6 +41,8 @@ export const DEFAULT_ROLE: RoleOptions = {
 	webhookLimit: 3,
 	clipLimit: 10,
 	noteEachClipsLimit: 200,
+	userListLimit: 10,
+	userEachUserListsLimit: 50,
 };
 
 @Injectable()
@@ -212,6 +216,8 @@ export class RoleService implements OnApplicationShutdown {
 			webhookLimit: Math.max(...getOptionValues('webhookLimit')),
 			clipLimit: Math.max(...getOptionValues('clipLimit')),
 			noteEachClipsLimit: Math.max(...getOptionValues('noteEachClipsLimit')),
+			userListLimit: Math.max(...getOptionValues('userListLimit')),
+			userEachUserListsLimit: Math.max(...getOptionValues('userEachUserListsLimit')),
 		};
 	}
 
diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts
index 054387ff8..18c9787fa 100644
--- a/packages/backend/src/core/UserListService.ts
+++ b/packages/backend/src/core/UserListService.ts
@@ -10,6 +10,7 @@ import { DI } from '@/di-symbols.js';
 import { UserEntityService } from '@/core/entities/UserEntityService.js';
 import { ProxyAccountService } from '@/core/ProxyAccountService.js';
 import { bindThis } from '@/decorators.js';
+import { RoleService } from '@/core/RoleService.js';
 
 @Injectable()
 export class UserListService {
@@ -23,13 +24,21 @@ export class UserListService {
 		private userEntityService: UserEntityService,
 		private idService: IdService,
 		private userFollowingService: UserFollowingService,
+		private roleService: RoleService,
 		private globalEventServie: GlobalEventService,
 		private proxyAccountService: ProxyAccountService,
 	) {
 	}
 
 	@bindThis
-	public async push(target: User, list: UserList) {
+	public async push(target: User, list: UserList, me: User) {
+		const currentCount = await this.userListJoiningsRepository.countBy({
+			userListId: list.id,
+		});
+		if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).userEachUserListsLimit) {
+			throw new Error('Too many users');
+		}
+
 		await this.userListJoiningsRepository.insert({
 			id: this.idService.genId(),
 			createdAt: new Date(),
diff --git a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
index 1bec77b83..a9672250c 100644
--- a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
@@ -10,10 +10,10 @@ import { DownloadService } from '@/core/DownloadService.js';
 import { UserListService } from '@/core/UserListService.js';
 import { IdService } from '@/core/IdService.js';
 import { UtilityService } from '@/core/UtilityService.js';
+import { bindThis } from '@/decorators.js';
 import { QueueLoggerService } from '../QueueLoggerService.js';
 import type Bull from 'bull';
 import type { DbUserImportJobData } from '../types.js';
-import { bindThis } from '@/decorators.js';
 
 @Injectable()
 export class ImportUserListsProcessorService {
@@ -102,7 +102,7 @@ export class ImportUserListsProcessorService {
 
 				if (await this.userListJoiningsRepository.findOneBy({ userListId: list!.id, userId: target.id }) != null) continue;
 
-				this.userListService.push(target, list!);
+				this.userListService.push(target, list!, user);
 			} catch (e) {
 				this.logger.warn(`Error in line:${linenum} ${e}`);
 			}
diff --git a/packages/backend/src/server/api/endpoints/users/lists/create.ts b/packages/backend/src/server/api/endpoints/users/lists/create.ts
index 99f0751ea..810c9909b 100644
--- a/packages/backend/src/server/api/endpoints/users/lists/create.ts
+++ b/packages/backend/src/server/api/endpoints/users/lists/create.ts
@@ -5,6 +5,8 @@ import type { UserList } from '@/models/entities/UserList.js';
 import { Endpoint } from '@/server/api/endpoint-base.js';
 import { UserListEntityService } from '@/core/entities/UserListEntityService.js';
 import { DI } from '@/di-symbols.js';
+import { ApiError } from '@/server/api/error';
+import { RoleService } from '@/core/RoleService.js';
 
 export const meta = {
 	tags: ['lists'],
@@ -20,6 +22,14 @@ export const meta = {
 		optional: false, nullable: false,
 		ref: 'UserList',
 	},
+
+	errors: {
+		tooManyUserLists: {
+			message: 'You cannot create user list any more.',
+			code: 'TOO_MANY_USERLISTS',
+			id: '0cf21a28-7715-4f39-a20d-777bfdb8d138',
+		},
+	},
 } as const;
 
 export const paramDef = {
@@ -39,8 +49,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 
 		private userListEntityService: UserListEntityService,
 		private idService: IdService,
+		private roleService: RoleService,
 	) {
 		super(meta, paramDef, async (ps, me) => {
+			const currentCount = await this.userListsRepository.countBy({
+				userId: me.id,
+			});
+			if (currentCount > (await this.roleService.getUserRoleOptions(me.id)).userListLimit) {
+				throw new ApiError(meta.errors.tooManyUserLists);
+			}
+	
 			const userList = await this.userListsRepository.insert({
 				id: this.idService.genId(),
 				createdAt: new Date(),
diff --git a/packages/backend/src/server/api/endpoints/users/lists/push.ts b/packages/backend/src/server/api/endpoints/users/lists/push.ts
index 96be7e11e..3a079ee1a 100644
--- a/packages/backend/src/server/api/endpoints/users/lists/push.ts
+++ b/packages/backend/src/server/api/endpoints/users/lists/push.ts
@@ -111,7 +111,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 			}
 
 			// Push the user
-			await this.userListService.push(user, userList);
+			await this.userListService.push(user, userList, me);
 		});
 	}
 }
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue
index 2fceaf9ce..f836b4620 100644
--- a/packages/frontend/src/pages/admin/roles.editor.vue
+++ b/packages/frontend/src/pages/admin/roles.editor.vue
@@ -176,6 +176,30 @@
 					</MkInput>
 				</div>
 			</MkFolder>
+
+			<MkFolder>
+				<template #label>{{ i18n.ts._role._options.userListMax }}</template>
+				<template #suffix>{{ options_userList_useDefault ? i18n.ts._role.useBaseValue : (options_userList_value) }}</template>
+				<div class="_gaps">
+					<MkSwitch v-model="options_userList_useDefault" :readonly="readonly">
+						<template #label>{{ i18n.ts._role.useBaseValue }}</template>
+					</MkSwitch>
+					<MkInput v-model="options_userList_value" :disabled="options_userList_useDefault" type="number" :readonly="readonly">
+					</MkInput>
+				</div>
+			</MkFolder>
+
+			<MkFolder>
+				<template #label>{{ i18n.ts._role._options.userEachUserListsMax }}</template>
+				<template #suffix>{{ options_userEachUserListsLimit_useDefault ? i18n.ts._role.useBaseValue : (options_userEachUserListsLimit_value) }}</template>
+				<div class="_gaps">
+					<MkSwitch v-model="options_userEachUserListsLimit_useDefault" :readonly="readonly">
+						<template #label>{{ i18n.ts._role.useBaseValue }}</template>
+					</MkSwitch>
+					<MkInput v-model="options_userEachUserListsLimit_value" :disabled="options_userEachUserListsLimit_useDefault" type="number" :readonly="readonly">
+					</MkInput>
+				</div>
+			</MkFolder>
 		</div>
 	</FormSlot>
 
@@ -251,6 +275,10 @@ let options_clipLimit_useDefault = $ref(role?.options?.clipLimit?.useDefault ??
 let options_clipLimit_value = $ref(role?.options?.clipLimit?.value ?? 0);
 let options_noteEachClipsLimit_useDefault = $ref(role?.options?.noteEachClipsLimit?.useDefault ?? true);
 let options_noteEachClipsLimit_value = $ref(role?.options?.noteEachClipsLimit?.value ?? 0);
+let options_userListLimit_useDefault = $ref(role?.options?.userListLimit?.useDefault ?? true);
+let options_userListLimit_value = $ref(role?.options?.userListLimit?.value ?? 0);
+let options_userEachUserListsLimit_useDefault = $ref(role?.options?.userEachUserListsLimit?.useDefault ?? true);
+let options_userEachUserListsLimit_value = $ref(role?.options?.userEachUserListsLimit?.value ?? 0);
 
 if (_DEV_) {
 	watch($$(condFormula), () => {
@@ -271,6 +299,8 @@ function getOptions() {
 		webhookLimit: { useDefault: options_webhookLimit_useDefault, value: options_webhookLimit_value },
 		clipLimit: { useDefault: options_clipLimit_useDefault, value: options_clipLimit_value },
 		noteEachClipsLimit: { useDefault: options_noteEachClipsLimit_useDefault, value: options_noteEachClipsLimit_value },
+		userListLimit: { useDefault: options_userListLimit_useDefault, value: options_userListLimit_value },
+		userEachUserListsLimit: { useDefault: options_userEachUserListsLimit_useDefault, value: options_userEachUserListsLimit_value },
 	};
 }
 
diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue
index 13b893ba4..7a2f26931 100644
--- a/packages/frontend/src/pages/admin/roles.vue
+++ b/packages/frontend/src/pages/admin/roles.vue
@@ -92,6 +92,20 @@
 							</MkInput>
 						</MkFolder>
 
+						<MkFolder>
+							<template #label>{{ i18n.ts._role._options.userListMax }}</template>
+							<template #suffix>{{ options_userListLimit }}</template>
+							<MkInput v-model="options_userListLimit" type="number">
+							</MkInput>
+						</MkFolder>
+
+						<MkFolder>
+							<template #label>{{ i18n.ts._role._options.userEachUserListsMax }}</template>
+							<template #suffix>{{ options_userEachUserListsLimit }}</template>
+							<MkInput v-model="options_userEachUserListsLimit" type="number">
+							</MkInput>
+						</MkFolder>
+
 						<MkButton primary rounded @click="updateBaseRole">{{ i18n.ts.save }}</MkButton>
 					</div>
 				</MkFolder>
@@ -135,6 +149,8 @@ let options_wordMuteLimit = $ref(instance.baseRole.wordMuteLimit);
 let options_webhookLimit = $ref(instance.baseRole.webhookLimit);
 let options_clipLimit = $ref(instance.baseRole.clipLimit);
 let options_noteEachClipsLimit = $ref(instance.baseRole.noteEachClipsLimit);
+let options_userListLimit = $ref(instance.baseRole.userListLimit);
+let options_userEachUserListsLimit = $ref(instance.baseRole.userEachUserListsLimit);
 
 async function updateBaseRole() {
 	await os.apiWithDialog('admin/roles/update-default-role-override', {
@@ -150,6 +166,8 @@ async function updateBaseRole() {
 			webhookLimit: options_webhookLimit,
 			clipLimit: options_clipLimit,
 			noteEachClipsLimit: options_noteEachClipsLimit,
+			userListLimit: options_userListLimit,
+			userEachUserListsLimit: options_userEachUserListsLimit,
 		},
 	});
 }