Running production in half and half : CakePHP & Laravel

By Shubham Chawala, Architect

25th July, 2025

Upgrading the system, including framework versions and database versions  is a critical technical change necessary for ensuring system stability and security. As software evolves, older versions often include deprecated features that are no longer supported. Additionally, each new version introduces enhancements and additional capabilities that can significantly improve performance and scalability.

Upgradation also addresses vulnerabilities identified in older versions, reducing the risk of exploits and ensuring compliance with modern security standards. Furthermore, newer versions often bring optimization improvements, making the system more efficient, reliable, and prepared to handle increased workloads or complex operations.

Staying up to date is essential for maintaining compatibility with modern tools, libraries, and integrations, ensuring the system remains robust and future-ready.

Upgrading and Migrating Frameworks: CakePHP to Laravel

For our system, we are using CakePHP, a PHP framework that has served us well over the years. However, as technology evolves, upgrading becomes inevitable. Initially, we planned to upgrade from CakePHP 2 to a newer version. However, after thorough research and team discussions, we decided to explore migrating to Laravel, which is the most popular php framework.

Why Consider Laravel Over CakePHP?

While this is out of scope for this article. But to just give gist around it. Laravel stands out because of its robust capabilities, a large and thriving community, and an extensive market skill set. One of the most compelling reasons for considering Laravel is its frequent releases and consistent community support. Unlike CakePHP, which has slower release cycles and a relatively limited community, Laravel’s ecosystem provides the latest features, better documentation, and long-term support that align with modern software development needs. 

The Challenge: Migrating from CakePHP to Laravel

While both CakePHP and Laravel are PHP frameworks, they differ significantly in terms of architecture, configurations, session management, folder structures, and much more. Migrating from CakePHP to Laravel isn’t just about rewriting code; it involves rethinking the way the entire system functions.

One of the biggest challenges is the scale of our product, Bizom, a feature-rich platform serving over 600+ clients. With new customers going live every month, fulfilling customer requirements, and enhancing the product, we have a large and continuous development pipeline. A complete migration before launching would not only be a monumental task but would also disrupt ongoing development and operations.

However, in engineering, the word “impossible” simply does not exist. So, how do we achieve this migration? The solution lies in a phased approach—module-based migration.

The Approach: Running CakePHP and Laravel in Parallel

To execute a module-based migration, we needed to run CakePHP and Laravel frameworks in parallel. This posed two major technical challenges:

  1. Request Handling: How to determine which requests should be processed by CakePHP and which by Laravel.
  2. Session Management:CakePHP and Laravel use different mechanisms for session management, so a unified approach was essential.

Understanding the Infrastructure and Request Flow

To address these challenges, we first analyzed how system processes requests:

  1. A request enters the load balancer, which distributes traffic across multiple instances using a configured approach.
  2. The load balancer forwards the request to underlying instances.
  3. The server forwards requests through a unified request handler layer, which manages routing internally. 
  4. Within our front-controller, the request object is initialized, processed, and a response is returned to the client.

The Two Possible Solutions for Running Frameworks in Parallel

We considered two solutions to run CakePHP and Laravel simultaneously:

  1. Using CURL Calls:
    In this approach, whenever a request hits the CakePHP code, it would trigger a CURL call to the Laravel codebase. While this ensures functionality, it introduces an additional network call, significantly increasing latency and impacting performance.
  2. Routing Logic in front-controller:The second approach involves implementing logic directly in the front controller logic to decide, at runtime, whether a request should be processed by CakePHP or Laravel. This approach eliminates the need for network calls, making it far more efficient and reducing latency.

We opted for the second solution—routing requests at the front controller level. This allows us to run both frameworks in parallel without impacting performance.

The Magical Code: Running Two Frameworks in Parallel

Here’s pseudo code for how we implemented the logic in front-controller to serve requests efficiently:

// Load configuration for Laravel integration

configData = parseJson(readFile(“laravelConfigurations.json”))

laravelAdapter = new LaravelAdapter(configData)

global.adapter = laravelAdapter

requestUri = getRequestUri()

if (global.adapter.isLaravelModule(requestUri)) {

    // Delegate to Laravel module entry-point

    entryPoint = buildPath(“../path_to_laravel”)

    include(entryPoint)

} else {

    // Proceed with custom or legacy app handling

    handleCustomApp()

}

This is how we make a decision about which framework will serve the request based on the api path.  To facilitate this, we created a JSON file called laravelConfiguration.json. This file specifies which apis have been migrated to Laravel. Below is the JSON structure:

{

 “enable”: true,

 “routes”: {

   “SampleController”: {

     “SampleAction”: false

   },

   “api_path/”: true,

 },

 “session”: {

   “csrfTokenName”: “_token” 

 }

}

If you look at the JSON, api_path it is under a feature flag. In the configuration, certain modules can be selectively enabled or disabled. If a module is marked as enabled, it will be handled by one system; otherwise, it defaults to being handled by another. This allows for flexible routing between systems based on module-level settings.

In summary, the router checks whether the module is enabled in the configuration. If it is, the request is redirected to laravel framework. Otherwise, it continues to be served by CakePHP.