diff --git a/autoload/magit/git.vim b/autoload/magit/git.vim
index 0705b7ed04b9ed9ca66781b748e9d15285ec2620..54552157795e51caafef58589202b2296c0162ef 100644
--- a/autoload/magit/git.vim
+++ b/autoload/magit/git.vim
@@ -17,14 +17,19 @@ endfunction
 " magit#git#get_status: this function returns the git status output formated
 " into a List of Dict as
 " [ {staged', 'unstaged', 'filename'}, ... ]
-function! magit#git#get_status()
+function! magit#git#get_status(update_mode)
 	let file_list = []
 
 	" systemlist v7.4.248 problem again
 	" we can't use git status -z here, because system doesn't make the
 	" difference between NUL and NL. -status z terminate entries with NUL,
 	" instead of NF
-	let status_list=magit#sys#systemlist(g:magit_git_cmd . " status --porcelain")
+	if a:update_mode == 'fast'
+		let ignore_flag = 'dirty'
+	else
+		let ignore_flag = 'none'
+	endif
+	let status_list=magit#sys#systemlist(g:magit_git_cmd . " status --porcelain --ignore-submodules=" . ignore_flag)
 	for file_status_line in status_list
 		let line_match = matchlist(file_status_line, '\(.\)\(.\) \%(.\{-\} -> \)\?"\?\(.\{-\}\)"\?$')
 		let filename = line_match[3]
@@ -153,10 +158,8 @@ endfunction
 " untracked content
 " param[in] submodule: submodule path
 " param[in] check_level: can be modified or untracked
-function! magit#git#sub_check(submodule, check_level)
-	let ignore_flag = ( a:check_level == 'modified' ) ?
-				\ '--ignore-submodules=untracked' : ''
-	let git_cmd=g:magit_git_cmd . " status --porcelain " . ignore_flag . " " . a:submodule
+function! magit#git#sub_check(submodule, ignore_flag)
+	let git_cmd=g:magit_git_cmd . " status --porcelain --ignore-submodules=" . a:ignore_flag . " " . a:submodule
 	return ( !empty(magit#sys#systemlist(git_cmd)) )
 endfunction
 
@@ -172,10 +175,10 @@ function! magit#git#git_sub_summary(filename, mode)
 	silent let diff_list=magit#sys#systemlist(git_cmd)
 	if ( empty(diff_list) )
 		if ( a:mode == 'unstaged' )
-			if ( magit#git#sub_check(a:filename, 'modified') )
+			if ( magit#git#sub_check(a:filename, 'untracked') )
 				return "modified content"
 			endif
-			if ( magit#git#sub_check(a:filename, 'untracked') )
+			if ( magit#git#sub_check(a:filename, 'none') )
 				return "untracked content"
 			endif
 		endif
diff --git a/autoload/magit/state.vim b/autoload/magit/state.vim
index 51488533c058cfe6ad23115036d5c8646fd7f31e..2ccde398c3b7618100184f713fb3cf3bdfe5643e 100644
--- a/autoload/magit/state.vim
+++ b/autoload/magit/state.vim
@@ -277,7 +277,7 @@ function! magit#state#update() dict
 	try
 		call magit#utils#chdir(magit#git#top_dir())
 		call magit#utils#refresh_submodule_list()
-		let status_list = magit#git#get_status()
+		let status_list = magit#git#get_status(b:magit_update_mode)
 		for [mode, diff_dict_mode] in items(self.dict)
 			for file_status in status_list
 				let status=file_status[mode]
diff --git a/common/magit_common.vim b/common/magit_common.vim
index f1f812371e6d69e0074b4b5edc8bdcc6b7d4cbd3..72b7f26548f8e58b9bdbab1c119474e0253f2b62 100644
--- a/common/magit_common.vim
+++ b/common/magit_common.vim
@@ -16,6 +16,7 @@ let g:magit_section_info = {
  \ 'cur_upstream':   'Upstream:',
  \ 'cur_push':       'Push:',
  \ 'commit_mode':    'Commit mode:',
+ \ 'update_mode':    'Update mode:',
  \ }
 
 let g:magit_git_status_code = {
diff --git a/doc/vimagit.txt b/doc/vimagit.txt
index e0ef71e178cc88c05e3c3ce3972a7c6307ad926c..aeaa4a050a8e376ba74318a6c00128eddbc1bd95 100644
--- a/doc/vimagit.txt
+++ b/doc/vimagit.txt
@@ -366,6 +366,24 @@ section only.
 
 ------------------------------------------------------------------------------
 
+UPDATE MODE                                               *vimagit-update-mode*
+
+Update can be slow, especially when the repository has a lot of (recursive)
+submodules. To speed up update, submodules status can be lighter.
+
+By setting update mode to normal, git status performs the default behavior.
+By setting update mode to fast, git status will use the option
+`--ignore-submodules=dirty`. This option will only search for commit changes
+in the submodules. All modified and untracked changes will be ignored.
+
+It is possible to control this option by two ways:
+- globally, by setting the vim option `g:magit_update_mode`
+- at repository level, by setting the git option:
+  `git config vimagit.update-mode fast`
+- for the record, it is also possible to set the option globally with git:
+  `git config --global vimagit.update-mode fast`
+
+------------------------------------------------------------------------------
 
 AUTOCMD                                                        *vimagit-autocmd*
 
@@ -517,6 +535,11 @@ empty).
 Default value is 0.
 let g:magit_auto_close=[01]
 
+                                                   *vimagit-g:magit_update_mode*
+See |vimagit-update-mode|.
+Can be set to 'normal' and 'fast'.
+Default value is 'normal'.
+
 ===============================================================================
 6. FAQ                                                             *vimagit-FAQ*
 
diff --git a/plugin/magit.vim b/plugin/magit.vim
index 4fb36e4dc16d1b0c6113f883a56d1c45139fa2a3..1dd5b8e32f66186360c189c11704b23aca73d08f 100644
--- a/plugin/magit.vim
+++ b/plugin/magit.vim
@@ -33,6 +33,10 @@ let g:magit_default_sections       = get(g:, 'magit_default_sections',
 let g:magit_discard_untracked_do_delete = get(g:, 'magit_discard_untracked_do_delete',        0)
 
 let g:magit_refresh_gutter         = get(g:, 'magit_refresh_gutter'   ,         1)
+
+let g:magit_update_mode           = get(g:, 'magit_update_mode',      'normal')
+let g:magit_update_modes = ['normal', 'fast']
+
 " Should deprecate the following
 let g:magit_refresh_gitgutter      = get(g:, 'magit_refresh_gitgutter',         0)
 
@@ -95,7 +99,12 @@ function! s:mg_get_info()
 	let upstream_msg=s:mg_cut_str(magit#git#get_commit_subject(upstream_br), limit)
 	let push_msg=s:mg_cut_str(magit#git#get_commit_subject(push_br), limit)
 
-	let head_line=magit#utils#strip(printf("%-*s %-*s %s", 
+	let update_msg = ""
+	if b:magit_last_update_time > 1.0 && b:magit_update_mode_undefined == 1
+				\ && b:magit_update_mode != 'fast'
+		let update_msg = "update is slow, consider fast update `:help vimagit-update-mode`"
+	endif
+	let head_line=magit#utils#strip(printf("%-*s %-*s %s",
 				\ align_w, g:magit_section_info.cur_head,
 				\ max_br_w, head_br, head_msg))
 	let upstream_line=magit#utils#strip(printf("%-*s %-*s %s",
@@ -104,7 +113,9 @@ function! s:mg_get_info()
 	let push_line=magit#utils#strip(printf("%-*s %-*s %s",
 				\ align_w, g:magit_section_info.cur_push,
 				\ max_br_w, push_br, push_msg))
-
+	let update_line=magit#utils#strip(printf("%-*s %-*s %s",
+				\ align_w, g:magit_section_info.update_mode,
+				\ max_br_w, b:magit_update_mode, update_msg))
 
 	silent put =g:magit_sections.info
 	silent put =magit#utils#underline(g:magit_sections.info)
@@ -113,6 +124,7 @@ function! s:mg_get_info()
 	silent put =head_line
 	silent put =upstream_line
 	silent put =push_line
+	silent put =update_line
 
 	if ( b:magit_current_commit_mode != '' )
 		let commit_mode_line=printf("%-*s %s",
@@ -615,7 +627,15 @@ function! magit#update_buffer(...)
 		let prev_filename = (pos > 0) ? filenames[pos-1] : ''
 	endif
 
+	if has('reltime')
+		let start_time = reltime()
+	endif
 	call b:state.update()
+	if has('reltime')
+		let b:magit_last_update_time = reltimefloat(start_time)
+	else
+		let b:magit_last_update_time = 0
+	endif
 
 	if ( g:magit_auto_close == 1 &&
 				\ b:magit_just_commited == 1 &&
@@ -866,6 +886,30 @@ function! magit#show_magit(display, ...)
 		return
 	endif
 
+	if index(g:magit_update_modes, g:magit_update_mode) == -1
+		echohl WarningMsg
+		echom "g:magit_update_mode='" . g:magit_update_mode . "' must be one of the following: " . join(g:magit_update_modes, ',')
+		echom "Reset to normal"
+		echohl None
+		let g:magit_update_mode = 'normal'
+	endif
+
+	let update_mode = magit#git#get_config('vimagit.update-mode', 'undefined')
+	if update_mode == 'undefined'
+		let b:magit_update_mode_undefined = 1
+		let b:magit_update_mode = g:magit_update_mode
+	else
+		let b:magit_update_mode_undefined = 0
+		if index(g:magit_update_modes, update_mode) == -1
+			echohl WarningMsg
+			echom "vimagit.update-mode='" . update_mode . "' (gitconfig) must be one of the following: " . join(g:magit_update_modes, ',')
+			echom "Reset to g:magit_update_mode"
+			echohl None
+			let update_mode = g:magit_update_mode
+		endif
+		let b:magit_update_mode = update_mode
+	endif
+
 	let b:state = deepcopy(g:magit#state#state)
 	call magit#utils#setbufnr(bufnr(buffer_name))
 	call magit#sign#init()
diff --git a/syntax/magit.vim b/syntax/magit.vim
index 3726ead52f7064d1808e179b696b550797dc6e9c..40521d6102ea4b2b62fc18b3ed87b3ec4491cfc6 100644
--- a/syntax/magit.vim
+++ b/syntax/magit.vim
@@ -39,6 +39,7 @@ execute 'syn match gitInfoRepo   "\%(' . g:magit_section_info.cur_repo . '\)\@<=
 execute 'syn match gitInfoHead "\%(' . g:magit_section_info.cur_head . '\s*\)\@<=\S\+" oneline'
 execute 'syn match gitInfoUpstream "\%(' . g:magit_section_info.cur_upstream . '\s*\)\@<=\S\+" oneline'
 execute 'syn match gitInfoPush "\%(' . g:magit_section_info.cur_push . '\s*\)\@<=\S\+" oneline'
+execute 'syn match gitUpdateMode "\%(' . g:magit_section_info.update_mode . '\s*\)\@<=\S\+" oneline'
 execute 'syn match gitCommitMode "\%(' . g:magit_section_info.commit_mode . '\)\@<=.*$" oneline'
 "execute 'syn match gitInfoCommit "\%(' . g:magit_section_info.cur_commit . '\)\@<=.*$" contains=infoSha1 oneline'
 "syntax match infoSha1 containedin=gitInfoCommit "\x\{7,}"
@@ -47,6 +48,7 @@ highlight default link gitInfoRepo Directory
 highlight default link gitInfoHead Identifier
 highlight default link gitInfoUpstream Identifier
 highlight default link gitInfoPush Identifier
+highlight default link gitUpdateMode Identifier
 highlight default link gitCommitMode Special
 highlight default link infoSha1 Identifier