diff --git a/doc/man/man1/salloc.1 b/doc/man/man1/salloc.1
index 6913d29e9783caf199db2aea0085ead7bc3ead08..7d0347840b79a9a5fadd0a6295964658b6aff5dd 100644
--- a/doc/man/man1/salloc.1
+++ b/doc/man/man1/salloc.1
@@ -608,6 +608,16 @@ License names can be followed by a colon and count
 Multiple license names should be comma separated (e.g.
 "\-\-licenses=foo:4,bar").
 
+.TP
+\fB\-M\fR, \fB\-\-clusters\fR=<\fIstring\fR>
+Clusters to issue commands to.  Multiple cluster names may be comma separated.
+The job will be submitted to the one cluster providing the earliest expected
+job initiation time. The default value is the current cluster. A value of
+\(aq\fIall\fR' will query to run on all clusters.  Note the
+\fB\-\-export\fR option to control environment variables exported
+between clusters.
+Note that the SlurmDBD must be up for this option to work properly.
+
 .TP
 \fB\-m\fR, \fB\-\-distribution\fR=
 \fIarbitrary\fR|<\fIblock\fR|\fIcyclic\fR|\fIplane=<options>\fR[:\fIblock\fR|\fIcyclic\fR|\fIfcyclic\fR]>
@@ -1476,6 +1486,9 @@ Same as \fB\-\-bell\fR
 \fBSALLOC_BURST_BUFFER\fR
 Same as \fB\-\-bb\fR
 .TP
+\fBSALLOC_CLUSTERS\fR or \fBSLURM_CLUSTERS\fR
+Same as \fB\-\-clusters\fR
+.TP
 \fBSALLOC_CONN_TYPE\fR
 Same as \fB\-\-conn\-type\fR
 .TP
diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index 6b497a0242f84ab13ff31ce86d00ddcd2a91df20..8a657adf4ba5b59083d7b8d9447cc7822c7e2a1e 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -911,6 +911,17 @@ License names can be followed by a colon and count
 Multiple license names should be comma separated (e.g.
 "\-\-licenses=foo:4,bar"). This option applies to job allocations.
 
+.TP
+\fB\-M\fR, \fB\-\-clusters\fR=<\fIstring\fR>
+Clusters to issue commands to.  Multiple cluster names may be comma separated.
+The job will be submitted to the one cluster providing the earliest expected
+job initiation time. The default value is the current cluster. A value of
+\(aq\fIall\fR' will query to run on all clusters.  Note the
+\fB\-\-export\fR option to control environment variables exported
+between clusters.
+This option applies only to job allocations.
+Note that the SlurmDBD must be up for this option to work properly.
+
 .TP
 .na
 \fB\-m\fR, \fB\-\-distribution\fR=
diff --git a/src/salloc/opt.c b/src/salloc/opt.c
index 9151518f15d546b31044707cd90d3ef9b517b72c..089f5727b7268afecc7f115408e2d3200e362a54 100644
--- a/src/salloc/opt.c
+++ b/src/salloc/opt.c
@@ -286,6 +286,7 @@ static void _opt_default()
 	opt.uid = uid;
 	opt.gid = getgid();
 
+	opt.clusters = NULL;
 	opt.cwd = NULL;
 	opt.progname = NULL;
 
@@ -408,6 +409,8 @@ env_vars_t env_vars[] = {
   {"SALLOC_ACCTG_FREQ",    OPT_STRING,     &opt.acctg_freq,    NULL          },
   {"SALLOC_BELL",          OPT_BELL,       NULL,               NULL          },
   {"SALLOC_BURST_BUFFER",  OPT_STRING,     &opt.burst_buffer,  NULL          },
+  {"SALLOC_CLUSTERS",      OPT_STRING,     &opt.clusters,      NULL          },
+  {"SLURM_CLUSTERS",       OPT_STRING,     &opt.clusters,      NULL          },
   {"SALLOC_CONN_TYPE",     OPT_CONN_TYPE,  NULL,               NULL          },
   {"SALLOC_CORE_SPEC",     OPT_INT,        &opt.core_spec,     NULL          },
   {"SALLOC_CPU_FREQ_REQ",  OPT_CPU_FREQ,   NULL,               NULL          },
@@ -682,6 +685,8 @@ void set_options(const int argc, char **argv)
 		{"kill-command",  optional_argument, 0, 'K'},
 		{"licenses",      required_argument, 0, 'L'},
 		{"distribution",  required_argument, 0, 'm'},
+		{"cluster",       required_argument, 0, 'M'},
+		{"clusters",      required_argument, 0, 'M'},
 		{"tasks",         required_argument, 0, 'n'},
 		{"ntasks",        required_argument, 0, 'n'},
 		{"nodes",         required_argument, 0, 'N'},
@@ -763,7 +768,7 @@ void set_options(const int argc, char **argv)
 		{NULL,            0,                 0, 0}
 	};
 	char *opt_string =
-		"+A:B:c:C:d:D:F:g:hHI::J:kK::L:m:n:N:Op:P:QRsS:t:uU:vVw:W:x:";
+		"+A:B:c:C:d:D:F:g:hHI::J:kK::L:m:M:n:N:Op:P:QRsS:t:uU:vVw:W:x:";
 	char *pos_delimit;
 
 	struct option *optz = spank_option_table_create(long_options);
@@ -882,6 +887,10 @@ void set_options(const int argc, char **argv)
 				exit(error_exit);
 			}
 			break;
+		case 'M':
+			xfree(opt.clusters);
+			opt.clusters = xstrdup(optarg);
+			break;
 		case 'n':
 			opt.ntasks_set = true;
 			opt.ntasks =
@@ -2076,6 +2085,7 @@ static void _usage(void)
 "              [--immediate[=secs]] [--no-kill] [--overcommit] [-D path]\n"
 "              [--oversubscribe] [-J jobname] [--jobid=id]\n"
 "              [--verbose] [--gid=group] [--uid=user] [--licenses=names]\n"
+"              [--clusters=cluster_names]\n"
 "              [--contiguous] [--mincpus=n] [--mem=MB] [--tmp=MB] [-C list]\n"
 "              [--account=name] [--dependency=type:jobid] [--comment=name]\n"
 #ifdef HAVE_BG		/* Blue gene specific options */
@@ -2128,6 +2138,10 @@ static void _help(void)
 "  -k, --no-kill               do not kill job on node failure\n"
 "  -K, --kill-command[=signal] signal to send terminating job\n"
 "  -L, --licenses=names        required license, comma separated\n"
+"  -M, --clusters=names        Comma separated list of clusters to issue\n"
+"                              commands to.  Default is current cluster.\n"
+"                              Name of 'all' will submit to run on all clusters.\n"
+"                              NOTE: SlurmDBD must up.\n"
 "  -m, --distribution=type     distribution method for processes to nodes\n"
 "                              (type = block|cyclic|arbitrary)\n"
 "      --mail-type=type        notify on state change: BEGIN, END, FAIL or ALL\n"
diff --git a/src/salloc/opt.h b/src/salloc/opt.h
index 8b96d15441f123c42b53ce583f079dc26376645a..21bc42504ffbc6201bf519b31e1e60cf518aabd4 100644
--- a/src/salloc/opt.h
+++ b/src/salloc/opt.h
@@ -60,7 +60,7 @@
 typedef enum {BELL_NEVER, BELL_AFTER_DELAY, BELL_ALWAYS} bell_flag_t;
 
 typedef struct salloc_options {
-
+	char *clusters;		/* cluster to run this on. */
 	char *progname;		/* argv[0] of this program or
 				 * configuration file if multi_prog */
 	char* user;		/* local username		*/
diff --git a/src/salloc/salloc.c b/src/salloc/salloc.c
index 817f90ab0b76ea94c5363ad5e4274911aef6891b..a772993dc4d4644b7bf19cbd380a8d9a5e97f52d 100644
--- a/src/salloc/salloc.c
+++ b/src/salloc/salloc.c
@@ -59,6 +59,7 @@
 #include "src/common/cpu_frequency.h"
 #include "src/common/env.h"
 #include "src/common/plugstack.h"
+#include "src/common/proc_args.h"
 #include "src/common/read_config.h"
 #include "src/common/slurm_rlimits_info.h"
 #include "src/common/slurm_time.h"
@@ -305,6 +306,16 @@ int main(int argc, char *argv[])
 		}
 	}
 
+	/* If can run on multiple clusters find the earliest run time
+	 * and run it there */
+	desc.clusters = xstrdup(opt.clusters);
+	if (opt.clusters &&
+	    slurmdb_get_first_avail_cluster(&desc, opt.clusters,
+			&working_cluster_rec) != SLURM_SUCCESS) {
+		print_db_notok(opt.clusters, 0);
+		exit(error_exit);
+	}
+
 	callbacks.ping = _ping_handler;
 	callbacks.timeout = _timeout_handler;
 	callbacks.job_complete = _job_complete_handler;
@@ -560,6 +571,8 @@ relinquish:
 			}
 		}
 	}
+
+	xfree(desc.clusters);
 	return rc;
 }
 
diff --git a/src/srun/libsrun/allocate.c b/src/srun/libsrun/allocate.c
index d409eb98658c42f838395f6c18d7cd57a5151bc4..45db52f08cc858ecad47a9cbfdf0b8d9a97928e8 100644
--- a/src/srun/libsrun/allocate.c
+++ b/src/srun/libsrun/allocate.c
@@ -50,6 +50,7 @@
 #include "src/common/forward.h"
 #include "src/common/log.h"
 #include "src/common/macros.h"
+#include "src/common/proc_args.h"
 #include "src/common/slurm_auth.h"
 #include "src/common/slurm_protocol_api.h"
 #include "src/common/slurm_time.h"
@@ -869,6 +870,16 @@ job_desc_msg_create_from_opts (void)
 	if (opt.mcs_label)
 		j->mcs_label = opt.mcs_label;
 
+	/* If can run on multiple clusters find the earliest run time
+	 * and run it there */
+	j->clusters = xstrdup(opt.clusters);
+	if (opt.clusters &&
+	    slurmdb_get_first_avail_cluster(j, opt.clusters,
+				&working_cluster_rec) != SLURM_SUCCESS) {
+		print_db_notok(opt.clusters, 0);
+		exit(error_exit);
+	}
+
 	return j;
 }
 
diff --git a/src/srun/libsrun/opt.c b/src/srun/libsrun/opt.c
index f60f7831ceda7eae2003aee56c3fff3be3ab964c..7c5a801f9f69d69f5a34aee073cf04d00290d797 100644
--- a/src/srun/libsrun/opt.c
+++ b/src/srun/libsrun/opt.c
@@ -394,6 +394,7 @@ static void _opt_default(void)
 	opt.cwd = xstrdup(buf);
 	opt.cwd_set = false;
 
+	opt.clusters = NULL;
 	opt.progname = NULL;
 
 	opt.ntasks = 1;
@@ -579,6 +580,7 @@ env_vars_t env_vars[] = {
 {"SLURM_BCAST",         OPT_BCAST,      NULL,               NULL             },
 {"SLURM_BLRTS_IMAGE",   OPT_STRING,     &opt.blrtsimage,    NULL             },
 {"SLURM_BURST_BUFFER",  OPT_STRING,     &opt.burst_buffer,  NULL             },
+{"SLURM_CLUSTERS",      OPT_STRING,     &opt.clusters,      NULL             },
 {"SLURM_CHECKPOINT",    OPT_STRING,     &opt.ckpt_interval_str, NULL         },
 {"SLURM_CHECKPOINT_DIR",OPT_STRING,     &opt.ckpt_dir,      NULL             },
 {"SLURM_CNLOAD_IMAGE",  OPT_STRING,     &opt.linuximage,    NULL             },
@@ -935,6 +937,8 @@ static void _set_options(const int argc, char **argv)
 		{"kill-on-bad-exit", optional_argument, 0, 'K'},
 		{"label",         no_argument,       0, 'l'},
 		{"licenses",      required_argument, 0, 'L'},
+		{"cluster",       required_argument, 0, 'M'},
+		{"clusters",      required_argument, 0, 'M'},
 		{"distribution",  required_argument, 0, 'm'},
 		{"ntasks",        required_argument, 0, 'n'},
 		{"nodes",         required_argument, 0, 'N'},
@@ -1045,7 +1049,7 @@ static void _set_options(const int argc, char **argv)
 		{"wckey",            required_argument, 0, LONG_OPT_WCKEY},
 		{NULL,               0,                 0, 0}
 	};
-	char *opt_string = "+A:B:c:C:d:D:e:Eg:hHi:I::jJ:kK::lL:m:n:N:"
+	char *opt_string = "+A:B:c:C:d:D:e:Eg:hHi:I::jJ:kK::lL:m:M:n:N:"
 		"o:Op:P:qQr:RsS:t:T:uU:vVw:W:x:XZ";
 	char *pos_delimit;
 	bool ntasks_set_opt = false;
@@ -1185,6 +1189,10 @@ static void _set_options(const int argc, char **argv)
 			xfree(opt.licenses);
 			opt.licenses = xstrdup(optarg);
 			break;
+		case 'M':
+			xfree(opt.clusters);
+			opt.clusters = xstrdup(optarg);
+			break;
 		case (int)'m':
 			opt.distribution = verify_dist_type(optarg,
 							     &opt.plane_size);
@@ -2742,7 +2750,7 @@ static void _usage(void)
 "            [--oversubscribe] [--label] [--unbuffered] [-m dist] [-J jobname]\n"
 "            [--jobid=id] [--verbose] [--slurmd_debug=#] [--gres=list]\n"
 "            [-T threads] [-W sec] [--checkpoint=time] [--gres-flags=opts]\n"
-"            [--checkpoint-dir=dir]  [--licenses=names]\n"
+"            [--checkpoint-dir=dir] [--licenses=names] [--clusters=cluster_names]\n"
 "            [--restart-dir=dir] [--qos=qos] [--time-min=minutes]\n"
 "            [--contiguous] [--mincpus=n] [--mem=MB] [--tmp=MB] [-C list]\n"
 "            [--mpi=type] [--account=name] [--dependency=type:jobid]\n"
@@ -2819,10 +2827,14 @@ static void _help(void)
 "  -K, --kill-on-bad-exit      kill the job if any task terminates with a\n"
 "                              non-zero exit code\n"
 "  -l, --label                 prepend task number to lines of stdout/err\n"
-"  -L, --licenses=names        required license, comma separated\n"
 "      --launch-cmd            print external launcher command line if not SLURM\n"
 "      --launcher-opts=        options for the external launcher command if not\n"
 "                              SLURM\n"
+"  -L, --licenses=names        required license, comma separated\n"
+"  -M, --clusters=names        Comma separated list of clusters to issue\n"
+"                              commands to.  Default is current cluster.\n"
+"                              Name of 'all' will submit to run on all clusters.\n"
+"                              NOTE: SlurmDBD must up.\n"
 "  -m, --distribution=type     distribution method for processes to nodes\n"
 "                              (type = block|cyclic|arbitrary)\n"
 "      --mail-type=type        notify on state change: BEGIN, END, FAIL or ALL\n"
diff --git a/src/srun/libsrun/opt.h b/src/srun/libsrun/opt.h
index 1380867a8726dbd69c877bf1ce5b4b287eab8398..1c8e9aa0fe6df4e0794992fc5e20dc94ca301d1a 100644
--- a/src/srun/libsrun/opt.h
+++ b/src/srun/libsrun/opt.h
@@ -66,7 +66,7 @@ extern int _verbose;
 extern enum modes mode;
 
 typedef struct srun_options {
-
+	char *clusters;		/* cluster to run this on. */
 	char *progname;		/* argv[0] of this program or
 				 * configuration file if multi_prog */
 	bool multi_prog;	/* multiple programs to execute */