Welcome to the sessions, Properties of Lightweight Concrete. This is Chetanji Kunapuray, Assistant Professor of Department of Cell Engineering, Vulture and Institute of Technology. So, these are the learning outcomes. At the end of the session, student will be able to explain the concept of lightweight concrete, the properties of lightweight concrete. Let us see the introduction of lightweight concrete. Definition wise, lightweight concrete is produced by including large quantities of air in the aggregate in matrix or in between the matrix particles or combination of these processes. Even lightweight material can be used to produce the lightweight concrete and basically the major mass contributing material is the aggregate. So, if the unit weight is less than about 1000 kg per meter cube, that these types of aggregates are designated as lightweight aggregate. Now, why the density is less? This is only because of the cellular structure or highly porous microstructure of the aggregate. So, the lightweight is because of this reason only. Generally the density of normal concrete is 2200 to 2600 kg per meter cube, which leads to heavy self-weight of the structure elements. However, the density of lightweight concrete varies from 300 to 1850 kg per meter cube. So, from this, let us see what are the advantages of lightweight concrete. Now, if the density is reducing, definitely the self-weight of the structure elements will reduce. So, if the structure elements are lighter, then their dead load will reduce. So, reduction in the dead load of the structure, this is the first advantage. Then when the dead load will reduce, the section sizes will reduce, which facilitates the speedy construction of the building of the structures. Next thing is as the sections are reducing, structural sizes are reducing, which reduces the haulage and handling cost of material as well as sections as well as the entire construction activity. Next thing, major advantage of lightweight concrete is in case of weak soils and tall structures because in RCC structures or in the buildings, generally dead load is the major contributing load in the total load. So, because of a heavy dead load, the spread of the foundation is more or the size of the foundation will be big in weak soils and in case of tall structure, the spread is also more, size is also more. So, as dead load will reduce, the spread or size of the foundation will reduce, so the foundation cost will reduce. And last thing is reduction is the section size, reduction in the structure, reduction in the material as well as the speedy construction and all other further activities of the construction for these types of lightweight concrete structures. These activities also will become fast and less time consuming, which will give us the overall economy and that economy can be achieved all. Let us see what are the properties of lightweight concrete. Now, these are the following properties of lightweight concrete. First is the compressive strength and density of the concrete which are correlated to each other. Next, modulus of elasticity and the Poisson ratio which are elastic properties of the concrete. Next is water absorption and moisture content and creep shrinkage after hardened state, thermal expansion and conductivity. So, these are basically primary properties of the lightweight concrete. Now, the suitability of lightweight concrete depends on above desired properties. Now, let us see the first property that is the compressive strength and density of the concrete. Basically, this is the basic relationship in the concrete that is the relationship between compressive strength and density. So, as density will improve, the strength of the concrete will improve. In case of lightweight concrete, generally the strength is lower than that of the normal concrete. Why this is because you can see this graph which is giving you relationship or the plot of this graph is compressive strength versus density of the concrete. Now, the density of concrete affects its strength. This figure shows an increase in strength from 30 to 60 MPa when the density is improved from 1300 kg per meter cube, so you can see here. So, improvement in the density leads to increase in the strength that we can see here. You can see the relationship of compressive strength to density for different countries. So, this is Germany or the concrete which is produced in the Germany in that graph. You can see different countries USA, Germany, Switzerland, Great Britain, USSR, Russia. So, the relationship is explained here and the strength is doubled from 30 to 60 when the density is whereas, the density is 1.5 times of 1360 that is 1900 kg per meter cube. Now, let us see this modulus velocity and Poisson's ratio. For concrete of density 1500 to 2500 kg per meter cube and strength up to 35 MPa. So, ACI recommends this figure 2 and this equation for calculation of modulus of elasticity. You can see this equation that is E c is equal to W raise to 1.5 into 0.043 root f dash c and this will give you E c or elasticity in MPa. Where this f dash c is cylinder compressive strength of the concrete and this f dash c can be calculated from this expression that is 0.7 under 0.7 fck. You can see this graph on x axis compressive strength in MPa on y axis modulus of elasticity in MPa. This line representing normal weight concrete and this zone representing light weight concrete. These two lines are for sand light weight aggregate concrete in several times the sand is used to improve the density of the concrete so that why these lines are for that. Now, this is the range for all light weight concrete. Now, this graph explains relationship between modulus of elasticity and strength. The next parameter is Poisson's ratio mu. Mu is based on several tests carried out and it varies 0.15 to 0.25. Practically the mu value is 0.2 taken for light weight concrete. Now, my question for all of you is as per ACI what is the relationship between cylinder and cube compressive strength? These are the options for you A, B, C, D 0.5, 0.6, 0.7, 0.8. Now, write down the answer for this question pause the video. The answer is 0.7 so relationship between cylinder strength and cube strength is 0.7. Now, let us see absorption properties so water absorption and moisture content. Now, generally light weight concrete is produced by using light weight coarse aggregates and light weight coarse aggregates are having higher degree of absorption. This is only because of their cellular pattern as well as microstructure is highly porous. So, light weight coarse aggregates are absorbing more water it is these are having high degree of absorption. This absorption is in between 5 to 20 percent of the water which is really high. Normal weight aggregates deserves 2 percent of the absorption. Now, how it is a difficult this is for workability purpose we want water and whatever water content is given in our IS or in the references this water content is for the hydration process and if this much quantity of what is absorbed so workability will be the issue so evaluating the workability in the mix design is very difficult. Next is CRIP and shrinkage values of the CRIP and shrinkage are greater for light weight concrete when it is compared to the normal concrete. This is only because of the cause strength as strength increased CRIP becomes less. So, for ultra high strength light weight concrete the value of CRIP becomes same or equal for normal and light weight concrete. Now, next is thermal expansion and thermal conductivity. So, the thermal expansion in terms of coefficient of thermal expansion is given and it is less than normal concrete though so because basically thermal expansion is a function of component materials for the concrete. So, the range for thermal expansion is 8 to 12 into 10 is to minus 6 for light weight concrete whereas, it is 9 to 13 into 10 is to minus 6 for normal weight concrete. Not much difference is there, but difference is there. Now, light weight concrete from this parameter of the property wise it is very excellent it has excellent insulating property. So, expression is given here for thermal conductivity k is equal to 0.072 e raise to 0.00125 w where w is unit weight of the concrete in kg parameter cube and e value is 2.7182. If you substitute w here you will get k. Here one thing I want to explain here as density of concrete increases the thermal conductivity increases. So, thermal conductivity is better because only of reduced density or lower density. Now, these are the few recommendations related to the physical properties of concrete and which are shown in table 1 and 2. Table 1 is recommended as slumps table 2 is relationship between water cementation and compressive strength. This recommended slumps for 3 different types of constructions are given for beams and reinforced concrete it is in between 125 minimum is a 25 100 is maximum. For columns building columns 100 to 25 and for slabs 75 to 25 so, while designing the mix and the fresh property like slump we can select the value in between of these maximum minimum. Now, as a guideline for taking the water cement ratio this table we can refer this is approximate water cement ratio and here you can see for M 20 grid of concrete the for non air entrained concrete it is 0.68. Now, this is the table 3 which gives you approximate mixing water and air content requirement for different slumps and nominal maximum sizes of aggregate. I am emphasizing on this that is a non air entrained concrete and the water quantity for nominal aggregate size there are 3 sizes 10 15 20. For 20 it is 189 for 20 to 25 to 50 slump and 204 kg per meter for 75 to 100 these things we can use in our mix designs also. These are the references for the video thank you.


Jerry of the circus for Jerry of the circus will be good friend yeah but not for long I'm afraid why not well there's always a danger that if the cub gets bigger he might hurt rags sometime while they're playing if no one was around and it was blood or something that cup might revert to his jungle ancestors what do you mean revert well he might forget he's supposed to be a well behaved while animal and suddenly smelling blood he might think of the kill oh I see of course I suppose he might still think you'd like to train with the pals I should say not what do you think I am guess maybe I'd better take rags now and I didn't mean to scare you Jerry not much you didn't know it's safe enough for them to play now if we kind of keep our eyes on them but it is true you have to be pretty careful while the crop goes up golly I should say so I suppose they're too little to know why they do certain things that's it and too young to be well enough trained so you can trust them it's fuzzy too small to start training yet no sir he's just about the right age yeah I'd like to try what can we teach him I was planning on feeding him now so this is just about the best time to start learning something I know because you reward him when he does the right thing hit the nail right in the head Jerry look here's a little board it let's make him jump over okay take these pieces of meat and start calling him I don't mean to kind of a cat you think now come here and right on I'm trying to train this cub guess I'll call him fuzzy he may as well learn his name now you're going to have your hands full here I'll hold rags see they both smell me oh no I manage rags will behave down rags and not a word out of you understand he may behave but he sure sashes your back come on now fuzzy you're fuzzy geez cute well he's got a good nose all right but he climbed over the board instead of just that's all right given this piece of meat at least you'll know what's coming to him on the other side of that board I'll put fuzzy back on the other side of the board again now mr. cubline let's see you do your stuff okay fuzzy come on well that's better catching on aren't you though you're kind of hungry huh he acts as if he hasn't eaten for days cublines eat just like little pigs and in a couple of months when they've got bigger stomachs and bigger appetite you should see them he hasn't jumped yet but he certainly has learned to get over that board quick enough just give him time here we're giving this another try there you go fuzzy back on the other side you're fuzzy fuzzy fuzzy sure he did but he lost his balance his first jump pretty good fuzzy you're deserve your meat this time hey careful of my finger she is teeth are sharp so are his claws cubs can do plenty of damage if they're not watched say wait a minute golly he's quick yeah he's not going to take any chances with the rest of that meat thinks he'd better get it now all I get is good back you go we'll try it once more fuzzy okay I'm ready come on fuzzy that's what I call a real job watch out Jerry he's gonna get the rest of that get away from there look at those little months here get away my golly that cub is a scrapper for being such a little shaver fuzzy you're trying to protect his meat trying to sprawl all over it's a little big poor rags fuzzy can sure put on a vicious looking act a rag look out stop it rags I'll look at his legs good night that's a mean one right in the joint to rags are you poor thing here wait a minute I'll stick fuzzy back in the cage and help you fix rags up this cub is smart enough but he is too much of a scrapper I can see you'll take plenty of training golly do you think rags will be all right I never heard him whine so much you think it's serious I'll see you in a minute here you are cat now you stay in there come on Jerry we'll go over to my wagon I got a lot of first-aid things over there all right oh there's Patsy hello there Patsy where you're going excitement I guess excitement say you just missed plenty of it what happened hey what's wrong with rags oh he got scratched by the new cub Jason was just you on me oh I'll say he did Jason look this looks kind of bad isn't that tendon torn or something look how he's holding that leg as if he has any control over yeah I know I'm not sure yet I'll have to fix it I'm up ah gee it isn't serious is it I don't know what I'd do if anything happened to rags I certainly hope not come on in here there you are rags I can't tell very well what's what yet we'll have to put a little iodine in here to be sure it's not infected got to be pretty careful with claws they can be nasty sometimes I know I know that's not very nice to take poor fellow there you are rags you're gonna be all nice and well certainly do a marvelous piece of work Jason why'd you learn to be such a good veterinarian you're in a hospital what do you mean oh well I was laid up once oh you mean that time you had that bad accident in the cage yeah that's it well all the time I was in the hospital I learned everything I could about how to protect myself in case of an accident I even used to read books on anatomy but how do you know about animals well when I learned all I could about people I got some books from the library on animals so I'd be an amateur veterinarian too I always knew you were smart Jason but didn't realize how versatile you are what's versatile oh that's being good at lots of things hey Jason what are you doing with those sticks I'm going to put rags foot in a splint say is it as bad as that that doesn't mean it's serious Jerry it'll just protect rags from getting hurt anymore and it'll make him keep his legs still well that one anyway but how will he do his act he won't do his act I'll say you what a bump do well I don't know as soon as we get this fixed you'd better take rags over and see what bumps says you certainly go about that managing business professionally Jason good night Pessie I almost forgot what well that letter came today what letter the one from the bank oh sure it is you want to read it well you haven't opened again no I thought I'd wait for you go on and read it okay if you say thou oh mr. Jordan sweet I don't know whether it's going to help us much or not though oh what'd they have to say let's see well this is from mr. Ross yeah I know the man at the bank mm-hmm he says he checked with the clearing house that he told us about I wish you're nice of them he says that particular lock is made by the Brunner lock company in Crystal Falls Jiminy whiskers that's something and he advises us to write them for further information I'll do that today gee will you pat me you're swell golly I sure like to find out where that box is dead and well if there's any way of preaching it we'll find it don't you worry Jerry all right if you ask me that's a pretty neat job you're welcome you've got a polite dog there Jerry did you hear him thank me I sure did he knows you're trying to help him aw look he's licking your hand that dog doesn't have to talk he has so many little ways of letting you know what he wants yeah and sometimes it's a big help for him not to be able to talk because he pretends he doesn't know what I'm telling him so he takes advantage of you mm-hmm yeah but I'm usually on to him and then he looks so foolish when he sees I won't let him get away with something it's getting late Jerry I think you'd better run along and see bumps and tell him about rags if bumps decides not to use him you'll have to know ahead of time in order to plan his acts oh of course and thanks Jason for fixing rags up so swell and goodbye patsy don't forget about that letter I won't see you later Jerry so long Jerry sorry old timer but you better rest this time come on bumps it's late hey how's rag fit is a fiddle but raising a rumpus every time I start to leave him here alone oh can you blame him here we've been telling him the show has to go on regardless now that he's got his fawn as flint we make him go to bed oh it just doesn't make sense does it rags old brother well I better get along stop it hey bumps you think you'd heard it if rags just ran around with you well no just on the walk around rags you win come on bumps will take you along I think it'll get him too excited not to let him work bumps if you don't mind just letting him tag along on the walk around well there's one thing that dog pure knows what he wants all right rags we'll do even if we are a handicapped gee you're swell bumps hi patsy hi folks hey young fellow why aren't you in bed you mean right oh it's a trooper in him he insists on going on well I don't blame him but you think it's safe bumps oh sure we'll take it easy you better watch us though we'll have to change our act and no summer sauce this time oh here's a cue and come on come on isn't that just like bumps he'll have to change his whole routine he's as proud of that pup as you are jerry golly rags is proud of himself like a kid that's finally got his own way well he can do the book trick anyhow sits on that big shoe of bumps as proud as if he was driving along on the front seat of a car hey gee bumps you didn't oh golly I thought he was going to kick him up in the air and let him do some of those summer sauce oh don't you worry about bumps kind of tricky the way he caught rags on his shoulder but you notice he helped rags land right so not as to hurt his legs rags on the whole circus he sits up there for cows so bad he can't go yeah say look at him sniffing bumps here I bet that tickles bumps is pretending he does know where rags is well rags isn't letting him get away with it look at him tap bumps with his good paw look at bumps hunting over the wrong shoulder trying to find out what's back of him yeah hey what's happened oh gee rags bumps his bad leg onto the stage why is he lying so still you think he's badly hurt jerry golly I hope not he just lay out one yelp I think he's playing possum though you know dead dog see bumps is picking him up heavens he surely looks limp look at the way bumps are shaking his head oh I think bumps are just putting that on for the audience jerry isn't he marvelous you think he lost his last friend he looks so sad so it was just a game after all had me scared for a minute me too look at him run here rags here rags for bumps coming behind him oh well I'm all out of breath say listen jerry get rags over the wagon will you want to have a look at that leg I'm afraid he really hurt himself when he ran into that stake oh gee bumps golly I'd never forgive myself if I made him go on and and he really got hurt well now don't you worry jerry but I'll tell you one he doesn't work again until that leg as well


Dave Mazda, how are you doing? I'm doing well, I'm happy to be back. Yes, and it's a great day to be back, because what I'd like to talk, you know, I've been trading these products for a long time, okay? And we know that, you know, the leveraged products are definitely for traders, okay? There's no doubt about it. What I'd like to talk a little bit about, okay, is that, you know, there's plenty of folks that, you know, you have so many more of them now that are in different sectors. And there's plenty of folks that, you know, if you're in for this market for a long period of time, it's pretty cool if you can get close to Delta Neutral. And Delta Neutral, folks, means that you just set something up on the other side without selling, without the tax implication. And direction is plenty of products like that, you know, that they could, you can protect yourself, meaning that, okay, unless you're in the housing business, you can get nail, right?  If you, if we get a downdraft going, you can protect yourself for a month, that's pretty good. Yeah, let's talk about hedging. Obviously a sell-off like we've seen in September really exuberated by today's market moves gets everyone thinking, how do I protect my portfolio? Yes. And one of the opportunity sets that we offer is these inverse ETFs. So what this means is that they offer the opposite of the return. So let's say markets are down 1%. It would be up accordingly. Now, a couple of ways to think about that. So I think folks are probably familiar with SPXL, that's the 3x bull on the S&P 500. The fair is SPXS. So this is a tool, let's say going in today, if someone wanted to put on a hedge in their portfolio of the short-term, I'd look at that 3x exposure, and against your longs, you're gonna be doing quite well today. But if you wanna have something that kind of can be a little bit of a longer-term holding, you still have to pay attention to it, understand to your point, how much hedge ratio do I wanna have on? You can look at something like SPDN. So this is just one times the inverse of the S&P 500. And because of that, you have the ability to use it for slightly longer time periods without some of the negatives that can come in from compounding. Now, to be honest, you get the returns of SPDN this year because markets effectively were on a straight line much the year, it's gonna be down. But in a month like September, whether you believe in seasonality, whether you're using other technical indicators, it could be really a powerful tool to help buffer against states like today. Oh, there's no doubt, man, no, I see this. This is pretty cool, man. I actually didn't know that you had a one-to-one on the S&P too, because that is huge. So folks, it is SPDN. And what's so cool, as Dave just said, this is something that if you think the S&P is gonna go lower, the good news is that, you know, you can put this on and say, okay, as my portfolio is going down, this is going up a bit, okay? You know, at just less risk in the marketplace, if you bottom line think we're gonna get out too quick, well, then you could do the ratio trade. It's something that I just would love you investors and traders to look into because it's important and it's amazing, Dave, that you actually could put them on and people can save a lot of money.   Yeah, I mean, and we haven't even been below the 50-day moving average in the S&P 500, not that that's an end-all-be-all ratio, but it's generally a guide of just how kind of easy returns have been. It is. So what's interesting is, you know, everyone's asking for the sell-off, whether this continues, these are opportunities where you want to put, either put some of that cash to work on the long side or look at hedging the longs you might have. Another use, cause we just got through another busy earning season that these inverse products can have is, let's say you have a portfolio that's tech heavy or semiconductor heavy. Whether you're using the ETF or the individual names, we really see a lot of activity on names like Tech S or on Sox S to provide that hedge on that week when everyone's reporting your new videos and that are moving the index, just to give you that buffer, because to your point, the last thing you want to have to do, unless you, the fundamentals of the company have changed or your opinion of the company or whatever indicators you're using change is sell longs in a day like today. Again, particularly if you put them on for reasons. So these tools can be used for that. And I like them as well because options have never been easier to trade for investors, but they involve different types of risks. Inverse ETFs have their own type of risk, but it's just a good way where again, you can keep the core of your portfolio or your trading book, whatever your outlook or thesis is and use a tool like this for a small outlay of capital to provide that buffer when you might need it at the worst possible time for a market. There's no doubt. The best possible time. And as Dave just brought up, the option market folks, what happens in a day like today, and listen, I trade a lot of options, you can't buy them today because your premium is so high. Your product is where it's at on a day, it really is, Dave, do you know what I mean? Because what ends up happening, I was looking, even looking at the spreads and the option market, they're outrageous, you know what I'm saying? They get blown through right away when we realize volatility increases. They do. Well listen, we appreciate the update, we look forward to speaking in two weeks. Talk soon. Thanks Dave, have a great one.


Do you ever wonder what happens when the police leave? Crime scene cleaners are private companies that handle the cleanup after the police are gone. Spalling Decon is one of the nation's largest cleanup companies handling the aftermath of homicides, suicides, decompositions, hoarding and much more. These are our stories. We are in safety harbor and we are doing a bio slash hoard. She did not pass away here. She passed away shortly after being removed from here at the hospital. The family lives out west and we have just a small list of things that we are looking for. It's a total clean out. Should be one day but we got down a man because somebody called out which puts us just a little bit further behind. We should be good.  Maybe we should have brought the dates earlier. We're not removing carpet. Watch your back. That's the bio that we were told exists. I'm glad we didn't bring a van.  There's one other bedroom somewhere. Ready? Oh my god. Alright, so carpet's not getting removed. Just total gut. That would probably be... That's the way it is. I anticipated me breaking something. Getting ready to really enjoy this job. That's what I'm doing today. Yeah, the one that has the littest for like keepsakes and things like that. Hey, do you want to start the morning off right? I'm joking guys. He was like really hardcore. Can you dump this in the same place? I'm cleaning the bio hazard part. So we have just a little bit of blood over the mattress. So it's super easy. This is going to take like 30 minutes. Cheers. This is gorgeous. Like I could totally see this in my entryway. What is that called? Foyer? It is beautiful but no. Is that like an old fashioned? Yeah, it's ringing right here. Is it got a cord? Yeah. I don't know where the phone is. It's just a receiver for it. Oh no, I mean like is it like corded? Oh no. That's probably the coolest thing we've ever heard on a job. Not even gonna lie. Phone ringing? Yeah, the 1920's called. Any money goes in that bin as well. Yeah, I get it. As we're going through the kitchen, there is one, two, three, four, five, six, seven, eight, nine, ten, eleven bottles of vodka. I also picked up three or four. I think three or four in the living room. I got one in the bag too. Plus one in the bag so we're looking at, please don't, why would you do that right now? He opened the fridge. That was his initiation for later, but at least now he knows that what he's getting himself into. So out of minimum, just walking in and being here for 20 minutes, we've seen 20 bottles of vodka. Vodka? Cause I can't talk great. Some people just like to drink. I'm supposed to smile. There's lots of dead bugs in there. Looks like some mouse droppings too. Dad in there, it's pretty nasty. I'm afraid to see what I find in there when I start digging through there and pull all that crap out. I'm sure it's gonna happen, but so far it's, you know, somebody has to do it. I got like an awesome quote for the day.  Always hold it high. Look the world straight. Hell in Kelly. A little bit of positivity for the day. It is Humpty. We got this.  I don't know what it's supposed to be, but it was hanging from the hook. This is the nice apartment. There's not like too much stuff, but we have a lot of furniture. So maybe we're gonna be here the whole day. That is fair. Jesus Christ, it must be nice and 12 foot tall. So we just had a guy. It's actually the first time it's ever happened to us. Come to deliver a disconnection notice to the power because the bill hasn't been paid. So he's like, it's the owner here. I'm like, no, they've since passed and family lives out West. He got really awkward because he was a young kid. I don't think he had ever had to deal with this before.  So I went outside and I was like, look, we're trying to clean up and pack up because the family isn't here. Is there a way you could just kind of leave it on for us? Don't worry about it. He goes, I didn't even think about that. So you're good.  Jobs like this that kind of put you into a reality check, like cleanliness of your house and the items that you have and where you have them and things like that because it's like when you pass away and you don't have any family or anything like that local. It's guys like that, like guys like us that come in and abide by a small but very strict list of what's key. The good thing is this family is awesome because they're donating everything furniture-wise or clothing-wise and things like that.  A lot of places right now being just after the holidays aren't picking up so it's us to bring and call. Sometimes stuff like this sits in our warehouse for a couple of weeks or up to a couple of months just so we can kind of figure out what place is best for donations whether it be like children's shelters for children's clothes and children's furniture or like women's shelters for abused and battered women or people that don't have the means to be able to get furnishings and things like that. That stinks. No. Is lunch ready yet? Because I'm about to dump this and go outside. Oh, are you serious? So nice. So, since you decided to pour eggshell water down the drain, Juan and I came up to the conclusion because we both don't like pineapple, you can go get fucked. It's brand new, it was in the wrapper. Hi, my name is Dakota. I'm the newest member of Spalding Decon. And this is really my second job. So far, it's going good. I haven't encountered anything too crazy. Like super gently used. Families who don't have anything can... I'm doing a separating garbage from paper work and things like that. Just like totally Carby Barbie did that. So I don't feel like doing anything anymore.  They taste amazing. Dakota! What? You want a snack? You just totally found some tidbots.  Yes!  I just got a notification. Oh, what? Heavy participation in Safety Harbor. Y'all? That's what it is. It's going right... Oh my God, are you kidding me? Look at that. Safety Harbor, Florida. I'm going home. That's where we are. That area is fucked. Yep. So it's like avoid, avoid, avoid, BAM! It's really starting to rain now, so I'm just going to go inside for a few minutes. I just want to check if we have something up here. At this point, it's happened, but you remember when I climbed up my leg? I do not do well with rodents or bugs. I just don't do anything. I just don't do well with anything that's like creepy crawler. Do you want to clean out this closet? Hey, you need a hand? Hardy-har-har. I kill myself. Dude, that's funny. Or she. Excuse me, I'm not trying to like... Identify the rat. It's in here somewhere. We're here on day two here in Safety Harbor and we're starting in the bedroom. Trying to finish the last-minute touch-up stuff should be here a couple of hours. Something did change today. We've got Nick because Dakota had prior plans, so changing up the crew a little bit. See you guys inside. Just kidding. Ready? This is like a five-man job. One moment, doc. I'm not going to make it. I'm not going to make it. I need it. Yeah, this side's kind of dark and dreary. Like my soul. Could you only wish your wood was that big? We're just trying to rearrange the trailer. We can take it to the nation center, but it's all big bulky stuff, so we have to kind of play a game of Tetris. Good. Gotta go down. What? Is it going to fit? I have this hanging over my bed for my pole. He's our man. If he can't do it, no one can. You got to get over the box. Yeah, you're good. How do you do that so easily? So we've been here for two hours exactly. We got here at 10.30. And pretty much got the place cleaned out furniture-wise. It's being donated, stuff that we can't donate. We're just going to throw in the dump trailer because we brought both trailers. And then it's just to tighten it up at the place and making sure that it's nothing else that we missed. It's actually really, it's perfect weather today for us to be working and kind of lifting furniture and things like that. So we have the doors open to kind of air it out, but it's also giving us a breeze because it's only 52 degrees at 12.30. So it's going really good today. Damn.  Yo. You can rock it. What you want, baby? I got what you need. You want Rolex? I got your Rolex. You need some cocaine. I got some cocaine. I got you. Could I rock this? Like, is this rockable? How you doing? Yeah, I could think. I think you could do an estimate, was it? Yes. Oh my God, I'm going to do the water job in this.  That's exactly what's going to happen. This thing is so warm. Already?  Juan! Nice. Oh my God, I feel like I'm wearing the entire African safari. Oh, I'm doing it all by myself. Yay! We did it. Look, we both did it. Yay. We bought some seeds. We are all done. Day number two complete. It is kind of warmed up to, like, 58 degrees. So it's been super, super pleasant. We have this trailer full of donation here. That trailer is another trailer full of garbage, stuff that we just, we can't donate.  We're looking at probably an hour and a half's drive. If I remember from yesterday, hope you guys enjoyed. Thanks for watching, guys. Don't forget to like, share, subscribe, and ring that bell to be notified of the next episode. That's it, guys. On to the next.


So, welcome to the last session of TripleCon, I guess, like the last, last lot of sessions. So I hope you had a good time so far. Today's session, I've talked about rendering and caching in the past, but today's session is meant to be more practical, more pragmatic, so it's not going into all the technical implementation details, it is not going into edge cases, it's going into the common case, and how you can use render caching, dynamic page cache, page cache, pick pipe in practice, how you can debug them in practice. So if that's not what you're looking for today, then maybe switch to a different session. If that is what you're looking for today, then I hope you will enjoy what's to come. I am going to do a live demo, live debugging, so if you have questions along the way, raise your hand so I can jump into things on the spot. Hopefully all goes well, it's a live thing, but I think it's more useful to see it being demonstrated how you can step through things than it is just on pure slides. So the point is that I'm taking you through the different layers, through the depths of Drupal to some extent, if you will, hopefully after this session it will not be as scary anymore if it is scary today. How many of you have had experience, or how many of you are using big pipe? Raise of hands? Cool, about 10%, 15% maybe. How many of you have disabled page cache? Three hands, four hands, interesting. How many of you have seen the ex-Drupal dynamic cache response header and have seen it set to uncacheable and wondered why? Okay, good. So hopefully all of those things should become clear. And again, please interrupt me if you have a question. So let's get started. I'm going to go very light on theory, but this is basically the only slide I have about caching. This is the principle of caching, right? I think I don't really need to explain it, but I'll just go over it real quick. The whole point of computing is that you have a bunch of inputs, you apply computations to it and you get output. So we're making a robot to a bunch of work and it takes time and we want it to go faster. So what is caching? It is instead of making the computation again and again, based on the inputs we generate a cache ID, something that represents uniquely the thing that we are computing. And then we read the computed output that we stored previously and just return that. So the point is to save time by storing some data somewhere that we can look up easily. That's simple, right? But the tricky thing about caching is not caching in and of itself. The tricky thing is cache invalidation. As the saying goes, or the joke goes, there's two hard problems in computer science, caching validation and naming things. Well, Drupal 8 tried to solve caching validation and hopefully you'll see or if you've already experienced it, you've already noticed that it has solved caching validation, not in the general way perhaps, but for the purposes of Drupal, definitely it did. And so perhaps what does caching validation mean? Well, the thing is that if inputs change, that the output should also change. And that's a tricky thing. We don't always know perfectly well when inputs change. And that was a very big problem in Drupal 7 and before, but for Drupal 8 we have the concept of cache tags and cache contexts. So cache tags describe data dependencies. They describe when stored data is modified, when it changes. So when you have something that is stored in cache, so some output that we cached, what matters is that the cache ID is always correct and that the stored data that we read is always up to date. Otherwise, we're showing them either wrong data or stale data. And we want to avoid that. So tags describe when an input has changed. So for example, when a user profile, let's say it's a user profile, and they change their hobby from table tennis to snowboarding, like that's important that it shows up right away on the rendered outputs, that's what cache tags describe, such stored data changes. Contacts on the other hand describe circumstances, the context. And an example would be rain or no rain. So imagine it is raining, that should show one result. And it is not raining, it should show the other results. So based on tags and contexts, we can define what the cache ID should vary by. So the cache ID is a thing we look up, and either we should look up the rain or the no rain cache entry or the rain cache entry, either one. In this case, there's only two possible values, but perhaps for some cache context, there is 10 or 100 or 1000s. So cache contexts impact the cache ID. Describe variations. Cache tags describe changes in the stored data. And both of them are necessary to do this correctly, to do cache lookups correctly and invalidate them correctly. There's a third that is less important, Max-H. Probably all of you have heard of Max-H before, because it's part of the HTTP cache control header. It's the same principle. Max-H, you only need for freshness, staleness, data that is always changing. Things like the current temperature. If I show the current temperature right now, then one second later, it might be different, right? So it's only for time-sensitive data, and that means things like charts, graphs for stock exchange, for weather and whatnot. So that's really all it's about. The caching means taking in-and-puts, going to an output. But that's trivial. The tricky thing, the hard thing, that wasn't solved until Drupal 8 was invalidating correctly. In Drupal 7, what happened was either you were serving stale data, or we were just invalidating the entire page cache, the entire render cache. Every single time a comment was posted, a title was edited, like everything was invalidated. Well, of course, things are correct then, but you're not really using the cache system effectively. This was about the cache system. This is about the render pipeline. The diagram, this looks pretty scary, right? So that's why I have this fitting emoji there. So I'm not going to go into detail about this. I did a talk about this two and a half years ago, and it's still completely accurate. So if you do want to know the ins and outs of the render pipeline and where you can tie into things and whatnot, please go to that talk or go and look at that talk. That's not what we want to do here today. It can be overwhelming for sure. This is the diagram we're going to look at. Hand drawn took me a lot of time, so it's a bit strange, but I hope you will find it clear. So for Drupal, what is really happening, Drupal and any other CMS or anything on the web, really, it receives a request and it builds a response. That's what the web is about, right? Now, when Drupal receives a request, it routes that to a controller, controller or page callback in Drupal 7, but controller in the end, what it does is returning a render array, so something like this. And eventually, the render system will decorate it with, for example, blocks if you're using the block module or if you're using panels, then there will be panels surrounding the main content and whatnot, but basically, you're effectively building a massive render array who here has cursed render arrays at some points. Okay, everybody else clearly hasn't used render arrays yet. Yeah, they're good, they're great, but they can be frustrating. So we go from a request, we go to a controller. The controller returns a render array. The render array can be expanded further, by, for example, the block module, but eventually it goes into the renderer. And the renderer, what it does is take those render arrays and build HTML fragments. So for example, an entire sidebar with over here at the bottom, the red part is a placeholder. This may be, for example, let's say a video. This may be the header. This may be the main content with a bunch of personalized links. Like for example, if you look at a node, then it will show you five new comments, and you can perhaps post the comments, or perhaps you can't. That's the dynamic nature there. But in any case, we take something that is very much PHP-like, render arrays, and we turn that into HTML fragments. Okay, that kind of makes sense, right? At some point, you need to get to HTML. But then the next step is for these HTML fragments that are each like separate different areas of the page to be assembled into one page. And once it reaches dynamic page cache, we end up with something like this. It's something that looks like a HTML page. So can people in the back actually see the diagram sufficiently well? Yeah, I see nothing. Okay, I could zoom in like this if you want me to. So basically, we are looking at a page and every fragment is assembled into the page, but it's still a partial HTML response because the red bits, those mean that those are placeholders that still aren't rendered. Like there's just a placeholder there, like something that could be injected in there, but that means the page is not yet fully assembled. The interesting thing, though, is that dynamic page cache can cache this page as it is as you're looking at it right now, which means that instead of going through the process of going to a controller that returns a render array, then we build a render array further, then we turn it into HTML fragments, and then we assemble this HTML fragments into an HTML response. We can skip all that. We can just go from request right away to dynamic page cache. So we can skip a lot of code that we would be executing otherwise. This is how dynamic page cache can accelerate things. You can go right from incoming request to a partial HTML response, at which point the only things that still need to be rendered are these tiny red bits. So that's a huge time saver, which is why dynamic page cache is in Drupal Core, which is why it's enabled by default. It helps everyone. It helps anonymous, authenticated, sessionless session responses. It helps all of them. But then, as you can see, we've reached this fork in the road, if you will. So we either go to page cache or we go to big pipe. And I saw that only 15% of you have enabled big pipe. There's no reason for you not to enable big pipe, honestly. It's stable as of Drupal 8.3. We're about to release Drupal 8.4. It is being proposed to be enabled by default in the standard install profile. That is still ongoing. There have been other priorities. But after what you will see today, hopefully you'll consider enabling it because it is helpful. But anyway, page cache. Page cache is what we use for anonymous users. Page cache is what can accelerate the responses for anonymous users, which would mean that we can go right from the request, not the dynamic page cache, but immediately to page cache responses. And page cache contains final HTML responses. So as you can see, the red bits have turned green, meaning the placeholders have been replaced with their final contents. So for example, the thing here at the bottom of the left sidebar will contain a personalized block and the green bit over here in the main content contains the comments, five new comments links. You can post a comment or, well, it's an anonymous user, so you probably can't. The point is we can go right from request, bam, to a final response, which is why page cache is able to send responses in a few milliseconds super fast. But that doesn't help you if you have an authenticated user. So that is why there is big pipe to accelerate those responses, which means that we still are going from request straight to dynamic page cache's partial HTML response. But then we go to page, to big pipe. And what we can do is we send immediately the thing that dynamic page cache stored, which is a partial HTML response. So we can send this data, this HTML right away, as you can see here. But then we keep the connection open. We keep the TCP IP connection open and we send the fragments, the placeholders, the red bits, the values for those, we send them afterwards, which means that immediately, even for authenticated users, you see the majority of the page. You see the skeleton of the page at the very least, the menu and whatnot, the header. But then the personalized bits show up later. And that is pretty powerful. I did make one simplification because most of us care about anonymous versus authenticated. But for many of us, it's actually also the case that what we also care about is anonymous users with sessions. For example, a e-commerce website, Drupal commerce sites. So Drupal commerce, if you add something to the shopping cart, as an anonymous user, obviously you started this session. And that means that page cache cannot be used anymore. But you can still use big pipe. And so big pipe can still send everything in a page and then stream the contents of the cart or the rendered cart can be streamed afterwards, which means that Drupal commerce has an advantage over other e-commerce solutions because it can stay fast, even when using a shopping cart, which was a huge problem before. So long story short, request comes in, turns into a renderer way. That's what you provide as a module developer. The renderer turns it into HTML fragments. The HTML fragments are assembled together, but the placeholders aren't replaced yet. Before it ends up in page cache, the placeholders are replaced. And at that point, things are super fast for anonymous users. But for authenticated users, or more specifically, users with sessions, anonymous or not, we can stream the result that is stored in dynamic page cache right away, which means you, within milliseconds, get something. And then the final bits will follow dozens of milliseconds later where you have the replacements for those placeholders. So together, this means that Drupal has a pretty complete solution for accelerating things at different levels. You could argue that the HTML fragments, which, by the way, are also cached individually, like we wouldn't necessarily need that if you always have dynamic page cache. But it's still helpful in certain other cases, because, for example, maybe page A and page B, they both use this same HTML fragment, if that is also cached and that can be reused. But at each of these layers, so the HTML fragment layer, the partial HTML response layer, the fully assembled page cache layer, all of those are performing caching. So that's where rendering and caching come together. That was basically all the theory I have. So let's look at a concrete example. By the way, everyone still with me so far? Yeah. Cool. So let's look at an uncacheable block. I have this code is available in the demo module that, once the talk is published, you will be able to download and play with all of this yourself. So the idea of this uncacheable block is we're showing the weather forecast, and the weather forecast is changing at all times. However, it's a very shitty weather forecast, because it's always predicting rain. However, we're pretending that we're actually doing the work of computing an actual weather forecast. And so it's taking some time, because it's talking to some external weather service, supposedly. But we are indicating that this is never, ever cacheable. So we say maxH is zero, as in, this can be cached for exactly zero seconds, which means not at all. This block, when rendered, looks something like this. So we have a timestamp there, which is not very helpful, but I'm just using a timestamp so that you can see that it's, when it will see the live demo, you will see that it's changing at every request, so that it's not cached at all. The next one, a personalized block that is personalized per session. So every session gets different content. So we start with five funny emojis, and then we render something. What we do is we pick one at random from those five, and then we say, well, here's a funny emoji just for you. Pan picked at this particular time. The time again allows you to see when it was generated, so yet we can see whether it's been changed or not in the demo. And what we're seeing as well, we're caching this per session. The session cache context indicates this is cacheable per session. And the next one is exactly the same. So, well, this is what it looks like. The next one is exactly the same per user. So again, five funny emojis. This one says today's funny emoji for you. Again, picking a one at random. This time the user cache context instead of the session cache context. And one thing on top of that, we're saying that it's cacheable for 86,400 seconds, which is one day. And so when you look at this, again, a random emoji, just to visualize how it works. And last but not least, a cacheable block. So in this case, what we're doing is we're showing which user is a root user, user number one. So we're getting their name. We're only showing this to users that aren't user one. And we're saying, well, this is cacheable until user one is modified, meaning that we're adding the cache tag for user one, which means that it looks like this for my site because my root user is called root. But this should be changed every time the root user, user one, changes their username. So I think I hope that's pretty clear. So we have four blocks. One is uncacheable and it's always showing the same text, but it's showing like every block is showing a unique time, the time at which it was generated. This one is not cacheable at all. The next one is cacheable per session. The next one is cacheable per user. And the final one is cacheable across everything, but it's not displayed for user one and will or should update automatically as soon as user one changes their name. So later on, you'll be able to download the demo. Time for live debugging. And so again, please interrupt me if you have questions. So let me get started by turning on the exit, but first probably let me zoom this in. This is the first time I'm doing this. So I'm apologizing ahead of time if this isn't a great format. I'm just trying to shake things up. Let me know if you like it afterwards. So we are looking at something. Well, actually, let us start from scratch. So I've got a connection to my database here and I'm going to select cache dynamic page cache, cache render and cache page. So those are the cache bins for render caching, page caching and dynamic page cache. And I'm going to truncate all of them so that we start from scratch. And I'm going to regenerate the page. Okay, so we get... Well, that's kind of annoying, but they picked the same one at random. I can't help that. So let's actually truncate again and hope for better this time. Make things more clear. Yay.  Okay, and let's look at the anonymous user here. And interestingly enough, even though this is not plugged in and this one is, we get the same thing. That's not good. But as you can see, it is completely at random because actually this one was picked at this time and this one was picked at a different time. So ends in two, ends in seven. Okay, that's really annoying. Perhaps I should clear again because it's not clear otherwise for you guys. Okay, probably should have picked a different strategy. Oh, okay, I know what's going on. See, I'm refreshing this page and nothing is happening, even though it's definitely loading. The reason being... Let's see if I can display this clearly. So you can see in the response headers or you should be able to see XdrupleDynamicCacheMiss, okay, but XdrupleCacheHit. So we're getting a page cache hit, which is why we're not seeing anything too. We're not seeing anything change here because we didn't clear the page cache. So as I said, live debugging. So I'm talking out loud. Hopefully the reasoning that I'm pronouncing is actually helping you as well. So now I cleared the page cache and I refresh and I again get the same emojis. Great. Well, actually this time it's actually okay. Funny emoji just for you. The authenticated side as user two. I'm seeing the laughing, crying face and on the anonymous side I get the hands up in the air face. Yeah, as you can see, they're different. Okay. So we already ran into something as in page caching, obviously. I was a anonymous user and so I can clear render cache entries as much as I like. As long as this page cache entry exists, I'm still going to be able to see the same cached page, which makes sense, right? Because as I showed in the diagram, we go directly from requests to the fully assembled response. That's what you guys are seeing. Okay. So that's one thing demonstrated. Hooray. It's kind of stressful doing these things live. Okay. So let's probably look at render cache. So I'm going to clear. Well, I'm actually going to start with renderer and I'm going to need to do this zooming in thing all the time because PHP storm broke its zooming behavior, at least in my machine. I don't know why but anyway, so we're looking at the renderer but I actually know that I need to look at the render cache because that's where it's actually being stored. So if you go to the renderer and scroll down, you'll see that one of the injected services is this one, render cache. So I'm going to click on this one, which is the interface. But if I then press control H, I can see the hierarchy and I can see that there's only one implementation, which is render cache. If I go in there, I'll see this method get. So getting something from the render cache and either is returning the cached result, meaning cache hit, or it's returning false, meaning cache miss. Actually, let's look at all the breakpoints. Perhaps turn on XeVoc first. Okay. And perhaps already, okay, that works. And actually I can show you all of the breakpoints. So I just added these two, the ones in render cache for cached elements and for false. I also added some in other places. For example, for let's start with the beginning, I basically looked at every place in dynamic page cache and page cache where it's setting a header because both modules signal to you as the end user or to you as a developer. What actually happened here? So it always says XdrupleDynamicCache uncacheable or XdrupleDynamicCache miss or XdrupleDynamicCache hit. You can guess which what each means, I guess. Miss and hit seem pretty obvious. Uncacheable means that even though it was processed by dynamic page cache, it was deemed uncacheable. So we can look at that because I saw some hands earlier that that was not perfectly understood. So if we go and look at the code, we are seeing that it's being set here. So the responses uncacheable market as such is what the comment says. When is this being set? Well, when this thing returns false as in when it's not able, when should cache response is returning false? If we look at that, what happens here is this receives a response object. We retrieve the cache ability metadata in the response object and we look at both, well, at the max age, the contexts, and the tags. And so there are some other placeholder conditions which means that if either this max age auto placeholder condition or this cache context auto placeholder condition or this cache tag auto placeholder condition is met, then we will automatically turn it into a placeholder because it is so dynamic that it would otherwise infect or pollute the overall page because let's say we're looking at an entire page. So something like this. And let's say that this thing here at the bottom is perhaps not cacheable at all. Well, if we would be caching things correctly, then this entire page should become uncacheable because otherwise, you would end up with serving something that was not cacheable and yet still caching it and serving it to everyone. So you may be serving still data. That is why we invented the concept of placeholders in Drupal 8. So these red bits are placeholders. Why? To not infect the rest of the page with super highly dynamic or uncacheable things. And that is exactly what dynamic page cache is detecting here. If it is something super highly uncacheable, that is when it says, nope, you shouldn't cache this response because it's not safe. It doesn't make sense. There would be too many variations. So digging a little bit deeper on a placeholder conditions, if you grab the entire code base for that, then you'll see that there's one entry in core.services.yaml. If we go and look there, you'll see that these are the default other placeholder conditions. It's in the container. As you can see, it's in a container parameter called render.config. So you can change it to your liking. But by default, we'll say that max-h is 0, is too dynamic, as in we will not cache this because it's just changing too much in this case. It's changing at every request. And session and user, because caching per user, if imagine you have a million users, then you're going to be caching a million variations. That doesn't make sense. Similarly, for use, for sessions, you'll usually have many, many sessions, so it doesn't make sense to cache for every session. Even though I'm doing that here for demonstration purposes, you shouldn't do that. Okay, so that answers, hopefully, the question of what does that mean, the uncacheable dynamic page cache header. Then we have similar break points in page cache for page cache hits and for a page cache miss. And then in big pipe, we have a break point for the sand chunk method, which we'll see more about later. Okay, everyone's still with us? Any questions? Not zoom in? Okay. Okay, I will do that. Thank you, that's really helpful. But I think I should zoom in, right, because otherwise, you can't read it. Yes, I will do that. Thank you. Was it too hard to follow for everyone or was it okay for some people? Okay, damn it. Sorry, I blame PHP Storm. This used to work fine until last week. Okay, so let's go through an entire process of something being rendered. So I'm going to clear page cache and dynamic page cache so that we are hitting only, well, actually, I can clear everything again. I guess I'll demonstrate now how a render cache works. So I've cleared dynamic page cache and page cache, which means that we are not skipping certain steps. We're going through the entire process. So if we reload this page now, we should be breaking on something that is in the render cache, which is where we are at. The first request is kind of special because, as you can see, it's very, it's kind of difficult now to, is this better? We're looking at dynamic page cache here, but if we, because dynamic page cache reuses render cache, it's an implementation detail. But if we skip the next one, we'll see more clear examples. So we'll see, for example, in this case, we're looking at, I hope that is readable. This is a render cache request for viewing user two in the full entity view display mode. So what we're doing here is retrieving a fully cached version of user profile two being rendered. And the cached markup we can see right here. So if I copy paste that out, to make it more visual, this is what has been stored, what has been rendered cached. I can't. I can't, but like last time I used it, it failed miserably. Hey, okay. Last time I tried this, it worked terribly. Live demo of PHP storm failing. I can't apply, I pressed okay. What more can I do? Yeah, but it's then I lose the, then I lose the debug mode. So PHP storm is not meant to do live debugging. I guess that should have told me something. Yeah, it's still better. Okay, so this shows you one render cache entry being retrieved. If I, so I keep jumping ahead. So I'm pressing the continue shortcut, resume program, option commands are. So now we are retrieving entity view block, bardic account menu. So the account menu block we are retrieving from render cache. We're retrieving the branding block. We're retrieving the main menu block. Retrieving the messages block. Retrieving the breadcrumbs block and so on and so on. So on this particular page is very simple. So you're not seeing much besides blocks because what you're looking at if I refresh the page without, you see that this is basically the only entity on there and everything else is blocks. So that's why we're only seeing render cache entries being discovered. So that's the first phase. A page can be accelerated by render cache, but then it's assembling each of these different parts. All the small parts are being assembled separately. Now, if I refresh the page again or let's do something else. Let's look at the network while refreshing the page. We should in theory now be able to see the dynamic page cache has a cache hit. And indeed it has a cache hit because I just refreshed it so I filled the cache and now it's filled. So we have a cache hit. So if I clear it again, I should see a cache miss. Cache miss. And so every subsequent request for this particular combination of contexts will be a cache hit. But you will probably notice that there is no xDruple cache header in here because we're not an anonymous user. We can only hit the page cache as an anonymous user. So let's look at that instead. So again, cache page is one entry now. And that means if I refresh this, look at the response headers. Dynamic page cache was a miss because the cache hit was for the logged in user. Currently I'm the not logged in user which makes sense and that dynamic cache is a miss. But xDruple cache is a hit. Now if I go and delete it again, the page cache entry, so I'm still in the cache cache page bin. If I delete the only entry in there, then I should be getting a cache hit. Sorry, a cache hit for xDruple dynamic cache because it was filled the previous time. But a cache miss for page cache because I just deleted that. So in this case, we're seeing a cache miss for page cache but a hit for dynamic page cache. Why? Well, because what is happening is this was cached. So this is what the hit is representing. We had a partial HTML response that is stored and that can allow us to skip the steps from render array to fragments to partial HTML response. We can start with the partial HTML response with that part as a hit. But page cache was empty which means that was the thing that was missed. So that is why I can imagine it's sometimes confusing why some things are sometimes a hit and sometimes a miss. Hopefully this clears that up a bunch. Now if we go to the... Are there ways to deal with this from a client-side rendering or an edge-side rendering aspect? Let's say you have a reverse proxy in front of it. So the question is, can you make this integrate well, I think, with a edge cache? Is it a basic question? Is it PSI or H.E.C.C.H. or HTML, WageX? Because although this looks very efficient, you want to avoid hitting the PHP runtime and consuming web server connections under load. I wasn't planning on covering that but it's a fine question. So page cache here is effectively something like varnish. It is effectively implemented without any inside Drupal knowledge. So anything that page cache can do, also, by definition, must be possible in varnish or any other edge cache, which means that for sessionless responses at the very least, it is totally possible to do cache tag-based invalidation of anonymous responses. So the answer is yes for anything cache tag-based. For cache contacts, that's more difficult because cache contacts require inside knowledge because, for example, if something varies by user, like the edge is never going to know which users exist or which the current user is or which session it is and so on, although there are techniques to make that work but it's super advanced, super complex, requires a lot of complex infrastructure and the edge needs to be communicating with the origin, so that makes things more complex but there is a way to do it. The question is, are there no, is there no built-in way to render ESI tags for these fragments? Yeah, H include is kind of a that thing, though, but yeah, as far as I know. But so, yes, you can actually integrate this very easily. That is actually what BigPipe does. BigPipe uses exactly the same approach. So I will cover that now, actually. So hopefully that will answer your question in more detail then. So let's refresh the page again and note that this uncashable block is being changed every single time. So if I reload it and I'll turn off Exibug for a second, so you can see that it's now 79, 84, 85, 86, as you can see, I can keep refreshing and it's custom every single time. Now, how is this actually being rendered? Well, that's where BigPipe comes in. Let's turn Exibug on again and let's refresh the page. And actually turn on listening for debugging again. So I'm going to skip the render cache stuff because we covered that. This is also like I put a breakpoint there. So this is an ideal way for you to debug these things and try to get an understanding. So I specifically chose these points which because they're very easy to find. So if you grab dynamic page cache or page cache for literally hit or miss, then you're able to easily find those points that you want to put a breakpoint at because just before those points you have the decision logic that determines whether it is going to be a cache hit or a cache miss. But we are interested in BigPipe right now so I'm going to disable this breakpoint as well and now we are in the BigPipe class and we're sending chunks. I'm trying to zoom in and out slowly and I'm not sure if I'm succeeding. Very sorry. I'm going to try to demonstrate all the things at the same time.   I'm going to go to a blank page about the load user two. So now you can see we start from a blank slate, right? The first thing we are sending, the first chunk we are sending in BigPipe is this and I'll copy paste it in here. That should be more than legible. Perhaps it's too big. So as you can see, just an HTML document as you would expect, but there is no closing body tag. That's strange. Well, it's because what we're doing is sending placeholders and we still want to stream the replacements for those placeholders. So we have BigPipe-style placeholders here right now. We have one for the rendering of messages. We have one for local tasks. We have one for the uncashable block, the one that was just refreshing all the time with the weather forecast. We have one for the personalized block per session, one for the personalized block per user and then finally one for the cashable block. So as you can see, all of these are placeholders and there's no actual content in there. This is very much like ESI, as you were asking. So what is happening is in Drupal, there's a concept of placeholder strategies. So you can choose to replace placeholders in multiple ways. BigPipe is just one way of replacing placeholders. Another way could be an ESI module that renders ESI includes and then just refers to a URL where those includes can be fetched and rendered. So that's exactly what you were asking. So as we can see, we have like six placeholders and if we continue now in Firefox and in the debugger, let's let PHP send this first chunk. Bam. This is what happens basically when BigPipe is being used. You can see that the majority of the page is visible. You can see that the cashable block is there. The personalized block, both of them, aren't there. The uncashable block is also not there. Which means that everything was sent, except for those red bits, if I'm talking in this metaphor, right? What we basically did was sending this part. The green parts is what we are about to send next, the replacements for those placeholders. So what is the first next chunk that we are sending? It's this strange looking, well actually let me just append to the bottom. That's conceptually also what's happening. We first send an enormous chunk that is the majority of the page and then what we do is send a BigPipe start event. The next thing we send is a whole blob of strange looking HTML.  And the Ajax system then goes and takes this Ajax command which is about inserting, well actually replacing some HTML, which HTML? Well, the thing with this placeholder ID, which one? The local tasks one. And then it replaces it with this HTML. And yes, it is HTML. It's just encoded as JSON. This just means, if you remember correctly, this is the equivalent of the apostrophe. So we're sending the rendered version of each block, of each placeholder individually after the initial page was sent. And so as you can see, this is what we had initially. And now Ajax, once it's JS runs, it hasn't run yet, which is why we don't see the first block up here yet. But once it has run, it will show up. And it isn't running simply because we are doing debugging right now. The next chunk is for another block. It is for the uncashable block. Then another block is for the personalized block, procession block, and so on and so on. Still hasn't processed yet. It's because we're debugging. And so I can continue a few more times. So this is replacing the per user personalized block. Once more, this is then the messages block. Once more, we're done. The big pipe stop event. At this point, big pipes JavaScript will stop processing the new things that are appearing at the very bottom of the HTML. So we kept the connection open. Oh, and at this point, it has been processed. But as you can see, we're seeing it in super slow motion at this point. But these three blocks, the uncashable block, the personalized procession block, and the personalized per user block, those three did not appear on the page initially, nor did the view and edit local tasks thing here. Messages, there aren't any so there aren't any visible. But those bits of the page showed up later and everything else of the page showed up immediately, which especially is very helpful on high latency connections or on pages where there's a lot of complex computations, where you have content that is highly dynamic, uncashable completely, or perhaps requires a lot of number crunching, for example, to determine the favorites of the user or what has been happening recently. Those kinds of things, those can be served later on, streamed via big pipe, and then the overall page still remains fast. And so we've now sent the stop events and the very last thing that is sent is a body HTML, the closing body and closing HTML tag. Right now you can see that, well, I can't go there apparently without disappearing, interesting. In the bottom left of the screen, you can see that it's still waiting for data from the host. And as soon as we send the remaining or the closing body in HTML tag, it will finish, bam, done. Now if of course I turn off X debug, and there is no more long waiting periods, then this is much faster. But as you can see, the casual block shows up immediately. Three other ones show up later. Hopefully that was clear. Hopefully this is all helping, and I'm not making a fool of myself. So that's the live debugging I wanted to cover. Any questions about live debugging? Anything else you want to see right now? Anything that is unclear? Yes. That's a good question. Yes, exactly. That's a good question. So he was asking whether we are using a chunk to transfer encoding because we don't know the content length. The answer is you're correct on both counts. We are using chunks to transfer encoding, and we do not know the content length. So that is the number one requirement, actually. So let me, I know one way of easily finding the documentation page.  Apparently there isn't anymore. Okay, wonderful. The big pipe documentation. This is like live usability testing of the Drupal 8 documentation. Modules. Contributed modules. Wonderful. Core modules and themes. That's what we want. And then big pipe. Apparently still not listed. Click this first. Hopefully it's there. Big pipe module. Big pipe environment requirements, which is exactly what you were asking about. So what is required is that you are not doing output buffering because if there's output buffering then it's still going to wait until Drupal is done sending the HTML and then you don't get the benefits. So worst case, you do have output buffering and then big pipe will be not effective because it's still waiting for everything to complete. But other than that, it can't break anything. But that's the requirement that you don't have output buffering enabled. There's also instructions on how to enable varnish compatibility. The requirement is that you have streaming, again, because otherwise not streaming means output buffering, which means that you can't repeat. Okay, so we're talking about how to make big pipe compatible with your environment. The requirements are essentially that you are not buffering the output because otherwise you are not effectively streaming, which means you're still waiting for the entire response to be complete before sending it. The whole point is that we're sending every bit that we have available right away, which is how things are made faster, which is how the initial majority of the content can show up right away and then the replacements can show up later. This documentation page shows how to integrate or how to configure things correctly, so that it works with everything correctly. But worst case, if you enable big pipe, it just will not have any effect because there is output buffering, because it is not sending each chunk as it becomes available, and then it's just waiting, just like as if big pipe was not enabled. Effectively, yes. So the question is, from a PHP standpoint, are you effectively just keeping the connection open and basically waiting in between echoes and then sending HTML, echoing, printing, HTML? The answer is yes. There's not more to it. Like that's actually the ancient technique, but Drupal, like most CMSs, actually forgot that this was a thing that was possible in the first place for a long time. So almost all CMSs, including Drupal 7 and before, what they are doing is effectively waiting, waiting until every tiny little bit is rendered and then sending it all at once, which means that you're waiting sometimes for the tiniest bits of information, which is not efficient. Any other questions? Yeah? That would be wonderful. So I had a doubt about your initial code that you showed there. The doubt is, so we saw that there are these specific methods to specify the MAC page and so on, but also the output of the block is a render array, and the documentation that I could find always refers to putting this information inside the render array. The question is, would it work? Anyway, of course it's more clear this way, but does it work if you just put that information inside the render array that you return when you run the build? Yeah, it's a good question. I've had the same question like a week ago. So yes, ideally you put it in the purpose-built methods, like for example, get cache max age here, get cache context here, and then get cache tags here. Those are the three. The benefit is that it's more clear, but yes, you can also just put the cacheability metadata in the render array. Why? The reason is this may be calling other templates and other logic, and those themselves may have cacheability metadata as well. So it would be impossible, let's say that this block would be rendering an entity, for example, an entity, let's say, or the current user. The current user doesn't, and then perhaps the current user, and then it's modifying, there is a module that's modifying what is being rendered and that's adding yet more data. Like you wouldn't possibly be able to know in the logic of this block what eventually might be rendered. That's impossible. Render arrays can be extended and altered. That's the whole point. And so that is why it is allowed for you to specify cacheability metadata also in the render array that the block returns. But probably it's clearer in majority of cases to explicitly put it in there if it is something that is, like for example, explicitly varying by user. But for many use cases, it's actually impossible because things have to bubble up from the contents that are deeper within the block. So the question is what happens if you enable PageCache and Bigbyte at the same time? Fortunately, the answer to this one is simpler. So they are enabled at the same time on my computer right now. That works fine. Why? Because PageCache only operates on requests that do not have a session. Because it is assuming, like it is caching something, it is caching the final HTML response and it's assuming that it's the same for everyone, which is only true for users without a session. As soon as you have a session, it could be personalized either per user or based on shopping cart or whatnot. So PageCache is the simple case. Bigbyte only works if you do have a session. So there, that's the fork in the road, basically session, yes or not. And so Bigbyte accelerates the other case. PageCache is much faster because it can skip even more steps. It doesn't need to do any rendering, but it's only actually usable in the case of having no session. Cool. No other questions? Okay. So the next bit, testing. So using cacheability metadata is one thing, but if you don't apply it consistently and correctly, then things can break in unexpected ways, which is probably not what you want. You probably don't want to have built a client project and then have everything working correctly and staging and testing and manual testing. But then as soon as it goes live, oh, apparently things are breaking in horrible ways. Perhaps data is leaking from one customer to another or perhaps stale data is being displayed. There are possible security problems there as well, of course. So testing is important. And in my experience, it's been something that many people avoid doing because it's perceived as being hard or painful. So I'm hopeful that I can show you that it doesn't need to be painful. Can look as simple as this. You can do black box testing or white box testing. I'm starting with a simple case, which is black box testing. So what we're doing is very simple. We're asserting something. We have a custom assertion method. The assertion method is making a request and is asserting that there is a certain title. We're doing the request and we're checking that the title is in fact there. Simple enough, right? So in our actual test method, what we do is we first check that we make a request and the title is the expected one, the initial one. Then we load a node. We change the title and we save the node. And then we assert again and we now assert that the title has in fact been modified. Like maybe some of you are wondering, why is this even like a test? Well, the reason is that this is proving that this is working with instantaneous validation without you having to go and explicitly clear caches. How many of you have built sites that has had requirements for editors to manually clear pages? Like that's a super common thing. Okay, only like a dozen or so. That's interesting. Many people are like, eh, interesting. I guess because many Drupal 7 sites are always clearing things. In any case, this makes sure for the content cache, this is an example with content, but it's also true for configuration, things like block placement, panels and so on. Anything that is related to rendering, anything that might eventually impact rendering should have test coverage like this because it's proving without a doubt and you will know if there is a regression that things are updated right immediately when they have happened. So this is black box testing. It's just checking I make a change. Okay, it shows up without any extra measures. If we go a little bit further, there's white box testing. So we have the same sort of logic. So we have again an assertion method, but this time it has additional parameters, dynamic page cache and page cache. It's still receiving the title as well. What we're doing now is we're still asserting the initial title is there, but we're also asserting that dynamic page cache initially is a miss, page cache is initially a miss. But then if we make another request, dynamic page cache is a hit and page cache is a hit. This looks like super annoyingly simple. Yes, I know. But still it's just meant to convey how you go about testing these things. And I hope this is convincing enough that it isn't as complex as you might think it is. So again, initially both miss, then both hit, then we change the content. We have again two misses, but we do have the correct title, but then afterwards we have hits again. So we basically are each time priming the caches and then we are using the caches. That's all there is to it. Similarly for cache contexts, again black box testing, we're again asserting a thing. We're asserting that something is visible. We're again retrieving a page and we're asserting that both as the admin and the anonymous user, we are able to see this title. So true as in it is visible for the admin user, true it is visible for the anonymous user. So in this assertion method, what we're doing is we're logging in as the administrator. We are making that request and asserting that the title is visible we're logging out, which means we're anonymous and we're making an assertion that the title is again visible. So initially it's visible for both admin users and anonymous users. Then we unpublish the node and suddenly it's only visible for admin users anymore and not for anonymous users. That's sort of testing the different variations and testing the real world schemes or the real world situations that you will encounter. That is necessary to have strong assurances that you are caching things correctly and you're not divulging information, you're not serving stale data. And as you can see, it doesn't need to be complex. It can be literally as simple as this. And these tests, like I didn't omit anything, these are complete tests. And again here, it's possible to do white box testing where we are again looking at dynamic page cache and page cache. But in this case, because now we have an admin user. An admin user is a logged in user, which means they have a session, which means that page cache, which is the second parameter for a third thing, or sorry, the third parameter, for the admin user, that means that page cache should always not be there. Like there shouldn't be a ex-drupal cache header because as an admin user, you have a session, which means that you should never have a page cache entry. So this is also verifying that we're not accidentally creating entries in the page cache for the anonymous user, or as the anonymous user, which would allow the information to be divulged to anonymous users. This is perhaps a bit dry, but I think it is valuable to know. So testing. It's important because otherwise, things may be working in very unexpected ways. Even if you have test coverage, if it's not testing these variations in edge cases, you are in for potential trouble. So with that, are there any further questions? Questions about big buy, questions about dynamic page cache, render cache, everything was clear. Okay, thank you.