diff --git a/README.md b/README.md
index 8fe140f..d93a2a6 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,12 @@ When Git 2.18 or higher is not in your PATH, falls back to the REST API to downl
     # Default: 1
     fetch-depth: ''
 
+    # Number of fetches to perform simultaneously when updating submodules: -1
+    # indicates to use git default (serial updates). 0 uses as many jobs as there are
+    # processors.
+    # Default: -1
+    fetch-jobs: ''
+
     # Whether to download Git-LFS files
     # Default: false
     lfs: ''
diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts
index 2acec38..c376271 100644
--- a/__test__/git-auth-helper.test.ts
+++ b/__test__/git-auth-helper.test.ts
@@ -798,6 +798,7 @@ async function setup(testName: string): Promise<void> {
     clean: true,
     commit: '',
     fetchDepth: 1,
+    fetchJobs: -1,
     lfs: false,
     submodules: false,
     nestedSubmodules: false,
diff --git a/__test__/input-helper.test.ts b/__test__/input-helper.test.ts
index 1a8e5c9..f0f0d14 100644
--- a/__test__/input-helper.test.ts
+++ b/__test__/input-helper.test.ts
@@ -80,6 +80,7 @@ describe('input-helper tests', () => {
     expect(settings.commit).toBeTruthy()
     expect(settings.commit).toBe('1234567890123456789012345678901234567890')
     expect(settings.fetchDepth).toBe(1)
+    expect(settings.fetchJobs).toBe(-1)
     expect(settings.lfs).toBe(false)
     expect(settings.ref).toBe('refs/heads/some-ref')
     expect(settings.repositoryName).toBe('some-repo')
diff --git a/action.yml b/action.yml
index cab09eb..2495e0b 100644
--- a/action.yml
+++ b/action.yml
@@ -56,6 +56,12 @@ inputs:
   fetch-depth:
     description: 'Number of commits to fetch. 0 indicates all history for all branches and tags.'
     default: 1
+  fetch-jobs:
+    description: >
+      Number of fetches to perform simultaneously when updating submodules:
+      -1 indicates to use git default (serial updates). 0 uses as many jobs as
+      there are processors.
+    default: -1
   lfs:
     description: 'Whether to download Git-LFS files'
     default: false
diff --git a/dist/index.js b/dist/index.js
index 0a33ea1..eccac6e 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -7670,7 +7670,7 @@ class GitCommandManager {
             yield this.execGit(args);
         });
     }
-    submoduleUpdate(fetchDepth, recursive) {
+    submoduleUpdate(fetchDepth, recursive, fetchJobs) {
         return __awaiter(this, void 0, void 0, function* () {
             const args = ['-c', 'protocol.version=2'];
             args.push('submodule', 'update', '--init', '--force');
@@ -7680,6 +7680,9 @@ class GitCommandManager {
             if (recursive) {
                 args.push('--recursive');
             }
+            if (fetchJobs > -1) {
+                args.push(`--jobs=${fetchJobs}`);
+            }
             yield this.execGit(args);
         });
     }
@@ -18537,6 +18540,15 @@ function getInputs() {
         }
         core.debug(`submodules = ${result.submodules}`);
         core.debug(`recursive submodules = ${result.nestedSubmodules}`);
+        // Fetch jobs during submodule update
+        result.fetchJobs = -1;
+        if (result.submodules) {
+            result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'));
+            if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
+                result.fetchJobs = -1;
+            }
+            core.debug(`fetch jobs = ${result.fetchJobs}`);
+        }
         // Auth token
         result.authToken = core.getInput('token', { required: true });
         // SSH
@@ -32009,7 +32021,7 @@ function getSource(settings) {
                 // Checkout submodules
                 core.startGroup('Fetching submodules');
                 yield git.submoduleSync(settings.nestedSubmodules);
-                yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules);
+                yield git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules, settings.fetchJobs);
                 yield git.submoduleForeach('git config --local gc.auto 0', settings.nestedSubmodules);
                 core.endGroup();
                 // Persist credentials
diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts
index 01aedfe..938dca3 100644
--- a/src/git-command-manager.ts
+++ b/src/git-command-manager.ts
@@ -40,7 +40,11 @@ export interface IGitCommandManager {
   shaExists(sha: string): Promise<boolean>
   submoduleForeach(command: string, recursive: boolean): Promise<string>
   submoduleSync(recursive: boolean): Promise<void>
-  submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void>
+  submoduleUpdate(
+    fetchDepth: number,
+    recursive: boolean,
+    fetchJobs: number
+  ): Promise<void>
   tagExists(pattern: string): Promise<boolean>
   tryClean(): Promise<boolean>
   tryConfigUnset(configKey: string, globalConfig?: boolean): Promise<boolean>
@@ -343,7 +347,11 @@ class GitCommandManager {
     await this.execGit(args)
   }
 
-  async submoduleUpdate(fetchDepth: number, recursive: boolean): Promise<void> {
+  async submoduleUpdate(
+    fetchDepth: number,
+    recursive: boolean,
+    fetchJobs: number
+  ): Promise<void> {
     const args = ['-c', 'protocol.version=2']
     args.push('submodule', 'update', '--init', '--force')
     if (fetchDepth > 0) {
@@ -354,6 +362,10 @@ class GitCommandManager {
       args.push('--recursive')
     }
 
+    if (fetchJobs > -1) {
+      args.push(`--jobs=${fetchJobs}`)
+    }
+
     await this.execGit(args)
   }
 
diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts
index 48f20da..a84dc58 100644
--- a/src/git-source-provider.ts
+++ b/src/git-source-provider.ts
@@ -206,7 +206,11 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
       // Checkout submodules
       core.startGroup('Fetching submodules')
       await git.submoduleSync(settings.nestedSubmodules)
-      await git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules)
+      await git.submoduleUpdate(
+        settings.fetchDepth,
+        settings.nestedSubmodules,
+        settings.fetchJobs
+      )
       await git.submoduleForeach(
         'git config --local gc.auto 0',
         settings.nestedSubmodules
diff --git a/src/git-source-settings.ts b/src/git-source-settings.ts
index 2da5622..8cb8f7e 100644
--- a/src/git-source-settings.ts
+++ b/src/git-source-settings.ts
@@ -34,6 +34,11 @@ export interface IGitSourceSettings {
    */
   fetchDepth: number
 
+  /**
+   * The number of fetches to perform simultaneously when updating submodules
+   */
+  fetchJobs: number
+
   /**
    * Indicates whether to fetch LFS objects
    */
diff --git a/src/input-helper.ts b/src/input-helper.ts
index 237b06a..cbc951d 100644
--- a/src/input-helper.ts
+++ b/src/input-helper.ts
@@ -106,6 +106,16 @@ export async function getInputs(): Promise<IGitSourceSettings> {
   core.debug(`submodules = ${result.submodules}`)
   core.debug(`recursive submodules = ${result.nestedSubmodules}`)
 
+  // Fetch jobs during submodule update
+  result.fetchJobs = -1
+  if (result.submodules) {
+    result.fetchJobs = Math.floor(Number(core.getInput('fetch-jobs') || '-1'))
+    if (isNaN(result.fetchJobs) || result.fetchJobs < -1) {
+      result.fetchJobs = -1
+    }
+    core.debug(`fetch jobs = ${result.fetchJobs}`)
+  }
+
   // Auth token
   result.authToken = core.getInput('token', {required: true})