diff --git a/IPython/parallel/apps/baseapp.py b/IPython/parallel/apps/baseapp.py
index 78645fa..400cda7 100755
--- a/IPython/parallel/apps/baseapp.py
+++ b/IPython/parallel/apps/baseapp.py
@@ -75,6 +75,7 @@ base_aliases.update({
     'log-to-file' : 'BaseParallelApplication.log_to_file',
     'clean-logs' : 'BaseParallelApplication.clean_logs',
     'log-url' : 'BaseParallelApplication.log_url',
+    'cluster-id' : 'BaseParallelApplication.cluster_id',
 })
 
 base_flags = {
@@ -116,6 +117,18 @@ class BaseParallelApplication(BaseIPythonApplication):
     log_url = Unicode('', config=True,
         help="The ZMQ URL of the iplogger to aggregate logging.")
 
+    cluster_id = Unicode('', config=True,
+        help="""String id to add to runtime files, to prevent name collisions when
+        using multiple clusters with a single profile.
+        
+        When set, files will be named like: 'ipcontroller-<cluster_id>-engine.json'
+        """
+    )
+    def _cluster_id_changed(self, name, old, new):
+        self.name = self.__class__.name
+        if new:
+            self.name += '-%s'%new
+    
     def _config_files_default(self):
         return ['ipcontroller_config.py', 'ipengine_config.py', 'ipcluster_config.py']
     
diff --git a/IPython/parallel/apps/ipcontrollerapp.py b/IPython/parallel/apps/ipcontrollerapp.py
index 3f31680..b084348 100755
--- a/IPython/parallel/apps/ipcontrollerapp.py
+++ b/IPython/parallel/apps/ipcontrollerapp.py
@@ -174,7 +174,18 @@ class IPControllerApp(BaseParallelApplication):
 
     use_threads = Bool(False, config=True,
         help='Use threads instead of processes for the schedulers',
-        )
+    )
+
+    engine_json_file = Unicode('ipcontroller-engine.json', config=True,
+        help="JSON filename where engine connection info will be stored.")
+    client_json_file = Unicode('ipcontroller-client.json', config=True,
+        help="JSON filename where client connection info will be stored.")
+    
+    def _cluster_id_changed(self, name, old, new):
+        super(IPControllerApp, self)._cluster_id_changed(name, old, new)
+        self.engine_json_file = "%s-engine.json"%self.name
+        self.client_json_file = "%s-client.json"%self.name
+
 
     # internal
     children = List()
@@ -215,7 +226,7 @@ class IPControllerApp(BaseParallelApplication):
         """load config from existing json connector files."""
         c = self.config
         # load from engine config
-        with open(os.path.join(self.profile_dir.security_dir, 'ipcontroller-engine.json')) as f:
+        with open(os.path.join(self.profile_dir.security_dir, self.engine_json_file)) as f:
             cfg = json.loads(f.read())
         key = c.Session.key = asbytes(cfg['exec_key'])
         xport,addr = cfg['url'].split('://')
@@ -227,7 +238,7 @@ class IPControllerApp(BaseParallelApplication):
         if not self.engine_ssh_server:
             self.engine_ssh_server = cfg['ssh']
         # load client config
-        with open(os.path.join(self.profile_dir.security_dir, 'ipcontroller-client.json')) as f:
+        with open(os.path.join(self.profile_dir.security_dir, self.client_json_file)) as f:
             cfg = json.loads(f.read())
         assert key == cfg['exec_key'], "exec_key mismatch between engine and client keys"
         xport,addr = cfg['url'].split('://')
@@ -277,11 +288,11 @@ class IPControllerApp(BaseParallelApplication):
                     'url' : "%s://%s:%s"%(f.client_transport, f.client_ip, f.regport),
                     'location' : self.location
                     }
-            self.save_connection_dict('ipcontroller-client.json', cdict)
+            self.save_connection_dict(self.client_json_file, cdict)
             edict = cdict
             edict['url']="%s://%s:%s"%((f.client_transport, f.client_ip, f.regport))
             edict['ssh'] = self.engine_ssh_server
-            self.save_connection_dict('ipcontroller-engine.json', edict)
+            self.save_connection_dict(self.engine_json_file, edict)
 
     #
     def init_schedulers(self):
diff --git a/IPython/parallel/apps/ipengineapp.py b/IPython/parallel/apps/ipengineapp.py
index 43fca7a..055318f 100755
--- a/IPython/parallel/apps/ipengineapp.py
+++ b/IPython/parallel/apps/ipengineapp.py
@@ -135,8 +135,8 @@ aliases.update(base_aliases)
 
 class IPEngineApp(BaseParallelApplication):
 
-    name = Unicode(u'ipengine')
-    description = Unicode(_description)
+    name = 'ipengine'
+    description = _description
     examples = _examples
     config_file_name = Unicode(default_config_file_name)
     classes = List([ProfileDir, Session, EngineFactory, Kernel, MPI])
@@ -158,7 +158,15 @@ class IPEngineApp(BaseParallelApplication):
         controller and engine are started at the same time and it
         may take a moment for the controller to write the connector files.""")
 
-    url_file_name = Unicode(u'ipcontroller-engine.json')
+    url_file_name = Unicode(u'ipcontroller-engine.json', config=True)
+
+    def _cluster_id_changed(self, name, old, new):
+        if new:
+            base = 'ipcontroller-%s'%new
+        else:
+            base = 'ipcontroller'
+        self.url_file_name = "%s-engine.json"%base
+
     log_url = Unicode('', config=True,
         help="""The URL for the iploggerapp instance, for forwarding
         logging to a central location.""")