diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index 57161cbfbbc4e8e35c544351cc60323552c51570..7189bc26a34b93e2df8434e99bfa1ddec3c444d6 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -921,10 +921,15 @@ void ProjectData::parseProcesses(BaseLib::ConfigTree const& processes_config,
             OGS_FATAL("Unknown process type: %s", type.c_str());
         }
 
-        BaseLib::insertIfKeyUniqueElseError(_processes,
-                                            name,
-                                            std::move(process),
-                                            "The process name is not unique");
+        if (BaseLib::containsIf(
+                _processes,
+                [&name](std::unique_ptr<ProcessLib::Process> const& p) {
+                    return p->name == name;
+                }))
+        {
+            OGS_FATAL("The process name '%s' is not unique.", name.c_str());
+        }
+        _processes.push_back(std::move(process));
     }
 }
 
@@ -1020,10 +1025,9 @@ void ProjectData::parseChemicalSystem(
         "Ready for initializing interface to a chemical solver for water "
         "chemistry calculation.");
 
-    auto const& process = _processes.begin()->second;
     if (auto const* component_transport_process = dynamic_cast<
             ProcessLib::ComponentTransport::ComponentTransportProcess const*>(
-            process.get()))
+            _processes[0].get()))
     {
         auto const chemical_solver =
             //! \ogs_file_attr{prj__chemical_system__chemical_solver}
diff --git a/Applications/ApplicationsLib/ProjectData.h b/Applications/ApplicationsLib/ProjectData.h
index a488bc280e9965d5d7710aebe2d28c037f2a872a..4c1706781bfed7754fbc078c54ebf5fa4502ccaa 100644
--- a/Applications/ApplicationsLib/ProjectData.h
+++ b/Applications/ApplicationsLib/ProjectData.h
@@ -72,8 +72,8 @@ public:
     //
 
     /// Provides read access to the process container.
-    std::map<std::string, std::unique_ptr<ProcessLib::Process>> const&
-    getProcesses() const
+    std::vector<std::unique_ptr<ProcessLib::Process>> const& getProcesses()
+        const
     {
         return _processes;
     }
@@ -118,7 +118,7 @@ private:
 
     std::unique_ptr<MaterialPropertyLib::Medium> _medium;
     std::vector<std::unique_ptr<MeshLib::Mesh>> _mesh_vec;
-    std::map<std::string, std::unique_ptr<ProcessLib::Process>> _processes;
+    std::vector<std::unique_ptr<ProcessLib::Process>> _processes;
     std::vector<ProcessLib::ProcessVariable> _process_variables;
 
     /// Buffer for each parameter config passed to the process.
diff --git a/Applications/CLI/ogs.cpp b/Applications/CLI/ogs.cpp
index 4b433084fb8b2aa312295f732e8f05bd9b4a6299..6ed80a84731980033024c7aa6427f9bc46b94e78 100644
--- a/Applications/CLI/ogs.cpp
+++ b/Applications/CLI/ogs.cpp
@@ -220,7 +220,7 @@ int main(int argc, char* argv[])
             INFO("Initialize processes.");
             for (auto& p : project.getProcesses())
             {
-                p.second->initialize();
+                p->initialize();
             }
 
             // Check intermediately that config parsing went fine.
diff --git a/ProcessLib/CreateProcessData.cpp b/ProcessLib/CreateProcessData.cpp
index c5a2d33315ff2552a28b9b8d11e014e31abf5d73..5067876bbd9e0f8ac6f4d5217ad50177aff405ba 100644
--- a/ProcessLib/CreateProcessData.cpp
+++ b/ProcessLib/CreateProcessData.cpp
@@ -47,7 +47,7 @@ static std::unique_ptr<ProcessData> makeProcessData(
 
 std::vector<std::unique_ptr<ProcessData>> createPerProcessData(
     BaseLib::ConfigTree const& config,
-    const std::map<std::string, std::unique_ptr<Process>>& processes,
+    std::vector<std::unique_ptr<Process>> const& processes,
     std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>> const&
         nonlinear_solvers)
 {
@@ -58,8 +58,11 @@ std::vector<std::unique_ptr<ProcessData>> createPerProcessData(
     {
         //! \ogs_file_attr{prj__time_loop__processes__process__ref}
         auto const pcs_name = pcs_config.getConfigAttribute<std::string>("ref");
-        auto& pcs = *BaseLib::getOrError(
-            processes, pcs_name,
+        auto& pcs = *BaseLib::getIfOrError(
+            processes,
+            [&pcs_name](std::unique_ptr<Process> const& p) {
+                return p->name == pcs_name;
+            },
             "A process with the given name has not been defined.");
 
         auto const nl_slv_name =
diff --git a/ProcessLib/CreateProcessData.h b/ProcessLib/CreateProcessData.h
index 7a127d553b9f91f1440e762a0360a9094c6bb77d..f0e7b48d29a04a3e166004731d1fbf8e33d84a7b 100644
--- a/ProcessLib/CreateProcessData.h
+++ b/ProcessLib/CreateProcessData.h
@@ -15,7 +15,7 @@ namespace ProcessLib
 {
 std::vector<std::unique_ptr<ProcessData>> createPerProcessData(
     BaseLib::ConfigTree const& config,
-    const std::map<std::string, std::unique_ptr<Process>>& processes,
+    std::vector<std::unique_ptr<Process>> const& processes,
     std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>> const&
         nonlinear_solvers);
 
diff --git a/ProcessLib/CreateTimeLoop.cpp b/ProcessLib/CreateTimeLoop.cpp
index 71bbe024db3f7efd8e962efeec52cf03a5821b12..03ef0251b35a6f9a2514aa84f66040718e217eb5 100644
--- a/ProcessLib/CreateTimeLoop.cpp
+++ b/ProcessLib/CreateTimeLoop.cpp
@@ -22,7 +22,7 @@ namespace ProcessLib
 {
 std::unique_ptr<TimeLoop> createTimeLoop(
     BaseLib::ConfigTree const& config, std::string const& output_directory,
-    const std::map<std::string, std::unique_ptr<Process>>& processes,
+    const std::vector<std::unique_ptr<Process>>& processes,
     const std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>>&
         nonlinear_solvers,
     std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes,
diff --git a/ProcessLib/CreateTimeLoop.h b/ProcessLib/CreateTimeLoop.h
index 167e0e68ccbdff2b6f2759890989b7c46b5233cb..556a87ac01d3816b4260af713d8be3f22ae32941 100644
--- a/ProcessLib/CreateTimeLoop.h
+++ b/ProcessLib/CreateTimeLoop.h
@@ -47,7 +47,7 @@ namespace ProcessLib
 //! Builds a TimeLoop from the given configuration.
 std::unique_ptr<TimeLoop> createTimeLoop(
     BaseLib::ConfigTree const& config, std::string const& output_directory,
-    std::map<std::string, std::unique_ptr<Process>> const& processes,
+    std::vector<std::unique_ptr<Process>> const& processes,
     std::map<std::string, std::unique_ptr<NumLib::NonlinearSolverBase>> const&
         nonlinear_solvers,
     std::vector<std::unique_ptr<MeshLib::Mesh>> const& meshes,
diff --git a/ProcessLib/ProcessData.h b/ProcessLib/ProcessData.h
index e1d9321c61611601d6f36c5c11ca302b47727d80..2041b9aba238367b1b3f41deea2d78ee4f8dbc5c 100644
--- a/ProcessLib/ProcessData.h
+++ b/ProcessLib/ProcessData.h
@@ -15,11 +15,7 @@
 #include "NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h"
 
 #include "CoupledSolutionsForStaggeredScheme.h"
-
-namespace ProcessLib
-{
-class Process;
-}
+#include "Process.h"
 
 namespace ProcessLib
 {