diff --git a/app/models.py b/app/models.py
index c53956fd0e9e63b7dfc3830abdf26f9f84a8394f..4281fc55bcf25eec473ed4ad89caa76e8d550f4c 100644
--- a/app/models.py
+++ b/app/models.py
@@ -285,6 +285,12 @@ corpus_followers = db.Table(
     db.Column('corpus_id', db.ForeignKey('corpora.id'), primary_key=True)
 )
 
+user_followers = db.Table(
+    'user_followers',
+    db.Model.metadata,
+    db.Column('follower_user_id', db.ForeignKey('users.id'), primary_key=True),
+    db.Column('followed_user_id', db.ForeignKey('users.id'), primary_key=True)
+)
 
 class User(HashidMixin, UserMixin, db.Model):
     __tablename__ = 'users'
@@ -343,6 +349,14 @@ class User(HashidMixin, UserMixin, db.Model):
         backref=db.backref('followers', lazy='dynamic'),
         lazy='dynamic'
     )
+    followed_users = db.relationship(
+        'User',
+        secondary=user_followers,
+        primaryjoin=(user_followers.c.follower_user_id == id),
+        secondaryjoin=(user_followers.c.followed_user_id == id),
+        backref=db.backref('followers', lazy='dynamic'),
+        lazy='dynamic'
+    )
     jobs = db.relationship(
         'Job',
         backref='user',
@@ -559,17 +573,29 @@ class User(HashidMixin, UserMixin, db.Model):
     #endregion Profile Privacy settings
 
     def follow_corpus(self, corpus):
-        if not self.is_following(corpus):
+        if not self.is_following_corpus(corpus):
             self.followed_corpora.append(corpus)
 
     def unfollow_corpus(self, corpus):
-        if self.is_following(corpus):
+        if self.is_following_corpus(corpus):
             self.followed_corpora.remove(corpus)
     
     def is_following_corpus(self, corpus):
         return self.followed_corpora.filter(
             corpus_followers.c.corpus_id == corpus.id).count() > 0
 
+    def follow_user(self, user):
+        if not self.is_following_user(user):
+            self.followed_users.append(user)
+
+    def unfollow_user(self, user):
+        if self.is_following_user(user):
+            self.followed_users.remove(user)
+    
+    def is_following_user(self, user):
+        return self.followed_users.filter(
+            user_followers.c.followed_user_id == user.id).count() > 0
+
     def to_json_serializeable(self, backrefs=False, relationships=False, filter_by_privacy_settings=False):
         json_serializeable = {
             'id': self.hashid,
diff --git a/migrations/versions/7d51bc4b6079_.py b/migrations/versions/7d51bc4b6079_.py
new file mode 100644
index 0000000000000000000000000000000000000000..df825ad1360245e35ed988350a842499a217bd03
--- /dev/null
+++ b/migrations/versions/7d51bc4b6079_.py
@@ -0,0 +1,31 @@
+"""Add user_followers table
+
+Revision ID: 7d51bc4b6079
+Revises: 4aa88f253dab
+Create Date: 2023-01-17 12:48:33.261942
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '7d51bc4b6079'
+down_revision = '4aa88f253dab'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    op.create_table(
+        'user_followers',
+        sa.Column('follower_user_id', sa.Integer(), nullable=False),
+        sa.Column('followed_user_id', sa.Integer(), nullable=False),
+        sa.ForeignKeyConstraint(['followed_user_id'], ['users.id'], ),
+        sa.ForeignKeyConstraint(['follower_user_id'], ['users.id'], ),
+        sa.PrimaryKeyConstraint('follower_user_id', 'followed_user_id')
+    )
+
+
+def downgrade():
+    op.drop_table('user_followers')