diff --git a/doc/api/users.md b/doc/api/users.md
index 382d5fe03c1f37feef3d6749f804b9f8ed18f1ed..3578d3197749ed88046135de9d274ef04400855f 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -785,6 +785,7 @@ Set the status of the current user.
 
 ```plaintext
 PUT /user/status
+PATCH /user/status
 ```
 
 | Attribute            | Type   | Required | Description                                                                                                                                                                                                             |
@@ -793,7 +794,9 @@ PUT /user/status
 | `message`            | string | no       | Message to set as a status. It can also contain emoji codes. Cannot exceed 100 characters.                                                                                                                                                      |
 | `clear_status_after` | string | no       | Automatically clean up the status after a given time interval, allowed values: `30_minutes`, `3_hours`, `8_hours`, `1_day`, `3_days`, `7_days`, `30_days`
 
-When both parameters `emoji` and `message` are empty, the status is cleared. When the `clear_status_after` parameter is missing from the request, the previously set value for `"clear_status_after` is cleared.
+Difference between `PUT` and `PATCH`
+
+When using `PUT` any parameters that are not passed will be set to `null` and therefore cleared. When using `PATCH` any parameters that are not passed will be ignored. Explicitly pass `null` to clear a field.
 
 ```shell
 curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" --data "clear_status_after=1_day" --data "emoji=coffee" \
diff --git a/lib/api/users.rb b/lib/api/users.rb
index d2d45c942918c3448a36b09fd222880ed8de219d..7b4c9104cd8194476e7e5efc718ff50dee236bd5 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -1020,6 +1020,25 @@ def target_user
         end
       end
 
+      helpers do
+        def set_user_status(include_missing_params:)
+          forbidden! unless can?(current_user, :update_user_status, current_user)
+
+          if ::Users::SetStatusService.new(current_user, declared_params(include_missing: include_missing_params)).execute
+            present current_user.status, with: Entities::UserStatus
+          else
+            render_validation_error!(current_user.status)
+          end
+        end
+
+        params :set_user_status_params do
+          optional :emoji, type: String, desc: "The emoji to set on the status"
+          optional :message, type: String, desc: "The status message to set"
+          optional :availability, type: String, desc: "The availability of user to set"
+          optional :clear_status_after, type: String, desc: "Automatically clear emoji, message and availability fields after a certain time", values: UserStatus::CLEAR_STATUS_QUICK_OPTIONS.keys
+        end
+      end
+
       desc "Get the currently authenticated user's SSH keys" do
         success Entities::SSHKey
       end
@@ -1299,21 +1318,30 @@ def target_user
 
       desc 'Set the status of the current user' do
         success Entities::UserStatus
+        detail 'Any parameters that are not passed will be nullified.'
       end
       params do
-        optional :emoji, type: String, desc: "The emoji to set on the status"
-        optional :message, type: String, desc: "The status message to set"
-        optional :availability, type: String, desc: "The availability of user to set"
-        optional :clear_status_after, type: String, desc: "Automatically clear emoji, message and availability fields after a certain time", values: UserStatus::CLEAR_STATUS_QUICK_OPTIONS.keys
+        use :set_user_status_params
       end
       put "status", feature_category: :users do
-        forbidden! unless can?(current_user, :update_user_status, current_user)
+        set_user_status(include_missing_params: true)
+      end
 
-        if ::Users::SetStatusService.new(current_user, declared_params).execute
-          present current_user.status, with: Entities::UserStatus
-        else
-          render_validation_error!(current_user.status)
+      desc 'Set the status of the current user' do
+        success Entities::UserStatus
+        detail 'Any parameters that are not passed will be ignored.'
+      end
+      params do
+        use :set_user_status_params
+      end
+      patch "status", feature_category: :users do
+        if declared_params(include_missing: false).empty?
+          status :ok
+
+          break
         end
+
+        set_user_status(include_missing_params: false)
       end
 
       desc 'get the status of the current user' do
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index bfb71d95f5e9b06878f8ff247f930241961d121e..0808b8b3a194f75970573b179945c5395df21221 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -4045,60 +4045,164 @@ def update_password(user, admin, password = User.random_password)
     end
   end
 
-  describe 'GET /user/status' do
-    let(:path) { '/user/status' }
+  describe '/user/status' do
+    let(:user_status) { create(:user_status, clear_status_at: 8.hours.from_now) }
+    let(:user_with_status) { user_status.user }
+    let(:params) { {} }
+    let(:request_user) { user }
 
-    it_behaves_like 'rendering user status'
-  end
+    shared_examples '/user/status successful response' do
+      context 'when request is successful' do
+        let(:params) { { emoji: 'smirk', message: 'hello world' } }
 
-  describe 'PUT /user/status' do
-    it 'saves the status' do
-      put api('/user/status', user), params: { emoji: 'smirk', message: 'hello world' }
+        it 'saves the status' do
+          set_user_status
 
-      expect(response).to have_gitlab_http_status(:success)
-      expect(json_response['emoji']).to eq('smirk')
+          expect(response).to have_gitlab_http_status(:success)
+          expect(json_response['emoji']).to eq('smirk')
+          expect(json_response['message']).to eq('hello world')
+        end
+      end
     end
 
-    it 'renders errors when the status was invalid' do
-      put api('/user/status', user), params: { emoji: 'does not exist', message: 'hello world' }
+    shared_examples '/user/status unsuccessful response' do
+      context 'when request is unsuccessful' do
+        let(:params) { { emoji: 'does not exist', message: 'hello world' } }
 
-      expect(response).to have_gitlab_http_status(:bad_request)
-      expect(json_response['message']['emoji']).to be_present
+        it 'renders errors' do
+          set_user_status
+
+          expect(response).to have_gitlab_http_status(:bad_request)
+          expect(json_response['message']['emoji']).to be_present
+        end
+      end
     end
 
-    it 'deletes the status when passing empty values' do
-      put api('/user/status', user)
+    shared_examples '/user/status passing nil for params' do
+      context 'when passing nil for params' do
+        let(:params) { { emoji: nil, message: nil, clear_status_after: nil } }
+        let(:request_user) { user_with_status }
 
-      expect(response).to have_gitlab_http_status(:success)
-      expect(user.reload.status).to be_nil
+        it 'deletes the status' do
+          set_user_status
+
+          expect(response).to have_gitlab_http_status(:success)
+          expect(user_with_status.status).to be_nil
+        end
+      end
     end
 
-    context 'when clear_status_after is given' do
-      it 'sets the clear_status_at column' do
-        freeze_time do
+    shared_examples '/user/status clear_status_after field' do
+      context 'when clear_status_after is valid', :freeze_time do
+        let(:params) { { emoji: 'smirk', message: 'hello world', clear_status_after: '3_hours' } }
+
+        it 'sets the clear_status_at column' do
           expected_clear_status_at = 3.hours.from_now
 
-          put api('/user/status', user), params: { emoji: 'smirk', message: 'hello world', clear_status_after: '3_hours' }
+          set_user_status
 
           expect(response).to have_gitlab_http_status(:success)
-          expect(user.status.reload.clear_status_at).to be_within(1.minute).of(expected_clear_status_at)
-          expect(Time.parse(json_response["clear_status_at"])).to be_within(1.minute).of(expected_clear_status_at)
+          expect(user.status.clear_status_at).to be_like_time(expected_clear_status_at)
+          expect(Time.parse(json_response["clear_status_at"])).to be_like_time(expected_clear_status_at)
         end
       end
 
-      it 'unsets the clear_status_at column' do
-        user.create_status!(clear_status_at: 5.hours.ago)
+      context 'when clear_status_after is nil' do
+        let(:params) { { emoji: 'smirk', message: 'hello world', clear_status_after: nil } }
+        let(:request_user) { user_with_status }
 
-        put api('/user/status', user), params: { emoji: 'smirk', message: 'hello world', clear_status_after: nil }
+        it 'unsets the clear_status_at column' do
+          set_user_status
 
-        expect(response).to have_gitlab_http_status(:success)
-        expect(user.status.reload.clear_status_at).to be_nil
+          expect(response).to have_gitlab_http_status(:success)
+          expect(user_with_status.status.clear_status_at).to be_nil
+        end
       end
 
-      it 'raises error when unknown status value is given' do
-        put api('/user/status', user), params: { emoji: 'smirk', message: 'hello world', clear_status_after: 'wrong' }
+      context 'when clear_status_after is invalid' do
+        let(:params) { { emoji: 'smirk', message: 'hello world', clear_status_after: 'invalid' } }
 
-        expect(response).to have_gitlab_http_status(:bad_request)
+        it 'raises error when unknown status value is given' do
+          set_user_status
+
+          expect(response).to have_gitlab_http_status(:bad_request)
+        end
+      end
+    end
+
+    describe 'GET' do
+      let(:path) { '/user/status' }
+
+      it_behaves_like 'rendering user status'
+    end
+
+    describe 'PUT' do
+      subject(:set_user_status) { put api('/user/status', request_user), params: params }
+
+      include_examples '/user/status successful response'
+
+      include_examples '/user/status unsuccessful response'
+
+      include_examples '/user/status passing nil for params'
+
+      include_examples '/user/status clear_status_after field'
+
+      context 'when passing empty params' do
+        let(:request_user) { user_with_status }
+
+        it 'deletes the status' do
+          set_user_status
+
+          expect(response).to have_gitlab_http_status(:success)
+          expect(user_with_status.status).to be_nil
+        end
+      end
+
+      context 'when clear_status_after is not given' do
+        let(:params) { { emoji: 'smirk', message: 'hello world' } }
+        let(:request_user) { user_with_status }
+
+        it 'unsets clear_status_at column' do
+          set_user_status
+
+          expect(response).to have_gitlab_http_status(:success)
+          expect(user_with_status.status.clear_status_at).to be_nil
+        end
+      end
+    end
+
+    describe 'PATCH' do
+      subject(:set_user_status) { patch api('/user/status', request_user), params: params }
+
+      include_examples '/user/status successful response'
+
+      include_examples '/user/status unsuccessful response'
+
+      include_examples '/user/status passing nil for params'
+
+      include_examples '/user/status clear_status_after field'
+
+      context 'when passing empty params' do
+        let(:request_user) { user_with_status }
+
+        it 'does not update the status' do
+          set_user_status
+
+          expect(response).to have_gitlab_http_status(:success)
+          expect(user_with_status.status).to eq(user_status)
+        end
+      end
+
+      context 'when clear_status_after is not given' do
+        let(:params) { { emoji: 'smirk', message: 'hello world' } }
+        let(:request_user) { user_with_status }
+
+        it 'does not unset clear_status_at column' do
+          set_user_status
+
+          expect(response).to have_gitlab_http_status(:success)
+          expect(user_with_status.status.clear_status_at).not_to be_nil
+        end
       end
     end
   end