Deferred just means don't use them on every request.
@ccasselman What specs of the test environment?
@bashy I didn't mean the definition of the word deferred.
I didn't know if that was a pattern I hadn't heard of or how deferred providers are implemented differently than the normal ones.
@ccasselman Laravel loads all defined service providers from the filesystem on every request unless a provider declares itself as deferred. This just means that instead of loading the provider on every request, laravel will only load it when it's required/used. Check out this section of the docs for more info: http://laravel.com/docs/5.0/providers#deferred-providers
@tjames Thank you - that's exactly what I was asking for.
I appreciate you helping.
Thought you had a fresh install with just a string returned?
I didn't realize I made it sound like that. Its my production installation but it is just new controller doing a string return. I guess to clarify it is not running any of my personal code or business code but it is running on my production boxes with my production code base even though none of that code is being used during this process.
Either way, you'll not come close to the speed of Codeigniter or other lighter frameworks.
There's always a compromise between features, third party support and ease of use, to name a few.
If ultimate speed is an issue, you ought to be forgetting a framework, or even PHP.
The speed argument is long dead.
I agree with @sitesense . If speed is your goal then you should look at other languages like Go or Java. Anyway there are some methods to handle high traffic and I mean caching (redis, memcached) or varnish for reverse proxy. I read about a website which handles 4 billion page requests a month with Symfony which I believe it's slower than Laravel so it can be done. Now PHP has Zend OPCache which speeds up significantly the PHP execution. PHP and Laravel especially were not made for performance but for convenience. You can't have both. At least not now. Go goes the closest as it can get to this ideal situation but it has a long way ahead. I am also working on a startup and I also estimate a high traffic and even though Laravel is slow I prefer spending extra money on the hosting and a very comfortable working environment than using something more performant and saving money on hosting but having big headaches with maintenance. Now this is my case and it shouldn't be generalized. That is my humble opinion.
@ccasselman Its not right, that everyone is just "okay" with these > 500ms reponse times. I don't know why you get these times, but even on my very slow laptop a simple controller like the one you described is getting response times under 50ms. I don't know what it is, but there is something fundamentally wrong, its not just some missing optimizations.
Edit: I took the time and pushed a laravel installation to a small webhoster (not even a vhost / dedicated server) http://laratest.betelgeuse.uberspace.de/laravel/public/ The respnse times are between 70ms and 80ms for my tests (german hoster, mind the longer latency if you're based in the US).
@ccasselman Maybe something like http://phalconphp.com if you want speed.
@PatrickBauer 100ms for me with 23ms ping to the host.
Thats still much less then his 400+ms :)
I know, I didn't say it was bad :P
I really want to figure out where the slowness is - with that said - how do you recommend measuring and testing this out?
If you want performance and run a VPS, go with Play Framework. It is written in Scala, a wonderful language that deserve to dive in.
Read through most the answers, you said you weren't a server guy, just wondering what kind of compiler you're using for php? If you're not using HHVM i recommend you do so. The TLDR version is it compiles php into C and Hack
While HHVM might be a good route to take for performance, it would make more sense to first address why the application is so slow currently, before switching out the stack. Laravel out of the box shouldn't be that slow when running in production, as many others have evidenced. Hiding a performance problem behind HHVM is only going to come back to bite you later on.
Adding up to all the tips you received here, here is what I generally do to increase my app's performance
- Use a session driver like redis or memcached
- Use one of these drives for caching also
- Use cached query results for all the queries that are not volatile (not subject to change frequently)
- Fine-tune all Eloquent queries to eager-load any related model whenever it is possible and only when needed, I generally log out every query while developing and double-check each request. Use Model::with(...) or $instance->load(...) to eager-load your relations, but usage of the
protected $with;property on your models should be done with a lot of caution. - Comment out any provider not used, and as said before prefer to use deferred providers (look in the docs)
- Disable Query Logging on production
// on AppServiceProvider, or on a custom provider
public function boot()
{
if ( env( 'APP_ENV', 'local' ) !== 'local' )
{
\DB::connection()->disableQueryLog();
}
}
- Run these commands on production server
composer dump-autoload
php artisan clear-compiled
php artisan config:cache
php artisan route:cache
php artisan optimize --force
Note that route:cache will not work if you have even a single route defined as a closure.
Hope it helps.
One more thing, I use this package which does minification on blade's output : "graham-campbell/htmlmin": "~3.0". It will optimize your templates to remove unneeded spaces on output.
It won't help on your request performance, but can increase response time as less data is sent through the wire.
Don't use the live option, and if you use the force option, be aware it can break data on <pre> and <textarea> tags and any inline Javascript. If you need to use inline Javascript for any reason, be sure to end every statement with a semi-colon and don't use one-line comments ( // ). Multi-line comments ( /* ... */ ) will work fine.
i know every thing was said here, but it would be nice if you tell us how far you went in speed with this setup ?
@ccasselman Hi, Did your production team look into enabling Zend Opcache?
Just very informal speed tests. MacBook Pro:
Model Name: MacBook Pro Model Identifier: MacBookPro11,1 Processor Name: Intel Core i5 Processor Speed: 2.4 GHz Number of Processors: 1 Total Number of Cores: 2 L2 Cache (per Core): 256 KB L3 Cache: 3 MB Memory: 8 GB Boot ROM Version: MBP111.0138.B14 SMC Version (system): 2.16f68 Serial Number (system): C02MNHXTFH00 Hardware UUID: 2C9AB132-9DF2-5EEB-BC98-79BC05CBD80C
PHP 5.6.8 (cli) (built: Apr 20 2015 10:59:03) Copyright (c) 1997-2015 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
Zend Opcache enabled.
Running XAmpp.
Calling a Laravel Post Route to get all records from a MySQL table, 15 records.
Time measured from start of JavaScript function call to Post request to The Async Success callback with returned data.
Server reads POST request, creates SQL call, executes call. Read result set. Formats result set into a JSON message structure and returns to JavaScript. end time is captured BEFORE JS app processes returned JSON message. Uses JS Date.getTime() to capture time in ms.
Avg w/o ZendOpcache enabled ~ 310 ms. Avg w ZendOpcache enabled ~ 120 ms.
Main menu page is reloaded after each test run.
Again just an informal test to satisfy my curiosity after reading about this in Modern PHP.
Laravel 5
Composer File Packages
"require": {
"laravel/framework": "@stable",
"monolog/monolog": "~1.13",
"guzzlehttp/guzzle": "@stable",
"cboden/ratchet": "0.3.*",
"react/zmq": "0.2.*|0.3.*",
"league/flysystem-aws-s3-v2": "^1.0",
"aws/aws-sdk-php-laravel": "~2.0",
"videlalvaro/php-amqplib": "2.2.*",
"barryvdh/laravel-ide-helper": "~2.0.3",
"doctrine/dbal": "~2.3",
"league/monga": "@stable",
"yaap/theme": "2.*",
"rap2hpoutre/laravel-log-viewer": "@stable",
"firebase/php-jwt": "~2.0",
"spatie/laravel-backup": "^2.4",
"fzaninotto/faker": "@stable",
"spatie/laravel-tail": "^1.1",
"kris/laravel-form-builder": "1.5.*"
},
@ccasselman Came here because the same problem is killing me. I have a few ideas for you, although not the final answer, yet.
Situation:
1 out of 10 requests to my application has a response time over > 500ms, all other requests are < 100ms. This is on my local homestead environment as well as on my linode (which is managed by laravel forge, btw). The route that is called only send a simple hello as a response. No database calls etc.
The strange thing is that as soon as i drop more than 1 request at my app sequentially, response times get much better. The first request is always slow, the next ~9-12 are fine, then there's one slow, the next ~9-12 are fine, and so on...
I can replicate this behavior with a small bash script, which sends requests after a 0.1s timeout. Using a 0.5s timeout yield worse response times, using a 0.05s timeout yields better response times.
Here is the script:
$ for i in {1..100};do curl -s -w "%{time_total}\n" -o /dev/null http://app.dev/test; sleep 0.1; done
And the typical output:
0.778 <--- slow
0.047
0.061
0.043
0.072
0.071
0.052
0.057
0.052
0.075
0.060
0.851 <--- slow
0.066
0.055
0.072
0.067
0.044
0.057
0.057
0.081
0.058
0.040
0.067
0.047
0.804 <--- slow
0.066
0.050
0.055
0.041
0.064
0.061
0.046
0.059
0.055
0.057
0.071
0.045
...
I've tried tweaking nginx/php-fpm already (buffers etc), but to no avail.
I tried using blackfire.io to get some insights. Same situation: If i tell blackfire to only test "one time" (= disable aggregation) I get response times of 1.0s+, when enabling aggregation i get 0.2s on average (i think they do 10 requests). Here are the results for the curious:
1-time-run: https://blackfire.io/profiles/11dd92d7-2ddb-403e-918c-b884b7447b53/graph
10-time-run: https://blackfire.io/profiles/51bab4ca-a505-440e-b4e0-ea76a6bac5d3/graph
I am pretty sure it is a laravel thing, because: The graphs for the two tests above (one time vs. 10 times) look absolutely different. I do not understand them fully yet (have to study a bit how to read them), but it seems that my "one time run" is spending much more time in the autoloader.
Doing php artisan optimize does not help (i disabled debug in my env).
Hope this helps someone in this great community giving us a hint where to look next.
My question is: Does anybody know if the autoloader is doing some weird filesystem caching stuff that works for a few requests and then gets cleared, resulting in slower response times?
I believe that you load too much view and make it slower,because its happened to me too :)
@schtono It think you have this game of slow request because of this configuration, opcache.revalidate_freq and validate_timestamps, if you have opcache turned on, it will check for file changes every 2 seconds, this will slow down request. On production you can turned it off, and do the cache busting manually, or make frequency much higher number, hope this will help
This post is very interesting. I've used cache memcached driver on my app. I divide by four the performance of my app by doing :
memcached in .env file
php artisan config:cache
php artisan optimize --force
An other manner is to optimize assets via Elixir scripts and css. You must compile a file named all.css and all.js in your public directory and you can win 0,5 - 1 second
I don't test eager loading in queries.
@linksderisar I guess your opcache settings is not correct for a production use. On production you should set up opcache revalidate freq to 0 and validate time stamps to 0. Otherwise it will regenerate your cache every n-seconds.
For more info see https://www.scalingphpbook.com/blog/2014/02/14/best-zend-opcache-settings.html
I just wanted to add there might be some heavy optimization with static file serving on nginx (that's what happened to me) and adding this code on nginx sites-enabled configurations made it so much faster:
location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
expires max;
log_not_found off;
access_log off;
}
And if I'm missing something here, please tell me.
Please or to participate in this conversation.