diff --git a/CHANGELOG b/CHANGELOG
index 983a219703abf054e036e0ba5b6c232198314839..7572b6af151a400cd8ddf6bdd8f89a604dba8b13 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,6 +22,7 @@ v 8.5.0 (unreleased)
   - Fix visibility level text in admin area (Zeger-Jan van de Weg)
   - Warn admin during OAuth of granting admin rights (Zeger-Jan van de Weg)
   - Update the ExternalIssue regex pattern (Blake Hitchcock)
+  - Remember user's inline/side-by-side diff view preference in a cookie (Kirill Katsnelson)
   - Optimized performance of finding issues to be closed by a merge request
   - Revert "Add IP check against DNSBLs at account sign-up"
   - Fix API to keep request parameters in Link header (Michael Potthoff)
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index dd32d509191ecb1359be717b560a773105504e55..a326bc582158240f4ad0759dffc57092900cf72e 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -28,6 +28,11 @@ class Projects::ApplicationController < ApplicationController
 
   private
 
+  def apply_diff_view_cookie!
+    view = params[:view] || cookies[:diff_view]
+    cookies.permanent[:diff_view] = params[:view] = view if view
+  end
+
   def builds_enabled
     return render_404 unless @project.builds_enabled?
   end
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index f5a169e5aa984847cc9435914d7745bdc5a88079..5a084e123a15171dac1ecbd1ebdbae3959ce0925 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -13,6 +13,8 @@ class Projects::CommitController < Projects::ApplicationController
   def show
     return git_not_found! unless @commit
 
+    apply_diff_view_cookie!
+
     @line_notes = commit.notes.inline
     @note = @project.build_commit_note(commit)
     @notes = commit.notes.not_inline.fresh
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index ed3050d59aafa73943aa6bfb50ae945e59503241..9d588c370aabeff7a577f6168efe87272882bb5f 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -57,6 +57,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
   end
 
   def diffs
+    apply_diff_view_cookie!
+
     @commit = @merge_request.last_commit
     @base_commit = @merge_request.diff_base_commit
 
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 6aaec224f6eeff04ceaed2106978fa40201186ab..9450a389d814ee9b0dcba91d0b2615a6f9cb4e5e 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -188,7 +188,7 @@ describe Projects::MergeRequestsController do
         expect(response).to render_template('diffs')
       end
     end
-    
+
     context 'as json' do
       it 'renders the diffs template to a string' do
         go format: 'json'
@@ -199,6 +199,32 @@ describe Projects::MergeRequestsController do
     end
   end
 
+  describe 'GET diffs with view' do
+    def go(extra_params = {})
+      params = {
+        namespace_id: project.namespace.to_param,
+        project_id:   project.to_param,
+        id:           merge_request.iid
+      }
+
+      get :diffs, params.merge(extra_params)
+    end
+
+    it 'saves the preferred diff view in a cookie' do
+      go view: 'parallel'
+
+      expect(response.cookies['diff_view']).to eq('parallel')
+    end
+
+    it 'assigns :view param based on cookie' do
+      request.cookies['diff_view'] = 'parallel'
+
+      go
+
+      expect(controller.params[:view]).to eq 'parallel'
+    end
+  end
+
   describe 'GET commits' do
     def go(format: 'html')
       get :commits,