diff --git a/src/db/postgre.ts b/src/db/postgre.ts
index bc5ee4ce8c..e5726e9c87 100644
--- a/src/db/postgre.ts
+++ b/src/db/postgre.ts
@@ -36,10 +36,10 @@ import { Emoji } from '../models/entities/emoji';
 import { ReversiGame } from '../models/entities/games/reversi/game';
 import { ReversiMatching } from '../models/entities/games/reversi/matching';
 import { UserNotePining } from '../models/entities/user-note-pinings';
-import { UserServiceLinking } from '../models/entities/user-service-linking';
 import { Poll } from '../models/entities/poll';
 import { UserKeypair } from '../models/entities/user-keypair';
 import { UserPublickey } from '../models/entities/user-publickey';
+import { UserProfile } from '../models/entities/user-profile';
 
 const sqlLogger = dbLogger.createSubLogger('sql', 'white', false);
 
@@ -101,12 +101,12 @@ export function initDb(justBorrow = false, sync = false, log = false) {
 			AuthSession,
 			AccessToken,
 			User,
+			UserProfile,
 			UserKeypair,
 			UserPublickey,
 			UserList,
 			UserListJoining,
 			UserNotePining,
-			UserServiceLinking,
 			Following,
 			FollowRequest,
 			Muting,
diff --git a/src/migrate.ts b/src/migrate.ts
index b9d6eb3396..f833ec180b 100644
--- a/src/migrate.ts
+++ b/src/migrate.ts
@@ -26,6 +26,7 @@ import { UserKeypair } from './models/entities/user-keypair';
 import { extractPublic } from './crypto_key';
 import { Emoji } from './models/entities/emoji';
 import { toPuny } from './misc/convert-host';
+import { UserProfile } from './models/entities/user-profile';
 
 const u = (config as any).mongodb.user ? encodeURIComponent((config as any).mongodb.user) : null;
 const p = (config as any).mongodb.pass ? encodeURIComponent((config as any).mongodb.pass) : null;
@@ -70,6 +71,7 @@ const getDriveFileBucket = async (): Promise<mongo.GridFSBucket> => {
 async function main() {
 	await initDb();
 	const Users = getRepository(User);
+	const UserProfiles = getRepository(UserProfile);
 	const DriveFiles = getRepository(DriveFile);
 	const DriveFolders = getRepository(DriveFolder);
 	const Notes = getRepository(Note);
@@ -90,17 +92,11 @@ async function main() {
 			usernameLower: user.username.toLowerCase(),
 			host: toPuny(user.host),
 			token: generateUserToken(),
-			password: user.password,
 			isAdmin: user.isAdmin,
-			autoAcceptFollowed: true,
-			autoWatch: false,
 			name: user.name,
-			location: user.profile ? user.profile.location : null,
-			birthday: user.profile ? user.profile.birthday : null,
 			followersCount: user.followersCount,
 			followingCount: user.followingCount,
 			notesCount: user.notesCount,
-			description: user.description,
 			isBot: user.isBot,
 			isCat: user.isCat,
 			isVerified: user.isVerified,
@@ -108,9 +104,18 @@ async function main() {
 			sharedInbox: user.sharedInbox,
 			uri: user.uri,
 		});
+		await UserProfiles.save({
+			userId: user._id.toHexString(),
+			description: user.description,
+			userHost: toPuny(user.host),
+			autoAcceptFollowed: true,
+			autoWatch: false,
+			password: user.password,
+			location: user.profile ? user.profile.location : null,
+			birthday: user.profile ? user.profile.birthday : null,
+		});
 		if (user.publicKey) {
 			await UserPublickeys.save({
-				id: genId(),
 				userId: user._id.toHexString(),
 				keyId: user.publicKey.id,
 				keyPem: user.publicKey.publicKeyPem
@@ -118,7 +123,6 @@ async function main() {
 		}
 		if (user.keypair) {
 			await UserKeypairs.save({
-				id: genId(),
 				userId: user._id.toHexString(),
 				publicKey: extractPublic(user.keypair),
 				privateKey: user.keypair,
diff --git a/src/models/entities/user-keypair.ts b/src/models/entities/user-keypair.ts
index be264641f7..9181abf8cb 100644
--- a/src/models/entities/user-keypair.ts
+++ b/src/models/entities/user-keypair.ts
@@ -4,11 +4,8 @@ import { id } from '../id';
 
 @Entity()
 export class UserKeypair {
-	@PrimaryColumn(id())
-	public id: string;
-
 	@Index({ unique: true })
-	@Column(id())
+	@PrimaryColumn(id())
 	public userId: User['id'];
 
 	@OneToOne(type => User, {
diff --git a/src/models/entities/user-service-linking.ts b/src/models/entities/user-profile.ts
similarity index 52%
rename from src/models/entities/user-service-linking.ts
rename to src/models/entities/user-profile.ts
index 3d99554e1e..24b92231f5 100644
--- a/src/models/entities/user-service-linking.ts
+++ b/src/models/entities/user-profile.ts
@@ -1,14 +1,11 @@
-import { PrimaryColumn, Entity, Index, JoinColumn, Column, OneToOne } from 'typeorm';
-import { User } from './user';
+import { Entity, Column, Index, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
 import { id } from '../id';
+import { User } from './user';
 
 @Entity()
-export class UserServiceLinking {
-	@PrimaryColumn(id())
-	public id: string;
-
+export class UserProfile {
 	@Index({ unique: true })
-	@Column(id())
+	@PrimaryColumn(id())
 	public userId: User['id'];
 
 	@OneToOne(type => User, {
@@ -17,6 +14,96 @@ export class UserServiceLinking {
 	@JoinColumn()
 	public user: User | null;
 
+	@Column('varchar', {
+		length: 128, nullable: true,
+		comment: 'The location of the User.'
+	})
+	public location: string | null;
+
+	@Column('char', {
+		length: 10, nullable: true,
+		comment: 'The birthday (YYYY-MM-DD) of the User.'
+	})
+	public birthday: string | null;
+
+	@Column('varchar', {
+		length: 1024, nullable: true,
+		comment: 'The description (bio) of the User.'
+	})
+	public description: string | null;
+
+	@Column('jsonb', {
+		default: [],
+	})
+	public fields: {
+		name: string;
+		value: string;
+	}[];
+
+	@Column('varchar', {
+		length: 128, nullable: true,
+		comment: 'The email address of the User.'
+	})
+	public email: string | null;
+
+	@Column('varchar', {
+		length: 128, nullable: true,
+	})
+	public emailVerifyCode: string | null;
+
+	@Column('boolean', {
+		default: false,
+	})
+	public emailVerified: boolean;
+
+	@Column('varchar', {
+		length: 128, nullable: true,
+	})
+	public twoFactorTempSecret: string | null;
+
+	@Column('varchar', {
+		length: 128, nullable: true,
+	})
+	public twoFactorSecret: string | null;
+
+	@Column('boolean', {
+		default: false,
+	})
+	public twoFactorEnabled: boolean;
+
+	@Column('varchar', {
+		length: 128, nullable: true,
+		comment: 'The password hash of the User. It will be null if the origin of the user is local.'
+	})
+	public password: string | null;
+
+	@Column('jsonb', {
+		default: {},
+		comment: 'The client-specific data of the User.'
+	})
+	public clientData: Record<string, any>;
+
+	@Column('boolean', {
+		default: false,
+	})
+	public autoWatch: boolean;
+
+	@Column('boolean', {
+		default: false,
+	})
+	public autoAcceptFollowed: boolean;
+
+	@Column('boolean', {
+		default: false,
+	})
+	public alwaysMarkNsfw: boolean;
+
+	@Column('boolean', {
+		default: false,
+	})
+	public carefulBot: boolean;
+
+	//#region Linking
 	@Column('boolean', {
 		default: false,
 	})
@@ -96,6 +183,7 @@ export class UserServiceLinking {
 		length: 64, nullable: true, default: null,
 	})
 	public discordDiscriminator: string | null;
+	//#endregion
 
 	//#region Denormalized fields
 	@Index()
diff --git a/src/models/entities/user-publickey.ts b/src/models/entities/user-publickey.ts
index 6c019f3313..81c42404fa 100644
--- a/src/models/entities/user-publickey.ts
+++ b/src/models/entities/user-publickey.ts
@@ -4,11 +4,8 @@ import { id } from '../id';
 
 @Entity()
 export class UserPublickey {
-	@PrimaryColumn(id())
-	public id: string;
-
 	@Index({ unique: true })
-	@Column(id())
+	@PrimaryColumn(id())
 	public userId: User['id'];
 
 	@OneToOne(type => User, {
diff --git a/src/models/entities/user.ts b/src/models/entities/user.ts
index 0a2878c0c9..40d27a42bb 100644
--- a/src/models/entities/user.ts
+++ b/src/models/entities/user.ts
@@ -45,18 +45,6 @@ export class User {
 	})
 	public name: string | null;
 
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The location of the User.'
-	})
-	public location: string | null;
-
-	@Column('char', {
-		length: 10, nullable: true,
-		comment: 'The birthday (YYYY-MM-DD) of the User.'
-	})
-	public birthday: string | null;
-
 	@Column('integer', {
 		default: 0,
 		comment: 'The count of followers.'
@@ -101,44 +89,12 @@ export class User {
 	@JoinColumn()
 	public banner: DriveFile | null;
 
-	@Column('varchar', {
-		length: 1024, nullable: true,
-		comment: 'The description (bio) of the User.'
-	})
-	public description: string | null;
-
 	@Index()
 	@Column('varchar', {
 		length: 128, array: true, default: '{}'
 	})
 	public tags: string[];
 
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The email address of the User.'
-	})
-	public email: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public emailVerifyCode: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public emailVerified: boolean;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public twoFactorTempSecret: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public twoFactorSecret: string | null;
-
 	@Column('varchar', {
 		length: 256, nullable: true,
 	})
@@ -206,11 +162,6 @@ export class User {
 	})
 	public isVerified: boolean;
 
-	@Column('boolean', {
-		default: false,
-	})
-	public twoFactorEnabled: boolean;
-
 	@Column('varchar', {
 		length: 128, array: true, default: '{}'
 	})
@@ -248,44 +199,12 @@ export class User {
 	})
 	public uri: string | null;
 
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The password hash of the User. It will be null if the origin of the user is local.'
-	})
-	public password: string | null;
-
 	@Index({ unique: true })
 	@Column('char', {
 		length: 16, nullable: true, unique: true,
 		comment: 'The native access token of the User. It will be null if the origin of the user is local.'
 	})
 	public token: string | null;
-
-	@Column('jsonb', {
-		default: {},
-		comment: 'The client-specific data of the User.'
-	})
-	public clientData: Record<string, any>;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public autoWatch: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public autoAcceptFollowed: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public alwaysMarkNsfw: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public carefulBot: boolean;
 }
 
 export interface ILocalUser extends User {
diff --git a/src/models/index.ts b/src/models/index.ts
index f88bb8d636..d66e4e710a 100644
--- a/src/models/index.ts
+++ b/src/models/index.ts
@@ -25,7 +25,6 @@ import { FollowRequestRepository } from './repositories/follow-request';
 import { MutingRepository } from './repositories/muting';
 import { BlockingRepository } from './repositories/blocking';
 import { NoteReactionRepository } from './repositories/note-reaction';
-import { UserServiceLinking } from './entities/user-service-linking';
 import { NotificationRepository } from './repositories/notification';
 import { NoteFavoriteRepository } from './repositories/note-favorite';
 import { ReversiMatchingRepository } from './repositories/games/reversi/matching';
@@ -35,6 +34,7 @@ import { AppRepository } from './repositories/app';
 import { FollowingRepository } from './repositories/following';
 import { AbuseUserReportRepository } from './repositories/abuse-user-report';
 import { AuthSessionRepository } from './repositories/auth-session';
+import { UserProfile } from './entities/user-profile';
 
 export const Apps = getCustomRepository(AppRepository);
 export const Notes = getCustomRepository(NoteRepository);
@@ -45,12 +45,12 @@ export const NoteUnreads = getRepository(NoteUnread);
 export const Polls = getRepository(Poll);
 export const PollVotes = getRepository(PollVote);
 export const Users = getCustomRepository(UserRepository);
+export const UserProfiles = getRepository(UserProfile);
 export const UserKeypairs = getRepository(UserKeypair);
 export const UserPublickeys = getRepository(UserPublickey);
 export const UserLists = getCustomRepository(UserListRepository);
 export const UserListJoinings = getRepository(UserListJoining);
 export const UserNotePinings = getRepository(UserNotePining);
-export const UserServiceLinkings = getRepository(UserServiceLinking);
 export const Followings = getCustomRepository(FollowingRepository);
 export const FollowRequests = getCustomRepository(FollowRequestRepository);
 export const Instances = getRepository(Instance);
diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts
index 3939e3142a..9e11b2aa88 100644
--- a/src/models/repositories/user.ts
+++ b/src/models/repositories/user.ts
@@ -1,6 +1,6 @@
 import { EntityRepository, Repository, In } from 'typeorm';
 import { User, ILocalUser, IRemoteUser } from '../entities/user';
-import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings } from '..';
+import { Emojis, Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles } from '..';
 import rap from '@prezzemolo/rap';
 
 @EntityRepository(User)
@@ -80,6 +80,7 @@ export class UserRepository extends Repository<User> {
 
 		const relation = meId && (meId !== user.id) && opts.detail ? await this.getRelation(meId, user.id) : null;
 		const pins = opts.detail ? await UserNotePinings.find({ userId: user.id }) : [];
+		const profile = opts.detail ? await UserProfiles.findOne({ userId: user.id }) : null;
 
 		return await rap({
 			id: user.id,
@@ -116,9 +117,9 @@ export class UserRepository extends Repository<User> {
 			} : {}),
 
 			...(opts.detail ? {
-				description: user.description,
-				location: user.location,
-				birthday: user.birthday,
+				description: profile.description,
+				location: profile.location,
+				birthday: profile.birthday,
 				followersCount: user.followersCount,
 				followingCount: user.followingCount,
 				notesCount: user.notesCount,
@@ -131,9 +132,9 @@ export class UserRepository extends Repository<User> {
 			...(opts.detail && meId === user.id ? {
 				avatarId: user.avatarId,
 				bannerId: user.bannerId,
-				autoWatch: user.autoWatch,
-				alwaysMarkNsfw: user.alwaysMarkNsfw,
-				carefulBot: user.carefulBot,
+				autoWatch: profile.autoWatch,
+				alwaysMarkNsfw: profile.alwaysMarkNsfw,
+				carefulBot: profile.carefulBot,
 				hasUnreadMessagingMessage: MessagingMessages.count({
 					where: {
 						recipientId: user.id,
diff --git a/src/remote/activitypub/models/person.ts b/src/remote/activitypub/models/person.ts
index 6129dad3d3..a6f7482bba 100644
--- a/src/remote/activitypub/models/person.ts
+++ b/src/remote/activitypub/models/person.ts
@@ -14,16 +14,16 @@ import { IIdentifier } from './identifier';
 import { apLogger } from '../logger';
 import { Note } from '../../../models/entities/note';
 import { updateHashtag } from '../../../services/update-hashtag';
-import { Users, UserNotePinings, Instances, DriveFiles, Followings, UserServiceLinkings, UserPublickeys } from '../../../models';
+import { Users, UserNotePinings, Instances, DriveFiles, Followings, UserProfiles, UserPublickeys } from '../../../models';
 import { User, IRemoteUser } from '../../../models/entities/user';
 import { Emoji } from '../../../models/entities/emoji';
 import { UserNotePining } from '../../../models/entities/user-note-pinings';
 import { genId } from '../../../misc/gen-id';
-import { UserServiceLinking } from '../../../models/entities/user-service-linking';
 import { instanceChart, usersChart } from '../../../services/chart';
 import { UserPublickey } from '../../../models/entities/user-publickey';
 import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error';
 import { toPuny } from '../../../misc/convert-host';
+import { UserProfile } from '../../../models/entities/user-profile';
 const logger = apLogger;
 
 /**
@@ -126,7 +126,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 
 	const host = toPuny(new URL(object.id).hostname);
 
-	const { fields, services } = analyzeAttachments(person.attachment);
+	const { fields } = analyzeAttachments(person.attachment);
 
 	const tags = extractHashtags(person.tag).map(tag => tag.toLowerCase());
 
@@ -141,7 +141,6 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 			bannerId: null,
 			createdAt: Date.parse(person.published) || new Date(),
 			lastFetchedAt: new Date(),
-			description: fromHtml(person.summary),
 			name: person.name,
 			isLocked: person.manuallyApprovesFollowers,
 			username: person.preferredUsername,
@@ -153,8 +152,6 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 			endpoints: person.endpoints,
 			uri: person.id,
 			url: person.url,
-			fields,
-			...services,
 			tags,
 			isBot,
 			isCat: (person as any).isCat === true
@@ -169,18 +166,18 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
 		throw e;
 	}
 
+	await UserProfiles.save({
+		userId: user.id,
+		description: fromHtml(person.summary),
+		fields,
+	} as Partial<UserProfile>);
+
 	await UserPublickeys.save({
-		id: genId(),
 		userId: user.id,
 		keyId: person.publicKey.id,
 		keyPem: person.publicKey.publicKeyPem
 	} as UserPublickey);
 
-	await UserServiceLinkings.save({
-		id: genId(),
-		userId: user.id
-	} as UserServiceLinking);
-
 	// Register host
 	registerOrFetchInstanceDoc(host).then(i => {
 		Instances.increment({ id: i.id }, 'usersCount', 1);
@@ -347,7 +344,7 @@ export async function updatePerson(uri: string, resolver?: Resolver, hint?: obje
 		keyPem: person.publicKey.publicKeyPem
 	});
 
-	await UserServiceLinkings.update({ userId: exist.id }, {
+	await UserProfiles.update({ userId: exist.id }, {
 		twitterUserId: services.twitter.userId,
 		twitterScreenName: services.twitter.screenName,
 		githubId: services.github.id,
diff --git a/src/remote/activitypub/renderer/person.ts b/src/remote/activitypub/renderer/person.ts
index 4c6b518eb6..e561e47c68 100644
--- a/src/remote/activitypub/renderer/person.ts
+++ b/src/remote/activitypub/renderer/person.ts
@@ -8,15 +8,15 @@ import { getEmojis } from './note';
 import renderEmoji from './emoji';
 import { IIdentifier } from '../models/identifier';
 import renderHashtag from './hashtag';
-import { DriveFiles, UserServiceLinkings, UserKeypairs } from '../../../models';
+import { DriveFiles, UserProfiles, UserKeypairs } from '../../../models';
 
 export async function renderPerson(user: ILocalUser) {
 	const id = `${config.url}/users/${user.id}`;
 
-	const [avatar, banner, links] = await Promise.all([
+	const [avatar, banner, profile] = await Promise.all([
 		DriveFiles.findOne(user.avatarId),
 		DriveFiles.findOne(user.bannerId),
-		UserServiceLinkings.findOne({ userId: user.id })
+		UserProfiles.findOne({ userId: user.id })
 	]);
 
 	const attachment: {
@@ -27,41 +27,41 @@ export async function renderPerson(user: ILocalUser) {
 		identifier?: IIdentifier
 	}[] = [];
 
-	if (links.twitter) {
+	if (profile.twitter) {
 		attachment.push({
 			type: 'PropertyValue',
 			name: 'Twitter',
-			value: `<a href="https://twitter.com/intent/user?user_id=${links.twitterUserId}" rel="me nofollow noopener" target="_blank"><span>@${links.twitterScreenName}</span></a>`,
+			value: `<a href="https://twitter.com/intent/user?user_id=${profile.twitterUserId}" rel="me nofollow noopener" target="_blank"><span>@${profile.twitterScreenName}</span></a>`,
 			identifier: {
 				type: 'PropertyValue',
 				name: 'misskey:authentication:twitter',
-				value: `${links.twitterUserId}@${links.twitterScreenName}`
+				value: `${profile.twitterUserId}@${profile.twitterScreenName}`
 			}
 		});
 	}
 
-	if (links.github) {
+	if (profile.github) {
 		attachment.push({
 			type: 'PropertyValue',
 			name: 'GitHub',
-			value: `<a href="https://github.com/${links.githubLogin}" rel="me nofollow noopener" target="_blank"><span>@${links.githubLogin}</span></a>`,
+			value: `<a href="https://github.com/${profile.githubLogin}" rel="me nofollow noopener" target="_blank"><span>@${profile.githubLogin}</span></a>`,
 			identifier: {
 				type: 'PropertyValue',
 				name: 'misskey:authentication:github',
-				value: `${links.githubId}@${links.githubLogin}`
+				value: `${profile.githubId}@${profile.githubLogin}`
 			}
 		});
 	}
 
-	if (links.discord) {
+	if (profile.discord) {
 		attachment.push({
 			type: 'PropertyValue',
 			name: 'Discord',
-			value: `<a href="https://discordapp.com/users/${links.discordId}" rel="me nofollow noopener" target="_blank"><span>${links.discordUsername}#${links.discordDiscriminator}</span></a>`,
+			value: `<a href="https://discordapp.com/users/${profile.discordId}" rel="me nofollow noopener" target="_blank"><span>${profile.discordUsername}#${profile.discordDiscriminator}</span></a>`,
 			identifier: {
 				type: 'PropertyValue',
 				name: 'misskey:authentication:discord',
-				value: `${links.discordId}@${links.discordUsername}#${links.discordDiscriminator}`
+				value: `${profile.discordId}@${profile.discordUsername}#${profile.discordDiscriminator}`
 			}
 		});
 	}
@@ -93,7 +93,7 @@ export async function renderPerson(user: ILocalUser) {
 		url: `${config.url}/@${user.username}`,
 		preferredUsername: user.username,
 		name: user.name,
-		summary: toHtml(parse(user.description)),
+		summary: toHtml(parse(profile.description)),
 		icon: user.avatarId && renderImage(avatar),
 		image: user.bannerId && renderImage(banner),
 		tag,
diff --git a/src/server/api/endpoints/admin/reset-password.ts b/src/server/api/endpoints/admin/reset-password.ts
index 07b8b6d938..42df668606 100644
--- a/src/server/api/endpoints/admin/reset-password.ts
+++ b/src/server/api/endpoints/admin/reset-password.ts
@@ -3,7 +3,7 @@ import { ID } from '../../../../misc/cafy-id';
 import define from '../../define';
 import * as bcrypt from 'bcryptjs';
 import rndstr from 'rndstr';
-import { Users } from '../../../../models';
+import { Users, UserProfiles } from '../../../../models';
 
 export const meta = {
 	desc: {
@@ -42,7 +42,9 @@ export default define(meta, async (ps) => {
 	// Generate hash of password
 	const hash = bcrypt.hashSync(passwd);
 
-	await Users.update(user.id, {
+	await UserProfiles.update({
+		userId: user.id
+	}, {
 		password: hash
 	});
 
diff --git a/src/server/api/endpoints/i/2fa/done.ts b/src/server/api/endpoints/i/2fa/done.ts
index 8ccb09b8b7..edc7cefd26 100644
--- a/src/server/api/endpoints/i/2fa/done.ts
+++ b/src/server/api/endpoints/i/2fa/done.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import * as speakeasy from 'speakeasy';
 import define from '../../../define';
-import { Users } from '../../../../../models';
+import { UserProfiles } from '../../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -16,24 +16,26 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
-	const _token = ps.token.replace(/\s/g, '');
+	const token = ps.token.replace(/\s/g, '');
 
-	if (user.twoFactorTempSecret == null) {
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
+	if (profile.twoFactorTempSecret == null) {
 		throw new Error('二段階認証の設定が開始されていません');
 	}
 
 	const verified = (speakeasy as any).totp.verify({
-		secret: user.twoFactorTempSecret,
+		secret: profile.twoFactorTempSecret,
 		encoding: 'base32',
-		token: _token
+		token: token
 	});
 
 	if (!verified) {
 		throw new Error('not verified');
 	}
 
-	await Users.update(user.id, {
-		twoFactorSecret: user.twoFactorTempSecret,
+	await UserProfiles.update({ userId: user.id }, {
+		twoFactorSecret: profile.twoFactorTempSecret,
 		twoFactorEnabled: true
 	});
 });
diff --git a/src/server/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts
index 5efe77900a..db9a2fe944 100644
--- a/src/server/api/endpoints/i/2fa/register.ts
+++ b/src/server/api/endpoints/i/2fa/register.ts
@@ -4,7 +4,7 @@ import * as speakeasy from 'speakeasy';
 import * as QRCode from 'qrcode';
 import config from '../../../../../config';
 import define from '../../../define';
-import { Users } from '../../../../../models';
+import { UserProfiles } from '../../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -19,8 +19,10 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// Compare password
-	const same = await bcrypt.compare(ps.password, user.password);
+	const same = await bcrypt.compare(ps.password, profile.password);
 
 	if (!same) {
 		throw new Error('incorrect password');
@@ -31,7 +33,7 @@ export default define(meta, async (ps, user) => {
 		length: 32
 	});
 
-	await Users.update(user.id, {
+	await UserProfiles.update({ userId: user.id }, {
 		twoFactorTempSecret: secret.base32
 	});
 
diff --git a/src/server/api/endpoints/i/2fa/unregister.ts b/src/server/api/endpoints/i/2fa/unregister.ts
index fb3ecd4043..fa25b74391 100644
--- a/src/server/api/endpoints/i/2fa/unregister.ts
+++ b/src/server/api/endpoints/i/2fa/unregister.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
 import define from '../../../define';
-import { Users } from '../../../../../models';
+import { UserProfiles } from '../../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -16,17 +16,17 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// Compare password
-	const same = await bcrypt.compare(ps.password, user.password);
+	const same = await bcrypt.compare(ps.password, profile.password);
 
 	if (!same) {
 		throw new Error('incorrect password');
 	}
 
-	await Users.update(user.id, {
+	await UserProfiles.update({ userId: user.id }, {
 		twoFactorSecret: null,
 		twoFactorEnabled: false
 	});
-
-	return;
 });
diff --git a/src/server/api/endpoints/i/change-password.ts b/src/server/api/endpoints/i/change-password.ts
index f8f977200f..d0e0695e18 100644
--- a/src/server/api/endpoints/i/change-password.ts
+++ b/src/server/api/endpoints/i/change-password.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
 import define from '../../define';
-import { Users } from '../../../../models';
+import { UserProfiles } from '../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -20,8 +20,10 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// Compare password
-	const same = await bcrypt.compare(ps.currentPassword, user.password);
+	const same = await bcrypt.compare(ps.currentPassword, profile.password);
 
 	if (!same) {
 		throw new Error('incorrect password');
@@ -31,7 +33,7 @@ export default define(meta, async (ps, user) => {
 	const salt = await bcrypt.genSalt(8);
 	const hash = await bcrypt.hash(ps.newPassword, salt);
 
-	await Users.update(user.id, {
+	await UserProfiles.update({ userId: user.id }, {
 		password: hash
 	});
 });
diff --git a/src/server/api/endpoints/i/delete-account.ts b/src/server/api/endpoints/i/delete-account.ts
index 5aff74e0cc..7ef7aa5fac 100644
--- a/src/server/api/endpoints/i/delete-account.ts
+++ b/src/server/api/endpoints/i/delete-account.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
 import define from '../../define';
-import { Users } from '../../../../models';
+import { Users, UserProfiles } from '../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -16,8 +16,10 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// Compare password
-	const same = await bcrypt.compare(ps.password, user.password);
+	const same = await bcrypt.compare(ps.password, profile.password);
 
 	if (!same) {
 		throw new Error('incorrect password');
diff --git a/src/server/api/endpoints/i/regenerate-token.ts b/src/server/api/endpoints/i/regenerate-token.ts
index 729c1a300a..ec53bca979 100644
--- a/src/server/api/endpoints/i/regenerate-token.ts
+++ b/src/server/api/endpoints/i/regenerate-token.ts
@@ -3,7 +3,7 @@ import * as bcrypt from 'bcryptjs';
 import { publishMainStream } from '../../../../services/stream';
 import generateUserToken from '../../common/generate-native-user-token';
 import define from '../../define';
-import { Users } from '../../../../models';
+import { Users, UserProfiles } from '../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -18,8 +18,10 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// Compare password
-	const same = await bcrypt.compare(ps.password, user.password);
+	const same = await bcrypt.compare(ps.password, profile.password);
 
 	if (!same) {
 		throw new Error('incorrect password');
diff --git a/src/server/api/endpoints/i/update-client-setting.ts b/src/server/api/endpoints/i/update-client-setting.ts
index edbfe28f35..49bcb35ae6 100644
--- a/src/server/api/endpoints/i/update-client-setting.ts
+++ b/src/server/api/endpoints/i/update-client-setting.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import { publishMainStream } from '../../../../services/stream';
 import define from '../../define';
-import { Users } from '../../../../models';
+import { UserProfiles } from '../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -20,7 +20,7 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
-	await Users.createQueryBuilder().update()
+	await UserProfiles.createQueryBuilder().update()
 		.set({
 			clientData: {
 				[ps.name]: ps.value
diff --git a/src/server/api/endpoints/i/update-email.ts b/src/server/api/endpoints/i/update-email.ts
index 253017535f..d98f0d753e 100644
--- a/src/server/api/endpoints/i/update-email.ts
+++ b/src/server/api/endpoints/i/update-email.ts
@@ -8,7 +8,7 @@ import config from '../../../../config';
 import * as ms from 'ms';
 import * as bcrypt from 'bcryptjs';
 import { apiLogger } from '../../logger';
-import { Users } from '../../../../models';
+import { Users, UserProfiles } from '../../../../models';
 
 export const meta = {
 	requireCredential: true,
@@ -32,14 +32,16 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// Compare password
-	const same = await bcrypt.compare(ps.password, user.password);
+	const same = await bcrypt.compare(ps.password, profile.password);
 
 	if (!same) {
 		throw new Error('incorrect password');
 	}
 
-	await Users.update(user.id, {
+	await UserProfiles.update({ userId: user.id }, {
 		email: ps.email,
 		emailVerified: false,
 		emailVerifyCode: null
@@ -56,7 +58,7 @@ export default define(meta, async (ps, user) => {
 	if (ps.email != null) {
 		const code = rndstr('a-z0-9', 16);
 
-		await Users.update(user.id, {
+		await UserProfiles.update({ userId: user.id }, {
 			emailVerifyCode: code
 		});
 
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index 54e7f33bdb..ffc90b2f51 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -10,7 +10,9 @@ import extractHashtags from '../../../../misc/extract-hashtags';
 import * as langmap from 'langmap';
 import { updateHashtag } from '../../../../services/update-hashtag';
 import { ApiError } from '../../error';
-import { Users, DriveFiles } from '../../../../models';
+import { Users, DriveFiles, UserProfiles } from '../../../../models';
+import { User } from '../../../../models/entities/user';
+import { UserProfile } from '../../../../models/entities/user-profile';
 
 export const meta = {
 	desc: {
@@ -154,22 +156,23 @@ export const meta = {
 export default define(meta, async (ps, user, app) => {
 	const isSecure = user != null && app == null;
 
-	const updates = {} as any;
+	const updates = {} as Partial<User>;
+	const profile = {} as Partial<UserProfile>;
 
 	if (ps.name !== undefined) updates.name = ps.name;
-	if (ps.description !== undefined) updates.description = ps.description;
-	if (ps.lang !== undefined) updates.lang = ps.lang;
-	if (ps.location !== undefined) updates.location = ps.location;
-	if (ps.birthday !== undefined) updates.birthday = ps.birthday;
+	if (ps.description !== undefined) profile.description = ps.description;
+	//if (ps.lang !== undefined) updates.lang = ps.lang;
+	if (ps.location !== undefined) profile.location = ps.location;
+	if (ps.birthday !== undefined) profile.birthday = ps.birthday;
 	if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
 	if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
 	if (typeof ps.isLocked == 'boolean') updates.isLocked = ps.isLocked;
 	if (typeof ps.isBot == 'boolean') updates.isBot = ps.isBot;
-	if (typeof ps.carefulBot == 'boolean') updates.carefulBot = ps.carefulBot;
-	if (typeof ps.autoAcceptFollowed == 'boolean') updates.autoAcceptFollowed = ps.autoAcceptFollowed;
+	if (typeof ps.carefulBot == 'boolean') profile.carefulBot = ps.carefulBot;
+	if (typeof ps.autoAcceptFollowed == 'boolean') profile.autoAcceptFollowed = ps.autoAcceptFollowed;
 	if (typeof ps.isCat == 'boolean') updates.isCat = ps.isCat;
-	if (typeof ps.autoWatch == 'boolean') updates.autoWatch = ps.autoWatch;
-	if (typeof ps.alwaysMarkNsfw == 'boolean') updates.alwaysMarkNsfw = ps.alwaysMarkNsfw;
+	if (typeof ps.autoWatch == 'boolean') profile.autoWatch = ps.autoWatch;
+	if (typeof ps.alwaysMarkNsfw == 'boolean') profile.alwaysMarkNsfw = ps.alwaysMarkNsfw;
 
 	if (ps.avatarId) {
 		const avatar = await DriveFiles.findOne(ps.avatarId);
@@ -206,8 +209,8 @@ export default define(meta, async (ps, user, app) => {
 		emojis = emojis.concat(extractEmojis(tokens));
 	}
 
-	if (updates.description != null) {
-		const tokens = parse(updates.description);
+	if (profile.description != null) {
+		const tokens = parse(profile.description);
 		emojis = emojis.concat(extractEmojis(tokens));
 		tags = extractHashtags(tokens).map(tag => tag.toLowerCase());
 	}
@@ -221,6 +224,7 @@ export default define(meta, async (ps, user, app) => {
 	//#endregion
 
 	await Users.update(user.id, updates);
+	await UserProfiles.update({ userId: user.id }, profile);
 
 	const iObj = await Users.pack(user.id, user, {
 		detail: true,
diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/src/server/api/endpoints/notes/polls/vote.ts
index 7d0ed6e4f9..d868234dc9 100644
--- a/src/server/api/endpoints/notes/polls/vote.ts
+++ b/src/server/api/endpoints/notes/polls/vote.ts
@@ -10,7 +10,7 @@ import { deliver } from '../../../../../queue';
 import { renderActivity } from '../../../../../remote/activitypub/renderer';
 import renderVote from '../../../../../remote/activitypub/renderer/vote';
 import { deliverQuestionUpdate } from '../../../../../services/note/polls/update';
-import { PollVotes, NoteWatchings, Users, Polls } from '../../../../../models';
+import { PollVotes, NoteWatchings, Users, Polls, UserProfiles } from '../../../../../models';
 import { Not } from 'typeorm';
 import { IRemoteUser } from '../../../../../models/entities/user';
 import { genId } from '../../../../../misc/gen-id';
@@ -149,8 +149,10 @@ export default define(meta, async (ps, user) => {
 		}
 	});
 
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// この投稿をWatchする
-	if (user.autoWatch !== false) {
+	if (profile.autoWatch !== false) {
 		watch(user.id, note);
 	}
 
diff --git a/src/server/api/private/signin.ts b/src/server/api/private/signin.ts
index c1fd908d8a..fe2e5577c2 100644
--- a/src/server/api/private/signin.ts
+++ b/src/server/api/private/signin.ts
@@ -4,7 +4,7 @@ import * as speakeasy from 'speakeasy';
 import { publishMainStream } from '../../../services/stream';
 import signin from '../common/signin';
 import config from '../../../config';
-import { Users, Signins } from '../../../models';
+import { Users, Signins, UserProfiles } from '../../../models';
 import { ILocalUser } from '../../../models/entities/user';
 import { genId } from '../../../misc/gen-id';
 
@@ -45,13 +45,15 @@ export default async (ctx: Koa.BaseContext) => {
 		return;
 	}
 
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// Compare password
-	const same = await bcrypt.compare(password, user.password);
+	const same = await bcrypt.compare(password, profile.password);
 
 	if (same) {
-		if (user.twoFactorEnabled) {
+		if (profile.twoFactorEnabled) {
 			const verified = (speakeasy as any).totp.verify({
-				secret: user.twoFactorSecret,
+				secret: profile.twoFactorSecret,
 				encoding: 'base32',
 				token: token
 			});
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index 657e54decd..5ed25fa411 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -5,13 +5,13 @@ import generateUserToken from '../common/generate-native-user-token';
 import config from '../../../config';
 import fetchMeta from '../../../misc/fetch-meta';
 import * as recaptcha from 'recaptcha-promise';
-import { Users, RegistrationTickets, UserServiceLinkings, UserKeypairs } from '../../../models';
+import { Users, RegistrationTickets, UserProfiles, UserKeypairs } from '../../../models';
 import { genId } from '../../../misc/gen-id';
 import { usersChart } from '../../../services/chart';
-import { UserServiceLinking } from '../../../models/entities/user-service-linking';
 import { User } from '../../../models/entities/user';
 import { UserKeypair } from '../../../models/entities/user-keypair';
 import { toPuny } from '../../../misc/convert-host';
+import { UserProfile } from '../../../models/entities/user-profile';
 
 export default async (ctx: Koa.BaseContext) => {
 	const body = ctx.request.body as any;
@@ -106,23 +106,21 @@ export default async (ctx: Koa.BaseContext) => {
 		usernameLower: username.toLowerCase(),
 		host: toPuny(host),
 		token: secret,
-		password: hash,
 		isAdmin: config.autoAdmin && usersCount === 0,
-		autoAcceptFollowed: true,
-		autoWatch: false
 	} as User);
 
 	await UserKeypairs.save({
-		id: genId(),
 		publicKey: keyPair[0],
 		privateKey: keyPair[1],
 		userId: account.id
 	} as UserKeypair);
 
-	await UserServiceLinkings.save({
-		id: genId(),
-		userId: account.id
-	} as UserServiceLinking);
+	await UserProfiles.save({
+		userId: account.id,
+		autoAcceptFollowed: true,
+		autoWatch: false,
+		password: hash,
+	} as Partial<UserProfile>);
 
 	usersChart.update(account, true);
 
diff --git a/src/server/api/service/discord.ts b/src/server/api/service/discord.ts
index 4290e1ff9d..879b8b4849 100644
--- a/src/server/api/service/discord.ts
+++ b/src/server/api/service/discord.ts
@@ -8,7 +8,7 @@ import redis from '../../../db/redis';
 import * as uuid from 'uuid';
 import signin from '../common/signin';
 import fetchMeta from '../../../misc/fetch-meta';
-import { Users, UserServiceLinkings } from '../../../models';
+import { Users, UserProfiles } from '../../../models';
 import { ILocalUser } from '../../../models/entities/user';
 
 function getUserToken(ctx: Koa.BaseContext) {
@@ -45,7 +45,7 @@ router.get('/disconnect/discord', async ctx => {
 		token: userToken
 	});
 
-	await UserServiceLinkings.update({
+	await UserProfiles.update({
 		userId: user.id
 	}, {
 		discord: false,
@@ -202,7 +202,7 @@ router.get('/dc/cb', async ctx => {
 			return;
 		}
 
-		const link = await UserServiceLinkings.createQueryBuilder()
+		const profile = await UserProfiles.createQueryBuilder()
 			.where('discord @> :discord', {
 				discord: {
 					id: id,
@@ -211,12 +211,12 @@ router.get('/dc/cb', async ctx => {
 			.andWhere('userHost IS NULL')
 			.getOne();
 
-		if (link == null) {
+		if (profile == null) {
 			ctx.throw(404, `@${username}#${discriminator}と連携しているMisskeyアカウントはありませんでした...`);
 			return;
 		}
 
-		await UserServiceLinkings.update(link.id, {
+		await UserProfiles.update({ userId: profile.userId }, {
 			discord: true,
 			discordAccessToken: accessToken,
 			discordRefreshToken: refreshToken,
@@ -225,7 +225,7 @@ router.get('/dc/cb', async ctx => {
 			discordDiscriminator: discriminator
 		});
 
-		signin(ctx, await Users.findOne(link.userId) as ILocalUser, true);
+		signin(ctx, await Users.findOne(profile.userId) as ILocalUser, true);
 	} else {
 		const code = ctx.query.code;
 
@@ -289,7 +289,7 @@ router.get('/dc/cb', async ctx => {
 			token: userToken
 		});
 
-		await UserServiceLinkings.update({ userId: user.id }, {
+		await UserProfiles.update({ userId: user.id }, {
 			discord: true,
 			discordAccessToken: accessToken,
 			discordRefreshToken: refreshToken,
diff --git a/src/server/api/service/github.ts b/src/server/api/service/github.ts
index e59b149d19..580947811b 100644
--- a/src/server/api/service/github.ts
+++ b/src/server/api/service/github.ts
@@ -8,7 +8,7 @@ import redis from '../../../db/redis';
 import * as uuid from 'uuid';
 import signin from '../common/signin';
 import fetchMeta from '../../../misc/fetch-meta';
-import { Users, UserServiceLinkings } from '../../../models';
+import { Users, UserProfiles } from '../../../models';
 import { ILocalUser } from '../../../models/entities/user';
 
 function getUserToken(ctx: Koa.BaseContext) {
@@ -45,7 +45,7 @@ router.get('/disconnect/github', async ctx => {
 		token: userToken
 	});
 
-	await UserServiceLinkings.update({
+	await UserProfiles.update({
 		userId: user.id
 	}, {
 		github: false,
@@ -191,7 +191,7 @@ router.get('/gh/cb', async ctx => {
 			return;
 		}
 
-		const link = await UserServiceLinkings.createQueryBuilder()
+		const link = await UserProfiles.createQueryBuilder()
 			.where('github @> :github', {
 				github: {
 					id: id,
@@ -263,7 +263,7 @@ router.get('/gh/cb', async ctx => {
 			token: userToken
 		});
 
-		await UserServiceLinkings.update({ userId: user.id }, {
+		await UserProfiles.update({ userId: user.id }, {
 			github: true,
 			githubAccessToken: accessToken,
 			githubId: id,
diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts
index 77cf71395b..c0c762c6c3 100644
--- a/src/server/api/service/twitter.ts
+++ b/src/server/api/service/twitter.ts
@@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream';
 import config from '../../../config';
 import signin from '../common/signin';
 import fetchMeta from '../../../misc/fetch-meta';
-import { Users, UserServiceLinkings } from '../../../models';
+import { Users, UserProfiles } from '../../../models';
 import { ILocalUser } from '../../../models/entities/user';
 
 function getUserToken(ctx: Koa.BaseContext) {
@@ -44,7 +44,7 @@ router.get('/disconnect/twitter', async ctx => {
 		token: userToken
 	});
 
-	await UserServiceLinkings.update({
+	await UserProfiles.update({
 		userId: user.id
 	}, {
 		twitter: false,
@@ -139,7 +139,7 @@ router.get('/tw/cb', async ctx => {
 
 		const result = await twAuth.done(JSON.parse(twCtx), ctx.query.oauth_verifier);
 
-		const link = await UserServiceLinkings.createQueryBuilder()
+		const link = await UserProfiles.createQueryBuilder()
 			.where('twitter @> :twitter', {
 				twitter: {
 					userId: result.userId,
@@ -177,7 +177,7 @@ router.get('/tw/cb', async ctx => {
 			token: userToken
 		});
 
-		await UserServiceLinkings.update({ userId: user.id }, {
+		await UserProfiles.update({ userId: user.id }, {
 			twitter: true,
 			twitterAccessToken: result.accessToken,
 			twitterAccessTokenSecret: result.accessTokenSecret,
diff --git a/src/server/index.ts b/src/server/index.ts
index 563117773e..9c153f0167 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -23,7 +23,7 @@ import apiServer from './api';
 import { sum } from '../prelude/array';
 import Logger from '../services/logger';
 import { program } from '../argv';
-import { Users } from '../models';
+import { UserProfiles } from '../models';
 import { networkChart } from '../services/chart';
 
 export const serverLogger = new Logger('server', 'gray', false);
@@ -73,15 +73,15 @@ router.use(nodeinfo.routes());
 router.use(wellKnown.routes());
 
 router.get('/verify-email/:code', async ctx => {
-	const user = await Users.findOne({
+	const profile = await UserProfiles.findOne({
 		emailVerifyCode: ctx.params.code
 	});
 
-	if (user != null) {
+	if (profile != null) {
 		ctx.body = 'Verify succeeded!';
 		ctx.status = 200;
 
-		Users.update(user.id, {
+		UserProfiles.update({ userId: profile.userId }, {
 			emailVerified: true,
 			emailVerifyCode: null
 		});
diff --git a/src/server/web/feed.ts b/src/server/web/feed.ts
index 4b4ea87973..94f0643f75 100644
--- a/src/server/web/feed.ts
+++ b/src/server/web/feed.ts
@@ -1,7 +1,7 @@
 import { Feed } from 'feed';
 import config from '../../config';
 import { User } from '../../models/entities/user';
-import { Notes, DriveFiles } from '../../models';
+import { Notes, DriveFiles, UserProfiles } from '../../models';
 import { In } from 'typeorm';
 
 export default async function(user: User) {
@@ -10,6 +10,8 @@ export default async function(user: User) {
 		name: user.name || user.username
 	};
 
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	const notes = await Notes.find({
 		where: {
 			userId: user.id,
@@ -25,7 +27,7 @@ export default async function(user: User) {
 		title: `${author.name} (@${user.username}@${config.host})`,
 		updated: notes[0].createdAt,
 		generator: 'Misskey',
-		description: `${user.notesCount} Notes, ${user.followingCount} Following, ${user.followersCount} Followers${user.description ? ` · ${user.description}` : ''}`,
+		description: `${user.notesCount} Notes, ${user.followingCount} Following, ${user.followersCount} Followers${profile.description ? ` · ${profile.description}` : ''}`,
 		link: author.link,
 		image: user.avatarUrl,
 		feedLinks: {
diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts
index 0a84b88fb8..b83c3558d3 100644
--- a/src/services/drive/add-file.ts
+++ b/src/services/drive/add-file.ts
@@ -15,7 +15,7 @@ import { driveLogger } from './logger';
 import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
 import { contentDisposition } from '../../misc/content-disposition';
 import { detectMine } from '../../misc/detect-mine';
-import { DriveFiles, DriveFolders, Users, Instances } from '../../models';
+import { DriveFiles, DriveFolders, Users, Instances, UserProfiles } from '../../models';
 import { InternalStorage } from './internal-storage';
 import { DriveFile } from '../../models/entities/drive-file';
 import { IRemoteUser, User } from '../../models/entities/user';
@@ -365,6 +365,8 @@ export default async function(
 		propPromises = [calcWh(), calcAvg()];
 	}
 
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	const [folder] = await Promise.all([fetchFolder(), Promise.all(propPromises)]);
 
 	let file = new DriveFile();
@@ -376,7 +378,7 @@ export default async function(
 	file.comment = comment;
 	file.properties = properties;
 	file.isLink = isLink;
-	file.isSensitive = Users.isLocalUser(user) && user.alwaysMarkNsfw ? true :
+	file.isSensitive = Users.isLocalUser(user) && profile.alwaysMarkNsfw ? true :
 		(sensitive !== null && sensitive !== undefined)
 			? sensitive
 			: false;
diff --git a/src/services/following/create.ts b/src/services/following/create.ts
index 28e4ba3c12..57bb61fd92 100644
--- a/src/services/following/create.ts
+++ b/src/services/following/create.ts
@@ -9,7 +9,7 @@ import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc';
 import Logger from '../logger';
 import { IdentifiableError } from '../../misc/identifiable-error';
 import { User } from '../../models/entities/user';
-import { Followings, Users, FollowRequests, Blockings, Instances } from '../../models';
+import { Followings, Users, FollowRequests, Blockings, Instances, UserProfiles } from '../../models';
 import { instanceChart, perUserFollowingChart } from '../chart';
 import { genId } from '../../misc/gen-id';
 import { createNotification } from '../create-notification';
@@ -115,11 +115,13 @@ export default async function(follower: User, followee: User, requestId?: string
 		if (blocked != null) throw new IdentifiableError('3338392a-f764-498d-8855-db939dcf8c48', 'blocked');
 	}
 
+	const followeeProfile = await UserProfiles.findOne({ userId: followee.id });
+
 	// フォロー対象が鍵アカウントである or
 	// フォロワーがBotであり、フォロー対象がBotからのフォローに慎重である or
 	// フォロワーがローカルユーザーであり、フォロー対象がリモートユーザーである
 	// 上記のいずれかに当てはまる場合はすぐフォローせずにフォローリクエストを発行しておく
-	if (followee.isLocked || (followee.carefulBot && follower.isBot) || (Users.isLocalUser(follower) && Users.isRemoteUser(followee))) {
+	if (followee.isLocked || (followeeProfile.carefulBot && follower.isBot) || (Users.isLocalUser(follower) && Users.isRemoteUser(followee))) {
 		let autoAccept = false;
 
 		// 鍵アカウントであっても、既にフォローされていた場合はスルー
@@ -132,7 +134,7 @@ export default async function(follower: User, followee: User, requestId?: string
 		}
 
 		// フォローしているユーザーは自動承認オプション
-		if (!autoAccept && (Users.isLocalUser(followee) && followee.autoAcceptFollowed)) {
+		if (!autoAccept && (Users.isLocalUser(followee) && followeeProfile.autoAcceptFollowed)) {
 			const followed = await Followings.findOne({
 				followerId: followee.id,
 				followeeId: follower.id
diff --git a/src/services/note/create.ts b/src/services/note/create.ts
index 05837a4daf..6058fada16 100644
--- a/src/services/note/create.ts
+++ b/src/services/note/create.ts
@@ -17,7 +17,7 @@ import extractMentions from '../../misc/extract-mentions';
 import extractEmojis from '../../misc/extract-emojis';
 import extractHashtags from '../../misc/extract-hashtags';
 import { Note } from '../../models/entities/note';
-import { Mutings, Users, NoteWatchings, Followings, Notes, Instances, Polls } from '../../models';
+import { Mutings, Users, NoteWatchings, Followings, Notes, Instances, Polls, UserProfiles } from '../../models';
 import { DriveFile } from '../../models/entities/drive-file';
 import { App } from '../../models/entities/app';
 import { Not } from 'typeorm';
@@ -256,13 +256,15 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
 		deliverNoteToMentionedRemoteUsers(mentionedUsers, user, noteActivity);
 	}
 
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// If has in reply to note
 	if (data.reply) {
 		// Fetch watchers
 		nmRelatedPromises.push(notifyToWatchersOfReplyee(data.reply, user, nm));
 
 		// この投稿をWatchする
-		if (Users.isLocalUser(user) && user.autoWatch !== false) {
+		if (Users.isLocalUser(user) && profile.autoWatch) {
 			watch(user.id, data.reply);
 		}
 
@@ -286,7 +288,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
 		nmRelatedPromises.push(notifyToWatchersOfRenotee(data.renote, user, nm, type));
 
 		// この投稿をWatchする
-		if (Users.isLocalUser(user) && user.autoWatch !== false) {
+		if (Users.isLocalUser(user) && profile.autoWatch) {
 			watch(user.id, data.renote);
 		}
 
diff --git a/src/services/note/polls/vote.ts b/src/services/note/polls/vote.ts
index 15f1ddffbc..95e5b3ef3a 100644
--- a/src/services/note/polls/vote.ts
+++ b/src/services/note/polls/vote.ts
@@ -2,7 +2,7 @@ import watch from '../../../services/note/watch';
 import { publishNoteStream } from '../../stream';
 import { User } from '../../../models/entities/user';
 import { Note } from '../../../models/entities/note';
-import { PollVotes, Users, NoteWatchings, Polls } from '../../../models';
+import { PollVotes, Users, NoteWatchings, Polls, UserProfiles } from '../../../models';
 import { Not } from 'typeorm';
 import { genId } from '../../../misc/gen-id';
 import { createNotification } from '../../create-notification';
@@ -67,8 +67,10 @@ export default (user: User, note: Note, choice: number) => new Promise(async (re
 		}
 	});
 
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// ローカルユーザーが投票した場合この投稿をWatchする
-	if (Users.isLocalUser(user) && user.autoWatch) {
+	if (Users.isLocalUser(user) && profile.autoWatch) {
 		watch(user.id, note);
 	}
 });
diff --git a/src/services/note/reaction/create.ts b/src/services/note/reaction/create.ts
index 437b213ded..1b026cc9cc 100644
--- a/src/services/note/reaction/create.ts
+++ b/src/services/note/reaction/create.ts
@@ -8,7 +8,7 @@ import { toDbReaction } from '../../../misc/reaction-lib';
 import fetchMeta from '../../../misc/fetch-meta';
 import { User } from '../../../models/entities/user';
 import { Note } from '../../../models/entities/note';
-import { NoteReactions, Users, NoteWatchings, Notes } from '../../../models';
+import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles } from '../../../models';
 import { Not } from 'typeorm';
 import { perUserReactionsChart } from '../../chart';
 import { genId } from '../../../misc/gen-id';
@@ -79,8 +79,10 @@ export default async (user: User, note: Note, reaction: string) => {
 		}
 	});
 
+	const profile = await UserProfiles.findOne({ userId: user.id });
+
 	// ユーザーがローカルユーザーかつ自動ウォッチ設定がオンならばこの投稿をWatchする
-	if (Users.isLocalUser(user) && user.autoWatch !== false) {
+	if (Users.isLocalUser(user) && profile.autoWatch) {
 		watch(user.id, note);
 	}