Slide 1

Slide 1 text

Scaling WordPress What to expect. How to prepare. How to react. Takis Bouyouris [email protected]

Slide 2

Slide 2 text

WordPress Greek Community 1st meetup 19/06/2013 Contents ● What to expect Scaling is a problem you WANT to face and it is going to happen sooner or later. ● How to prepare General stuff you can do to make your WordPress installations lighter and less prone to heavy traffic. ● How to react So, you are prepared now! So, your website's traffic increases. What do you do then?

Slide 3

Slide 3 text

WordPress Greek Community 1st meetup 19/06/2013 What to expect ● Your website's lifetime ● Child ~1.000 page views/day ● Teenager ~10.000 page views/day ● Adult ~150.000 page views/day ● Maturity ~1.000.000 page views/day ● Immortality ~scales out (millions of page views/day) (these numbers are rough estimates, of course)

Slide 4

Slide 4 text

WordPress Greek Community 1st meetup 19/06/2013 What to expect/Greatest issues ● High traffic (traffic is traffic, obviously) ● Poor server/hosting performance ● Database clogging (do you actually know what queries your WordPress runs in the background when you do a query_posts?) ● Spikes. Those dreaded spikes! Server killer

Slide 5

Slide 5 text

WordPress Greek Community 1st meetup 19/06/2013 What to expect/Greatest issues ● Number of admins ● Number of concurrent users ● Frequency of content updates (is it a personal blog or a mighty portal?) ● Customization complexity (what you do with all these filters and hooks!) ● Services that cannot be cached ● Comments ● Competitions ● Forms, ajax calls, etc

Slide 6

Slide 6 text

WordPress Greek Community 1st meetup 19/06/2013 What to expect/Greatest issues ● Days to watch out for ● Monday ● Tuesday ● Wednesday ● Thursday ● Hours to watch out for ● Morning ~ 11:00 – 13:00 ● Afternoon ~ 15:00 – 19:00 ● Night ~ 22:00 – 24:00 ● (That's nice! So, I have to be on the watch out 24/7?)

Slide 7

Slide 7 text

WordPress Greek Community 1st meetup 19/06/2013 How to prepare ● WordPress is a simple CMS ● Database architecture is very simple ● For posts: wp_posts wp_postmeta ● For taxonomies: wp_terms wp_term_relationships wp_term_taxonomy * but you do have a table for links ● It is over-generalized ● A fit-for-all solution ● Therefore: not optimized!

Slide 8

Slide 8 text

WordPress Greek Community 1st meetup 19/06/2013 How to prepare ● Minify and combine CSS files ● Put CSS in the ● Minify and combine Javascript files ● Put Javascript before ● Minimize HTML markup ● Make as little http requests as possible ● Allow Keep-Alive ● Cache as much as possible ● For as long as possible ● Enable GZIP for texts ● Compress images and sprite them ● Avoid 404 requests ● Avoid redirects ● Use multiple domains ● Reduce DNS lookups ● Don't use cookies if not necessary or serve static content from cooki-less domains ● Use GET for AJAX

Slide 9

Slide 9 text

WordPress Greek Community 1st meetup 19/06/2013 WordPress tweaks ● Delete old post revisions from the database ● Set revisions not too often ● Set number of revisions retained low ● Use as little as possible custom thumbnail sizes ● Cleanup old sticky posts ● Avoid customization of frequent hooks and filters like "pre_get_posts" ● Avoid long post/taxonomy "not-ins"

Slide 10

Slide 10 text

WordPress Greek Community 1st meetup 19/06/2013 Excluding sticky posts in "pre_get_posts" SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND wp_posts.ID NOT IN (1002,1063,566,1194,1276,1802,1932,1957,2139,2528,2366,2946,3024,3147,2976,3303,3360,3434,4057,4213,4469,4495,4703,47 61,4769,4866,4845,4905,4927,4956,4965,5019,5209,5327,5437,5321,5533,5405,5580,5606,298,5706,5625,5859,5977,6032,6049, 6155,6198,6257,6345,6228,6266,6291,6437,6504,6547,6656,6623,6816,6836,6864,6837,7003,7129,7363,7331,7556,7609,7778,7 818,7345,7713,7611,7926,7712,8016,8106,8090,8001,8065,8010,8233,8321,525,8334,8340,8519,8456,8606,8578,8635,7992,861 3,8715,8536,8358,8742,8790,8759,8754,8832,8847,8857,8885,8871,8952,9026,9052,8973,9099,9122,9167,9177,9245,9280,9295, 9381,9348,9307,9368,9475,9516,9545,9577,9573,9567,9560,9376,9620,9636,9688,9644,9773,9814,9835,9852,9695,9927,9909,1 0036,9975,9992,10116,10232,10241,10257,10183,10221,10133,10163,10335,10367,9656,10469,10416,10494,10502,10547,105 50,10609,10658,10635,10625,10618,10761,10789,10776,10814,10937,10990,11066,11093,11146,11235,11198,11133,11174,11 215,11219,11183,11322,11330,11464,11445,11478,11561,11579,11617,11547,11679,11713,11668,11760,11772,11793,11803,1 1797,11611,11898,11912,11971,11963,12083,12102,12157,10174,12121,12143,12221,12302,12309,12334,12426,12370,12453, 12499,12444,12491,12549,12563,12482,12596,12647,12662,12600,12693,12742,12752,12816,12787,12807,12776,12795,12811 ,261,12879,12927,12944,12965,12995,13014,13041,13046,13073,13104,13160,13136,13174,13131,13186,13294,13314,13348,1 3404,13426,13414,13500,13567,13576,13619,13655,13749,13769,13685,13770,13762,13795,13788,13791,13937,13954,14019, 14077,14131,14169,14238,14286,14361,14450,14432,14397,14512,14506,14596,14606,14613,14666,14727,14671,14680,14640 ,14755,14819,14855,14888,14914,14950,15018,15148,15181,15255,15268,15327,15405,15452,15439,15421,15447,15524,1542 7,15482,15560,15579,15644,15690,15731,15773,15715,15678,15830,15752,15872,15909,15926,15947,15975,15995,16071,160 33,16179,16249,16259,16274,16326,16337,16359,16400,16368,16443,16481,16498,16515,16473,16570,16522,16641,16724,16 675,16746,16826,16835,16858,16887,16918,16891,17007,17052,17014,17066,17149,17101,17171,17125,17225,17255,17246,1 7293,17360,17371,17380,17321,17430,17451,17442,17481,17421,17516,17522,17580,17590,17621,17721,17769,17786,17794, 17884,17873,17906,17914,17980,18067,18048,18124,18152,18134,18164,18269,18208,18223,18320,18388,18350,18363,18340 ,18392,18344,18335,18451,18465,18458,18518,18616,18629,18688,18728,18655,18821,18890,18841,19003,19076,19166,1919 3,19254,18871,19223,19230,18904,19260,18886,19278,19491,19586,19644,19562,19684,19880,20073,20069,20038,20100,202 33,20272,20267,20317,20325,20375,20465,20477,20494,20544,20595,20609,20629,20687,20808,20856,20987,

Slide 11

Slide 11 text

WordPress Greek Community 1st meetup 19/06/2013 Oh, there was more of that 21066,21082,21008,21086,21117,21034,21074,21098,21172,21249,21307,21315,21347,21354,21366,21404,20874,21494,21542 ,21537,21572,21593,21652,21712,21760,21817,21843,21902,21871,22042,22072,22076,22147,22167,22198,22179,22232,2228 8,22317,22377,22570,22587,22632,22728,22766,22781,22793,22805,22817,22880,22933,22941,22856,22850,23277,23319,233 08,22673,23329,23388,23402,23423,23462,23531,23490,23582,23665,23650,23700,23732,23738,23772,23804,23920,23916,23 965,24004,24079,24056,24101,24153,24170,24072,24230,24276,24283,24295,24307,24330,24334,24360,24418,24479,24481,2 4505,24450,24542,24557,24577,24597,24608,24675,24688,24736,24673,24740,24770,24814,24848,24841,24804,24909,24918, 24923,24974,24959,24970,24992,25011,25020,25029,25052,25060,25086,25090,25095,25099,25109,25117,25132,25254,25192 ,25229,25307,25322,25333,25358,25383,25403,25411,25407,25391,25429,25488,25561,25586,25605,25650,25657,25691,2568 6,25682,25696,25748,25780,25837,25979,25990,25995,26007,26101,26165,26185,26193,26245,26280,26293,26347,26358,264 69,26503,26368,26491,26538,26548,26591,26663,26760,26678,26784,26789,26813,26880,26946,27011,27063,27036,27040,27 053,27087,27108,27151,27160,27170,27202,27290,27248,27228,27334,27384,27475,27440,27449,27519,27568,27608,27598,2 7632,27738,27784,27957,28003,28117,28131,28144,28173,28496,28455,28467,28591,28614,28719,28684,28663,28696,28768, 28838,28858,28919,28898,28930,28994,29050,29143,29287,29293,29380,29527,29505,29561,29537,29611,29696,29641,29814 ,29848,29860,29864,29888,29948,29987,30036,30007,30067,30094,30336,30360,30397,30513,30614,30618,30630,30694,3074 2,30829,30872,30881,31013,31040,31056,31288,31325,31347,31424,31454,31534,31573,31692,31749,31817,31879,31904,318 37,32059,32153,32161,32253,32372,32419,32418,32476,32484,32492,32750,32763,32857,32923,33122,33176,33248,33256,33 310,33394,33503,33562,33668,33626,33784,33778,33887,33985,34012,34017,34053,34083,34101,34139,34204,34254,34316,3 4377,34491,34489,34516,34568,34598,34676,34722,34805,34995,35023,35054,35060,35064,35085,35093,35107,35112,35143, 35182,35191,35389,35450,35527,35537,35553,35743,35735,35763,35898,35893,35914,36013,36151,36147,36310,36358,36391 ,36461,36456,36603,36618,36652,36665,36695,36747,36796,36893,36941,36958,37007,37107,37181,37268,37276,37316,3735 6,37427,37454,37487,37508,37514,37572,37615,37678,37815,37909,38156,38261,38417,38478,38626,38639,38672,38755,388 36,38864,39027,39045,39072,39130,39284,39351,39381,39493,39516,39558,39615,39645,39766,39911,39920,39931,39930,39 992,39982,40163,40223,40257,40278,40509,40535,40552,40611,40659,40772,40788,40856,40912,40935,40961,40993,41198,4 1280,41401,41448,41505,41596,41768,41792,41850,41982,42092,42053,42213,42266,42352,42423,42579,42612,42751,42794, 42846,42875,43028,43204,43277,43303,43370,43440,43650,43750,43786,43816,43841,43851,43929,43955,44036,44050,44064 ,44076,44113,44207,44293,44292,44351,44577,44615,44648,44755,44693,44881,44951,45047,45090,45095,45165,45188,4525 7,45420,45529,45625,45680,45734,45769,45771,45800,45813,45837,45881,45893,45908,45935,45917,45988,46015,46080,461 42,46168,46185,46317,46312,46371,46413,46518,46552,46693,46742,46766,46720,46861,46925,46941,47218,47268,47315,47 374,47378,47384,47391,47426,47398,47470,47479,47507,47513,47614,49209,49280,50050,50299,51072,52613,53004,53526,5 3676,54478,54583,55619,55891,56308,56890,57393,57424,57651,58504,58837,60845,61313,61596,61663)

Slide 12

Slide 12 text

WordPress Greek Community 1st meetup 19/06/2013 (Yeah, now we are just showing off) AND ( wp_posts.ID NOT IN ( SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id IN (1) ) ) AND wp_posts.post_type IN ('videos', 'galleries', 'competitions', 'post', 'nav_menu_item') AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending' OR wp_posts.post_status = 'trash' OR wp_posts.post_status = 'auto-draft' OR wp_posts.post_status = 'inherit' OR wp_posts.post_status = 'private') AND ( (wp_postmeta.meta_key = 'day_new' AND CAST(wp_postmeta.meta_value AS CHAR) = 'true') ) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 1 Yeah, right!

Slide 13

Slide 13 text

WordPress Greek Community 1st meetup 19/06/2013 Keep calm and cache on ● Probably the single most important technique ● Useful no matter how big your site is ● All websites need to use caching ● There are two areas where you can cache ● The server ● The browser (try to remain calm)

Slide 14

Slide 14 text

WordPress Greek Community 1st meetup 19/06/2013 Server caching ● Cache whole requests Use plugins like W3 Total Cace or Hyper Cache ● Object and query cache Same plugins, but use it yourself, too (remember WordPress transients) ● HTML fragment cache For instance cache the sidebar contents ● Opcode cache Use APC in Apache for PHP Opcode caching (mostly useful in big monolithic websites)

Slide 15

Slide 15 text

WordPress Greek Community 1st meetup 19/06/2013 Browser caching ● Better: eliminate redundant requests ● Add expires headers ● Favicons -almost- never change ● Font files -almost- never change ● Styles and scripts rarely change ● Images also rarely change (new ones appear, but old ones rarely change) ● HTML might change often (it depends) ● Be prepared to un-cache (invalidate) content In order to minimize requests

Slide 16

Slide 16 text

WordPress Greek Community 1st meetup 19/06/2013 What expires headers do They turn this: Into this: 200 (not OK!) 304 (that is OK!)

Slide 17

Slide 17 text

WordPress Greek Community 1st meetup 19/06/2013 How to react – Some tips ● "Always be prepared" ● Step by step ● Child ~1.000 page views ● Teenager ~10.000 page views ● Adult ~150.000 page views ● Maturity ~1.000.000 page views ● Immortality ~scales out (millions of page views) A shared hostinng is fine Must cache (W3C Total Cache, Hyper-Cache etc) A dedicated server is appropriate An extra cache server (Varnish) will do the job CDN: it costs but it gets the job done (tweaking is still necassary)

Slide 18

Slide 18 text

WordPress Greek Community 1st meetup 19/06/2013 Keep your options open ● You can always use a CDN even from early on ● Akamai ● CloudFront ● CloudFlare ● AWS ● Or a dedicated/managed WordPress hosting service ● http://wpengine.com/ ● http://zippykid.com/ ● https://page.ly/ ● http://websynthesis.com/ (just throwing some names, not recommending anything)

Slide 19

Slide 19 text

WordPress Greek Community 1st meetup 19/06/2013 Further reading ● http://www.webperformancetoday.com/ ● http://scalingwp.wordpress.com/ ● http://www.slideshare.net/josephscott/scaling-wordpr ess-20731197/ ● https://developers.google.com/speed/ ● http://www.stevesouders.com/ ● http://codex.wordpress.org/WordPress_Optimization /WordPress_Performance/

Slide 20

Slide 20 text

Scaling WordPress What to expect. How to prepare. How to react. Takis Bouyouris [email protected]