# Laravel + FastCGI Cache = ❤️ > ⚠️ Need a more specific guide? See https://medium.com/@murdercode/speed-up-your-laravel-application-up-to-1000x-with-fastcgi-cache-0135b11407e5 Using FastCGI cache allows you to speed up your website up to 1000x. In fact, the FastCGI cache (or Varnish) mechanism consists of putting a server-caching mechanism between a client and your web server. The whole page will be cached as an HTML output, and it will be delivered instead of using the PHP/MySQL/Redis stack, etc. for all users, but only for the first visit (and others after some specified time). **WARNING**: This is not a *take-away how-to*. Please read it carefully and use it at your own risk. This config is based on the ploi.io stack. We will not cover the FastCGI installation process, so please prepare FastCGI and adapt the next config if you need it. # What you need to know To achieve significant improvements in speed and security, it's important to note that pages will be cached and shared among users. Therefore, **it's crucial that sessions and cookies aren't cached**, as doing so may result in shared sessions and security complications. This caching method is cookieless and sessionless, and is ideal for websites without a login mechanism. However, it also -*supports Laravel Nova authentication*. ## 1. Disable Session & Cookies in Laravel The first thing to do is to remove the middlewares that create and store sessions and cookies. You can move those middlewares to another group for reuse by modifying the following method in `/app/Http/Kernel.php`: ```php protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'cookie' => [ \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, ], 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; ``` Please note that VerifyCSRF can pose a security issue if you don't know how to approach it. ## 2. Define where to use sesssions and cookies As we mentioned earlier, we want to use sessions and cookies in Laravel Nova (although you can choose to use them elsewhere). So, edit `/app/Providers/AppServiceProvider.php` as follows: ```php public function boot() { if(request()->hasCookie('YOURAPPNAME_session') || request()->is('cms/*') || request()->is('nova-api/*') || request()->is ('nova-vendor/*')) { $this->app['router']->pushMiddlewareToGroup('web', \App\Http\Middleware\EncryptCookies::class); $this->app['router']->pushMiddlewareToGroup('web', \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class); $this->app['router']->pushMiddlewareToGroup('web', \Illuminate\Session\Middleware\StartSession::class); $this->app['router']->pushMiddlewareToGroup('web', \Illuminate\View\Middleware\ShareErrorsFromSession::class); $this->app['router']->pushMiddlewareToGroup('web', \App\Http\Middleware\VerifyCsrfToken::class); } ``` **Note**: in our case we will use `cms` as Nova path instead `nova`. Change it with yours. Note that `nova-api` can be used from Laravel Nova Tools, so add it as shown. ## 3. Configure FastCGI We need to define some conditions, where FastCGI will be not enabled. In `fastcgi-cache.conf`: ``` # Create a variable to skip the cache set $skip_cache 0; # POST requests and urls with a query string should always go to PHP if ($request_method = POST) { set $skip_cache 1; } # Don't cache when there is a query string (e.g. ?search=query) #if ($query_string != "") { # set $skip_cache 1; #} # Don't cache if querystring if ($query_string ~* "nocache") { set $skip_cache 1; } if ($query_string ~* "query") { set $skip_cache 1; } # Set here your NAME_session, you can take it from HTTP response if ($http_cookie ~* "YOUR-SESSION-NAME_session") { set $skip_cache 1; } # Don't cache uris containing the following segments if ($request_uri ~* "/cms/|/telescope/|/horizon/|/nova-api/|/nova-vendor/|/feed|/.*sitemap.*\.(xml|xsl)") { set $skip_cache 1; } ``` Now it's time to ignore some headers for preventing misconfiguration. In `fastcgi-php-cache`, after `add_header` add: ``` fastcgi_cache NAMECACHE; fastcgi_cache_valid any 5s; # Allow only 1 request to cache content fastcgi_cache_lock on; # Use old cache when it's updating fastcgi_cache_use_stale updating; fastcgi_cache_background_update on; add_header X-FastCGI-Cache $upstream_cache_status; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; #Custom Laravel fastcgi_cache_key "$request_method $scheme://$host$request_uri"; fastcgi_cache_use_stale error timeout invalid_header http_500; #fastcgi_pass_header Set-Cookie; fastcgi_pass_header Cookie; fastcgi_ignore_headers Set-Cookie Cache-Control Expires Vary; fastcgi_hide_header Expires; fastcgi_hide_header Pragma; fastcgi_hide_header Vary; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; ``` Note that this config will use a microcaching mechanism. Please update with your values if you need it.