diff --git a/app/models/key.rb b/app/models/key.rb
index 83e4fc79798419b037645925f132b0a6eb0ca3c9..359538d2cbd5c3e841c64518daa5fb82c1845a32 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -21,20 +21,14 @@ class Key < ActiveRecord::Base
   def update_repository
     Gitlabhq::GitHost.system.new.configure do |c|
       c.update_keys(identifier, key)
-
-      projects.each do |project|
-        c.update_project(project.path, project)
-      end
+      c.update_projects(projects)
     end
   end
 
   def repository_delete_key
     Gitlabhq::GitHost.system.new.configure do |c|
       c.delete_key(identifier)
-
-      projects.each do |project|
-        c.update_project(project.path, project)
-      end
+      c.update_projects(projects)
     end
   end
 
diff --git a/lib/gitlabhq/gitolite.rb b/lib/gitlabhq/gitolite.rb
index e79afb55577fb558ade0ebb53bb6fd2046bbc241..0822c25e621468d582bbfb68bcd2c6b4ecf25ea5 100644
--- a/lib/gitlabhq/gitolite.rb
+++ b/lib/gitlabhq/gitolite.rb
@@ -81,5 +81,33 @@ module Gitlabhq
 
       ga_repo.save
     end
+
+    # Updates many projects and uses project.path as the repo path
+    # An order of magnitude faster than update_project
+    def update_projects(projects)
+      ga_repo = ::Gitolite::GitoliteAdmin.new(File.join(@local_dir,'gitolite'))
+      conf = ga_repo.config
+
+      projects.each do |project|
+        repo_name = project.path
+
+        repo = if conf.has_repo?(repo_name)
+                 conf.get_repo(repo_name)
+               else 
+                 ::Gitolite::Config::Repo.new(repo_name)
+               end
+
+        name_readers = project.repository_readers
+        name_writers = project.repository_writers
+
+        repo.clean_permissions
+        repo.add_permission("R", "", name_readers) unless name_readers.blank?
+        repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
+        conf.add_repo(repo, true)
+      end
+
+      ga_repo.save
+    end
+
   end
 end