Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Politeboat36's avatar

How to modify Session middleware for waking up a serverless database without blocking UI

Hello,

I have a Laravel + Inertia application that uses a serverless database which shuts down if a database query is not received within one hour. Once shut down, it takes around 30 seconds to wake up. I admit this is awful, but I proposed multiple options to the client and they chose this with full knowledge.

By default, Laravel stores sessions in the database, so when someone visits the home page while the database is shut down it shows a blank screen with no UI until the database wakes up and handles the user session store query. For my requirements, session data must be encrypted, so we use the database driver for sessions.

I believe I have a solution, but I wanted to see if others here have faced a similar problem and think this solution (below) is sufficient or if additional measures are needed.

I believe what would work is to create a custom StartSession middleware like so which asynchronously queries the database if the user is not logged in, which will start up the database if it is shut down. Because we use SSO for logins, the log in process is not immediate, so this may trigger the start up soon enough for a user to not notice it much.

<?php

namespace App\Http\Middleware;

use Illuminate\Session\Middleware\StartSession as Middleware;

class StartSession extends Middleware
{
    public function handle($request, \Closure $next)
    {
        if (!auth()->check()) {
            defer(function () {
                DB::select('SELECT 1');
            });
            $request->setLaravelSession(app('session')->driver('array'));
            return $next($request);
        }
        return parent::handle($request, $next);
    }
}

And register it in bootstrap/app.php:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Inertia\Inertia;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->web(append: [
            \App\Http\Middleware\HandleInertiaRequests::class,
            \Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
        ], replace: [
            \Illuminate\Session\Middleware\StartSession::class => \App\Http\Middleware\StartSession::class,
        ]);
    })->create();

It's possible that I need to use encrypted file sessions for the session driver, which will allow the UI to not be blocked just for session queries to a shut-down database, as long as the files are deleted by Laravel automatically and don't just accumulate.

0 likes
8 replies
jlrdw's avatar

Are you sure cache isn't what you are after? For session data to be displayed just load the page that uses that session data. I don't understand why it would take 30 seconds.

But sessions are temporary don't forget. They are generally used during the interaction with the application.

If other data needs storing for retrieval use another table specific for that. You should never have to "query" sessions as they are available anyway.

Like a cart, store the cart in a cart table. and when the cart data is needed put in session if user continues to shop.

But so many ways to deal with this stuff. But session should have garbage collection. A session table isn't meant to permanently store data, it's meant for temporary data.

JussiMannisto's avatar

Are you sure cache isn't what you are after? For session data to be displayed just load the page that uses that session data. I don't understand why it would take 30 seconds.

If other data needs storing for retrieval use another table specific for that. You should never have to "query" sessions as they are available anyway.

Read the first paragraph where they describe their setup. Are you familiar with the concept of serverless?

They're using a serverless database that apparently scales to zero and has to restart on demand. I'd never try to run an app like that if the database is needed for regular browsing. They could use a different session driver, but that doesn't help much if the database is used for anything else. A 30-second wait time is an automatic disqualifier, no matter how infrequent.

Politeboat36's avatar

Thank you for offering a suggestion. The database takes 30 seconds to start from a shut-down state. To save on database costs, the database shuts down after it has not received a query for 1 hour. I've modified my post to include this information.

I must encrypt session data and I don't know if there is a different driver I can use for sessions while keeping the session data encrypted (and not paying for an additional service like Redis). I would prefer not to use cookies to avoid the additional work of providing cookie notices.

The solution I'm asking for input on here is the only modification I would have to how Laravel handles sessions by default.

Politeboat36's avatar

I'm never going to recommend a serverless database again - no matter how many times I told them there would be a long wait to log in, they still forget I told them this and blame me. I'm trying to make it more tolerable by not blocking the UI for the login page.

JussiMannisto's avatar

The database takes 30 seconds to start from a shut-down state. To save on database costs, the database shuts down after it has not received a query for 1 hour.

It doesn't sound like there's a lot of traffic if the DB can be idle for an hour. How much money could you save doing this? I'd at least set minimum capacity to 1.

You could also get a VPS for $5 a month and run your DB there if you're comfortable with Linux and know how to configure TLS and firewalls. My impression is that you don't need horizontal scaling right now.

JussiMannisto's avatar

I must encrypt session data and I don't know if there is a different driver I can use for sessions while keeping the session data encrypted (and not paying for an additional service like Redis). I would prefer not to use cookies to avoid the additional work of providing cookie notices.

Encryption isn't an issue. You can encrypt session data or not, it works the same for any session storage. Except for cookie sessions, since Laravel always encrypts cookies.

I don't recommend cookie sessions (meaning session data kept in cookie contents), but you don't need notices for cookies that are necessary for the site to function. Plus your site is already using cookies. That's how Laravel identifies the user, as do most web apps.

If you have a filesystem available, file-based sessions should work well.

Politeboat36's avatar

I appreciate the recommendation for file based sessions and I think that may be the best solution.

This is a small internal tool and it saves us around $125 / month (estimate) doing this. I was using SQLite but they wanted to access the database using Power BI so now we're using SQL Server. We went from a fast and free database to the least expensive database which is often shut down when someone wants to start using it.

I proposed having a cron job keep the database awake during normal business hours, but I'm still waiting (3 weeks at this point) to hear back. The client has to approve anything I propose. I also have to bill my time so I'm looking for a 1 hour fix - setting up another service takes enough time to offset a few months of savings.

I've been playing around with the StartSession middleware and it seems that if I use file-based encrypted sessions then that may be fine. It would be more secure (if an unauthorized person had access to the server) to use the database session driver, but I would have to figure out how to keep the Session driver as "database" for a POST to /login AND the resulting GET /login (via 302 redirect from the POST request) redirects but set the driver to "array" for the first GET /login to prevent the database from being used (thus blocking the UI).

jlrdw's avatar

There is no such this as a serverless database. The term is just a marketing misnomer. Managed for you is what it really means.

Cloud is also a marketing term nothing more. They are servers.

Companies love putting fancy labels on things for sales.

And I am not referring to desktop DB's.

Please or to participate in this conversation.