Arya_Svitkona's avatar

Hosting with Vapor & Octane on AWS | Too many connections

Dear Community,

We have created a REST API based on Laravel 11, which currently has three endpoints (GET, POST, PATCH, DELETE). After initial vapor and octane setup we deployed our project to AWS and tried to send 1000 GET request. Although we have set octane-database-session-persist: true we face the issue that we reach an "Too many connections" error from the database.

Currently using db.t3.micro | mysql8.0 (2 vCPU @ 2.5Ghz, 1 GB RAM). Is that a limitation due to low RAM? Do we have to configure something else for Octane?

POST Request are working great, since we all write that to the Queue (~3800 Request / Second). When the Queue Lambda is working and tries to insert the data into the database, we face the same issue.

Is there anyone who can give us a helping hand with that problem? All the best

0 likes
2 replies
LaryAI's avatar
Level 58

To address the "Too many connections" error when using Laravel Vapor and Octane on AWS, there are several steps you can take to mitigate the issue. This error typically occurs when the number of database connections exceeds the maximum allowed by your database instance. Here are some potential solutions:

1. Increase the Maximum Connections Limit

You can increase the maximum number of connections allowed by your MySQL database. This can be done by modifying the MySQL configuration file (my.cnf or my.ini) and setting the max_connections parameter to a higher value. However, this might not be feasible if you're using a managed database service like AWS RDS, where you have limited control over the configuration.

2. Optimize Database Connections in Laravel

Ensure that your Laravel application is efficiently managing database connections. Here are some tips:

  • Connection Pooling: Use a connection pooler like pgbouncer for PostgreSQL or ProxySQL for MySQL to manage and reuse database connections.
  • Persistent Connections: Enable persistent connections in your database configuration. In Laravel, you can set the persistent option to true in your config/database.php file.
'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
    'options' => [
        PDO::ATTR_PERSISTENT => true,
    ],
],

3. Use Octane's Database Connection Management

Laravel Octane can manage database connections more efficiently. Ensure that you have configured Octane to handle database connections properly. You mentioned setting octane-database-session-persist: true, which is good. Additionally, you can configure Octane to close database connections after each request to avoid connection leaks.

4. Scale Your Database Instance

The db.t3.micro instance type is quite limited in terms of resources. Consider upgrading to a larger instance type with more CPU and RAM, which can handle more connections. For example, you could upgrade to a db.t3.medium or db.t3.large instance.

5. Use Queues for Write Operations

Since you mentioned that POST requests are working well because they are written to a queue, ensure that your queue workers are not overwhelming the database with too many concurrent connections. You can control the number of concurrent workers to avoid hitting the connection limit.

6. Monitor and Optimize Queries

Use database monitoring tools to identify slow or inefficient queries. Optimize these queries to reduce the load on your database. You can use tools like AWS CloudWatch, New Relic, or Laravel Telescope for monitoring.

Example Configuration for Octane

Here is an example configuration for Octane to ensure proper database connection management:

// config/octane.php

return [
    'server' => env('OCTANE_SERVER', 'swoole'),

    'workers' => env('OCTANE_WORKERS', 10),

    'max_requests' => env('OCTANE_MAX_REQUESTS', 1000),

    'task_workers' => [
        'default' => env('OCTANE_TASK_WORKERS', 10),
    ],

    'cache' => [
        'store' => env('OCTANE_CACHE_STORE', 'octane'),
    ],

    'tables' => [
        'example:1000' => [
            'id' => 'int',
            'data' => 'string',
        ],
    ],

    'database' => [
        'session_persist' => true,
        'connections' => [
            'mysql' => [
                'max_connections' => 100,
            ],
        ],
    ],
];

By following these steps, you should be able to mitigate the "Too many connections" error and improve the performance and stability of your Laravel application running on AWS with Vapor and Octane.

Arya_Svitkona's avatar

You can check the actual max_connection value of the database with following command: SHOW VARIABLES LIKE 'max_connections';

With the db.t3.micro | mysql8.0 (2 vCPU @ 2.5Ghz, 1 GB RAM) database server we can use ~60 db connections which can be the bottleneck. Since we upgraded to db.t3.small | mysql8.0 (2 vCPU @ 2.5Ghz, 2 GB RAM) we can handle ~db 140 connections.

In the same time we used Laravel Telescope to check if we can optimize our queries and we found an typical N+1 problem.

Can recommend: https://laracasts.com/series/eloquent-performance-patterns/episodes/3

Update: Enable RDS Proxy eliminated the "to many connection "issue, since it handles the database connection pooling. But we can still "just" handle ~280 Post request per second which is an easy request with a single insert into a table using the DB Facade.

Please or to participate in this conversation.