Lessons Learned after 190 Million Lessons Served
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Bánffy, Ricardo
Ricardo Bánffy - Lessons Learned after 190 Million Lessons Served What we learned along the way - processes, organization, technology and people - from 0 to 11 million students, 40 thousand courses and 20 thousand teachers.
 Okay, everybody's here. We have the final speaker for the day. It's Ricardo Bansi I was going to talk about lessons learned after 190 million lessons served Hi, good afternoon, thank you for coming I'm here to talk about some lessons I'm here to talk about lessons Before anything else, I have to say that I'm new to Udemy and most of what I'll describe happened before I arrived What I'll talk about is therefore the work of other people and the lessons, however, I think they stand on their own Well, this is where we are now Udemy was founded in 2010 and in six years it grew to 11 million students 40,000 courses given by 20,000 instructors in 80 languages The 190 million lessons served number I used for the title was gathered from a table that tracks students watching our videos Lesson 1 is about preserving our culture as we grow We're a learning company and learning is in our DNA For any healthy organization, preserving its culture is essential to its well-being What I'll talk about is about the engineering team Other teams have different things they do Well, we are very serious about onboarding onboarding new employees The idea is to get a new hire from a new hire to a productive engineer in the shortest possible time We use extensive automation We have standardized development environments That's reasonably flexible And if you really want to, you're able to deploy our website on your first day I did that in the first week Even I can do it We learn and teach ourselves using our own tools There are Udemy courses about our applications from the user perspective, from the backend perspective that are given by our own team So you can hear about the application as it is described by the people who created it We also communicate a lot We have hundreds of people in three continents And we spend 11 time zones We all hang out in Slack We use HipChat until yesterday Literally We just moved We also use Scrum We have the usual stand-ups, grooming sessions We also have hangouts We conduct all-hands meetings on hangouts or other solutions if we have too many people Every meeting room is capable of joining a hangout We have big screen, camera, good microphone So we can have easily meetings that span more than one team in one place Well, like I said before, we use automation a lot We automate the quality checks We can't commit ugly code Seriously, we can't commit code with one extra line We can't commit code with missing spaces We can't push broken code That means Git runs a basic set of tests before we are allowed to commit If you are allowed to push To commit, it's flake8 Still, anyway And you can't merge if your code doesn't pass a very extensive set of tests So you are absolutely sure that when you merge your code, you will not break anything Also, we also use custom tools Custom Django admin scripts, custom Django admin commands To help prevent accidents So if you want to update a series of records, a series of objects in the data store You will not be handed a MySQL prompt In fact, it's very few people who have that kind of access Instead, you'll do that through code that's reviewed by someone else That's known to be... I won't say bug free, but it probably is less bug free than you typing SQL commands on the MySQL prompt Even though we go to such great lengths to prevent that Some accidents happen I myself deleted a shared database on my fourth week at the company I was out of the Dublin office where I'm based, in San Francisco And I deleted one of our shared databases Not production environment, development environment But thanks to me, the whole development team with the San Francisco office Which is very large, actually Had a mandatory coffee break Because no one could do anything Yeah, there's some room for improvement What we can do to that? Well, we have the shared database We're working now to have an individual database for everyone We have just enough data so that you can run your development with meaningful data We also constantly make improvements to our development environment We add... All the time we add code that makes it easier to develop We add extra checks We add some extra functionalities that were not there before Personally, last week, I think... No, last month I added a bit of code that made some tree objects represent themselves In a nicer way on the terminal on the IPDB prompt It was horrendously complicated logic And by that, I had someone lessened my cognitive workload So that with my somewhat limited brain I could wrap it around a very complicated problem Without having to worry about imagining what the objects looked like I could just print them on the screen and have a look into them The second thing, the second lesson is that as you grow You start to... You have to... Well, all the time you should be measuring everything anyway When you grow, you will start measuring it in bulk So, every application we have generates... collects metrics about themselves About itself We collect those metrics in a huge... Not Facebook huge, but still pretty impressive scale For that, we use stuff like Sentry, Datadog and Chart.io This is not... Although this is considered something important to us These applications are good enough so you don't have to develop them again These guys are good So, Datadog, Sentry for alerts, Google Analytics The most of Frontend is constantly monitored with that Also, we have a huge user base With that comes the possibility of doing extensive tests and experiments Where you enable some feature and you can track on AB tests how the user base behaves Since you have a lot of people coming, you'll have good quality data on that And we can actually know how something will impact us Well, before we enable it to the whole user base This way, surprise are minimized Which is good. I don't like surprises That also allows us to have early warnings If something starts to... If you see the distribution, say, of execution time of a given function And you have a peak at, like, 100 milliseconds And you start developing a peak at 0 milliseconds You know something is wrong So, you can watch those distributions on a tool like Datadog And this data must be timely We must receive it soon after it's collected We must be able to see it immediately This large user base is all... It's convenient because it generates a lot of data we can analyze But it also amplifies any trend very quickly And it's really not that good for you If you only know what caused an outage Of a week-long outage of a service You don't want that. You want to know if possible before Am I going too fast? No? Yeah, I suspect you like this one It's about questioning and being a bit... Willing to abandon an approach Let me say that They, Netscape in this case, delayed a new version by three years They did it by making the single worst strategic mistake that any software company can make They decided to rewrite the code from scratch Okay, this is Józef Polsky Who knows Józef Polsky? Raise your hand Well, for those who don't know him, he's a pretty clever guy He created a lot of stuff we use daily Like Trello or Stack Overflow Who uses Stack Overflow here? Come on No, I don't believe you. No, no Everyone should raise their hands at that Okay He said that in an article, this thing you should never do That everyone should read, even if you want to disagree with him later Told you you would like it Yes, we moved from PHP We had a large PHP application built on a custom-made framework Created designed internally by our founders Who here has built their own framework? Who thought at that time it was a good idea? Who regrets that now? Okay, we're good This is a problem because new hires have to be trained on a framework they have never seen And it takes a long time It ties an expensive resource It ties an engineer that's already trained on that And the engineer will be tied and not building useful things Useful things for the business, useful features Things users are demanding That specific codebase had very little tests With the lack of tests, maintenance becomes walking on the minefield The fear of breaking stuff and not seeing it until it goes into production or worse yet Until it corrupts user data It drives you to adopt a very careful approach You will always end up opting for safe changes Instead of writing some more maintainable, more elegant, more performant code You may even be tempted to replicate side effects of a previous implementation out of fear you'll break something you're not seeing And obviously this makes development slower and more expensive So what did they do? And I say they because I arrived right after the migration was finished So I didn't even see that happening, I'm such a shame, I'd love to see that I'd love to be able to delete some PHP code So what did they do? No, they didn't jump for the first technology or the technology they loved the most They actually created a project and evaluated, they evaluated the various options They did a small proof of concept project with each of those And with what they learned, they guided the decision They looked into how easy it was to develop for that platform, what they knew How well the platform encourages good practices And how easy it is, it would be, to onboard new engineers and them Yes, this is a serious project, it's not... A lot of resources was put behind it They set deadlines, they agreed on goals They did that as if the company depended on it, because actually it did Well, I know you probably have guessed which technology they chose Because I wouldn't be here talking about it, I would be on NodeCon for something Other conference-stelling stuff instead of here Well, what you and me got? What beautiful environment I have the luxury of working with Well, we got a modern Django-based application And modern, it runs in Python 3.5 and Django 1.8 We are considering the move to Django 1.9 It also allows us to onboard engineers much quicker Because Django is an opinionated framework and you don't have to teach every decision we made Every decision you've made, a lot of decisions are already baked on the platform We have 88% of test coverage That's not perfect, we can do, we probably will improve that One of the things is that we can't commit code, we can't merge code If we've demurged, the code coverage goes below a certain threshold I have cursed this decision a couple of times myself In the end, it's for good With all that, we had also a lot of new features We had a more consistent codebase Which is what opinionated frameworks are for And well, there is some, of course, anything that was migrated There is some scar tissue where PHP and Django coexisted Some table names are a bit odd, some field names are a bit interesting And we have some special field types And some parts where we have to fight Django's opinions And let me tell you Django is very persistent in fighting back Who had here to fight back? Oh, you laughed, come on, someone raise their hand Okay And what did we learn from that? Well, the immigration took a while, it was two years With 30% of the engineering team dedicated to it It was done incrementally, feature by feature And there's a motivation thing on that The team involved, the team responsible for the migration Tracked the progress by counting the lines they actually deleted This is why I'm wearing this t-shirt, they call themselves the delitinators We've cried, deserved one I borrowed the t-shirt, I didn't delete any PHP line All the time the website was up and running And it was, as you would browse the pages, you would see a hybrid PHP Django application Showing your page, showing the data you were used to Also, since everything was changing, mindsets would have to change So that's where the automated checks come from Instead of ending up with an untested codebase They enforced some things that they considered mistakes They learned from the PHP codebase And they worked against the impulse to allow the Django codebase to be like that There's also a final lesson here This is about the importance of the mission As I mentioned in the start, we are a learning company We exist to help anyone learn anything That's quite a goal This also means that anyone can teach something to anyone else We all have things we like to talk about We all have passions We all have stuff that we would like to teach other people if we could Or stuff we'd like to know more If only we could find a person who could teach us What is the impact? About one third of the Udemy students are starting or growing their own business Using the knowledge they acquired through the platform for that We also have lots of people who became full-time instructors Who basically changed careers from being something to teaching That's something they love to do If you visit our stand, you'll see a couple sheets of stories Of how Udemy changed the lives of those people I'll tell one of those stories, not one that's on that sheet Those paper sheets I'll tell the story as it was told to me by my colleague Aaron Who actually knows this smiling, nice guy He's Lin Smith He had a lifetime career as a copywriter He wrote ads for companies like Vodafone, Lloyds, BBC, IBM And after this lifetime career, he decided it was time to retire And to keep himself busy as he winded down his company, his career He got involved in Udemy And he decided to start teaching people to write proper copy Well, it turns out he probably didn't retire Because as of now, he has taught more than 56,000 students I myself was very impressed with his number because I was once a teacher And my largest class was like 50, 60 students For a course that took 20 classes, 20 weekly classes If I were to get close to what this guy did after he retired It would take me 500 years to do that This is a 10x guy, a 500x guy probably When I read the stories, when I read the messages Our internal emails sent forward that our students sent I see our mission is very important In the end, everything we do at Udemy, everything we all do here at EuroPython Is about the people, is about the community It's about people, it's about teaching, it's about learning and sharing This is what we do Thank you Oh, one more thing In case you buy a course, if you use the import this for zero code You've got a 40% discount Any questions? Okay, give a big... Thank you, I know nothing about Django But you said that you had to fight the framework back What was an example? Django is an opinionated framework It assumes you want to do stuff in a certain specific way I know it's no longer the case But a good example I can bring up is from a long time ago And I met that situation I was doing an image bank for a portal And we wanted to save the images, the originals In a way that they would be deduplicated Which meant we would change the file name that was uploaded to a different one And we would place it on a different folder than what Django wanted to do It took me like one week to build the application And three weeks to build the logic to allow the application to save the files Where we wanted them to And it was really, really ugly code at that Anyone else? Hi, you said that Django and old PHP code coexist at the same time You probably didn't just flip the switch So can you explain this a bit more like you probably couldn't use internal Django root system And other features? How did you manage to do this? Did both systems coexist? Django and PHP share the same database with the same data That's why we have some strange table names and some parts of some older parts of the system The URL routing was done both on the web server and the Django application So some of the URLs would direct to the PHP application Some would send you to the Django application Is that what you wanted? Okay, so after you launched fully Django, then you had to do some cleanup of the code Because you basically hardcoded some of the URLs and some stuff Yeah, as the PHP code was being removed, the rules that sent to it, the code itself It was deleted from the configuration Any more questions? Sorry, it's not planned, but I can clarify the routing What we did is we had an Nginx front-end loop answer and we had custom roots of a giant routing table in there That was selectively root traffic to the Django app or let it root back to the PHP app We just slowly deleted those roots and let more and more roots fall through to the Django app That's basically how we flipped over without doing a big bang release So if things went wrong, we could just simply add the root back in and went back to the PHP app again Thank you for that So I hope to see you all at the lighting talks Let's thank Ricardo Thank you
 Okay, everybody's here. We have the final speaker for the day. It's Ricardo Bansi  I was going to talk about lessons learned after 190 million lessons served  Hi, good afternoon, thank you for coming  I'm here to talk about some lessons  I'm here to talk about lessons  Before anything else, I have to say that I'm new to Udemy  and most of what I'll describe happened before I arrived  What I'll talk about is therefore the work of other people  and the lessons, however, I think they stand on their own  Well, this is where we are now  Udemy was founded in 2010  and in six years it grew to 11 million students  40,000 courses given by 20,000 instructors in 80 languages  The 190 million lessons served number I used for the title  was gathered from a table that tracks students watching our videos  Lesson 1 is about preserving our culture as we grow  We're a learning company and learning is in our DNA  For any healthy organization, preserving its culture is essential to its well-being  What I'll talk about is about the engineering team  Other teams have different things they do  Well, we are very serious about onboarding  onboarding new employees  The idea is to get a new hire from a new hire to a productive engineer  in the shortest possible time  We use extensive automation  We have standardized development environments  That's reasonably flexible  And if you really want to, you're able to deploy our website on your first day  I did that in the first week  Even I can do it  We learn and teach ourselves using our own tools  There are Udemy courses about our applications  from the user perspective, from the backend perspective  that are given by our own team  So you can hear about the application as it is described by the people who created it  We also communicate a lot  We have hundreds of people in three continents  And we spend 11 time zones  We all hang out in Slack  We use HipChat until yesterday  Literally  We just moved  We also use Scrum  We have the usual stand-ups, grooming sessions  We also have hangouts  We conduct all-hands meetings on hangouts  or other solutions if we have too many people  Every meeting room is capable of joining a hangout  We have big screen, camera, good microphone  So we can have easily meetings that span more than one team in one place  Well, like I said before, we use automation a lot  We automate the quality checks  We can't commit ugly code  Seriously, we can't commit code with one extra line  We can't commit code with missing spaces  We can't push broken code  That means Git runs a basic set of tests before we are allowed to commit  If you are allowed to push  To commit, it's flake8  Still, anyway  And you can't merge if your code doesn't pass a very extensive set of tests  So you are absolutely sure that when you merge your code, you will not break anything  Also, we also use custom tools  Custom Django admin scripts, custom Django admin commands  To help prevent accidents  So if you want to update a series of records, a series of objects in the data store  You will not be handed a MySQL prompt  In fact, it's very few people who have that kind of access  Instead, you'll do that through code that's reviewed by someone else  That's known to be...  I won't say bug free, but it probably is less bug free than you typing  SQL commands on the MySQL prompt  Even though we go to such great lengths to prevent that  Some accidents happen  I myself deleted a shared database on my fourth week at the company  I was out of the Dublin office where I'm based, in San Francisco  And I deleted one of our shared databases  Not production environment, development environment  But thanks to me, the whole development team with the San Francisco office  Which is very large, actually  Had a mandatory coffee break  Because no one could do anything  Yeah, there's some room for improvement  What we can do to that?  Well, we have the shared database  We're working now to have an individual database for everyone  We have just enough data so that you can run your development with meaningful data  We also constantly make improvements to our development environment  We add... All the time we add code that makes it easier to develop  We add extra checks  We add some extra functionalities that were not there before  Personally, last week, I think... No, last month  I added a bit of code that made some tree objects represent themselves  In a nicer way on the terminal on the IPDB prompt  It was horrendously complicated logic  And by that, I had someone lessened my cognitive workload  So that with my somewhat limited brain  I could wrap it around a very complicated problem  Without having to worry about imagining what the objects looked like  I could just print them on the screen and have a look into them  The second thing, the second lesson is that as you grow  You start to... You have to...  Well, all the time you should be measuring everything anyway  When you grow, you will start measuring it in bulk  So, every application we have generates... collects metrics about themselves  About itself  We collect those metrics in a huge... Not Facebook huge, but still pretty impressive scale  For that, we use stuff like Sentry, Datadog and Chart.io  This is not... Although this is considered something important to us  These applications are good enough so you don't have to develop them again  These guys are good  So, Datadog, Sentry for alerts, Google Analytics  The most of Frontend is constantly monitored with that  Also, we have a huge user base  With that comes the possibility of doing extensive tests and experiments  Where you enable some feature and you can track on AB tests how the user base behaves  Since you have a lot of people coming, you'll have good quality data on that  And we can actually know how something will impact us  Well, before we enable it to the whole user base  This way, surprise are minimized  Which is good. I don't like surprises  That also allows us to have early warnings  If something starts to...  If you see the distribution, say, of execution time of a given function  And you have a peak at, like, 100 milliseconds  And you start developing a peak at 0 milliseconds  You know something is wrong  So, you can watch those distributions on a tool like Datadog  And this data must be timely  We must receive it soon after it's collected  We must be able to see it immediately  This large user base is all...  It's convenient because it generates a lot of data we can analyze  But it also amplifies any trend very quickly  And it's really not that good for you  If you only know what caused an outage  Of a week-long outage of a service  You don't want that. You want to know if possible before  Am I going too fast? No?  Yeah, I suspect you like this one  It's about questioning and being a bit...  Willing to abandon an approach  Let me say that  They, Netscape in this case, delayed a new version by three years  They did it by making the single worst strategic mistake that any software company can make  They decided to rewrite the code from scratch  Okay, this is Józef Polsky  Who knows Józef Polsky? Raise your hand  Well, for those who don't know him, he's a pretty clever guy  He created a lot of stuff we use daily  Like Trello or Stack Overflow  Who uses Stack Overflow here?  Come on  No, I don't believe you. No, no  Everyone should raise their hands at that  Okay  He said that in an article, this thing you should never do  That everyone should read, even if you want to disagree with him later  Told you you would like it  Yes, we moved from PHP  We had a large PHP application built on a custom-made framework  Created designed internally by our founders  Who here has built their own framework?  Who thought at that time it was a good idea?  Who regrets that now?  Okay, we're good  This is a problem because new hires have to be trained on a framework they have never seen  And it takes a long time  It ties an expensive resource  It ties an engineer that's already trained on that  And the engineer will be tied and not building useful things  Useful things for the business, useful features  Things users are demanding  That specific codebase had very little tests  With the lack of tests, maintenance becomes walking on the minefield  The fear of breaking stuff and not seeing it until it goes into production or worse yet  Until it corrupts user data  It drives you to adopt a very careful approach  You will always end up opting for safe changes  Instead of writing some more maintainable, more elegant, more performant code  You may even be tempted to replicate side effects of a previous implementation out of fear you'll break something you're not seeing  And obviously this makes development slower and more expensive  So what did they do?  And I say they because I arrived right after the migration was finished  So I didn't even see that happening, I'm such a shame, I'd love to see that  I'd love to be able to delete some PHP code  So what did they do?  No, they didn't jump for the first technology or the technology they loved the most  They actually created a project and evaluated, they evaluated the various options  They did a small proof of concept project with each of those  And with what they learned, they guided the decision  They looked into how easy it was to develop for that platform, what they knew  How well the platform encourages good practices  And how easy it is, it would be, to onboard new engineers and them  Yes, this is a serious project, it's not...  A lot of resources was put behind it  They set deadlines, they agreed on goals  They did that as if the company depended on it, because actually it did  Well, I know you probably have guessed which technology they chose  Because I wouldn't be here talking about it, I would be on NodeCon for something  Other conference-stelling stuff instead of here  Well, what you and me got?  What beautiful environment I have the luxury of working with  Well, we got a modern Django-based application  And modern, it runs in Python 3.5 and Django 1.8  We are considering the move to Django 1.9  It also allows us to onboard engineers much quicker  Because Django is an opinionated framework and you don't have to teach every decision we made  Every decision you've made, a lot of decisions are already baked on the platform  We have 88% of test coverage  That's not perfect, we can do, we probably will improve that  One of the things is that we can't commit code, we can't merge code  If we've demurged, the code coverage goes below a certain threshold  I have cursed this decision a couple of times myself  In the end, it's for good  With all that, we had also a lot of new features  We had a more consistent codebase  Which is what opinionated frameworks are for  And well, there is some, of course, anything that was migrated  There is some scar tissue where PHP and Django coexisted  Some table names are a bit odd, some field names are a bit interesting  And we have some special field types  And some parts where we have to fight Django's opinions  And let me tell you Django is very persistent in fighting back  Who had here to fight back?  Oh, you laughed, come on, someone raise their hand  Okay  And what did we learn from that?  Well, the immigration took a while, it was two years  With 30% of the engineering team dedicated to it  It was done incrementally, feature by feature  And there's a motivation thing on that  The team involved, the team responsible for the migration  Tracked the progress by counting the lines they actually deleted  This is why I'm wearing this t-shirt, they call themselves the delitinators  We've cried, deserved one  I borrowed the t-shirt, I didn't delete any PHP line  All the time the website was up and running  And it was, as you would browse the pages, you would see a hybrid PHP Django application  Showing your page, showing the data you were used to  Also, since everything was changing, mindsets would have to change  So that's where the automated checks come from  Instead of ending up with an untested codebase  They enforced some things that they considered mistakes  They learned from the PHP codebase  And they worked against the impulse to allow the Django codebase to be like that  There's also a final lesson here  This is about the importance of the mission  As I mentioned in the start, we are a learning company  We exist to help anyone learn anything  That's quite a goal  This also means that anyone can teach something to anyone else  We all have things we like to talk about  We all have passions  We all have stuff that we would like to teach other people if we could  Or stuff we'd like to know more  If only we could find a person who could teach us  What is the impact?  About one third of the Udemy students are starting or growing their own business  Using the knowledge they acquired through the platform for that  We also have lots of people who became full-time instructors  Who basically changed careers from being something to teaching  That's something they love to do  If you visit our stand, you'll see a couple sheets of stories  Of how Udemy changed the lives of those people  I'll tell one of those stories, not one that's on that sheet  Those paper sheets  I'll tell the story as it was told to me by my colleague Aaron  Who actually knows this smiling, nice guy  He's Lin Smith  He had a lifetime career as a copywriter  He wrote ads for companies like Vodafone, Lloyds, BBC, IBM  And after this lifetime career, he decided it was time to retire  And to keep himself busy as he winded down his company, his career  He got involved in Udemy  And he decided to start teaching people to write proper copy  Well, it turns out he probably didn't retire  Because as of now, he has taught more than 56,000 students  I myself was very impressed with his number because I was once a teacher  And my largest class was like 50, 60 students  For a course that took 20 classes, 20 weekly classes  If I were to get close to what this guy did after he retired  It would take me 500 years to do that  This is a 10x guy, a 500x guy probably  When I read the stories, when I read the messages  Our internal emails sent forward that our students sent  I see our mission is very important  In the end, everything we do at Udemy, everything we all do here at EuroPython  Is about the people, is about the community  It's about people, it's about teaching, it's about learning and sharing  This is what we do  Thank you  Oh, one more thing  In case you buy a course, if you use the import this for zero code  You've got a 40% discount  Any questions?  Okay, give a big...  Thank you, I know nothing about Django  But you said that you had to fight the framework back  What was an example?  Django is an opinionated framework  It assumes you want to do stuff in a certain specific way  I know it's no longer the case  But a good example I can bring up is from a long time ago  And I met that situation  I was doing an image bank for a portal  And we wanted to save the images, the originals  In a way that they would be deduplicated  Which meant we would change the file name that was uploaded to a different one  And we would place it on a different folder than what Django wanted to do  It took me like one week to build the application  And three weeks to build the logic to allow the application to save the files  Where we wanted them to  And it was really, really ugly code at that  Anyone else?  Hi, you said that Django and old PHP code coexist at the same time  You probably didn't just flip the switch  So can you explain this a bit more like you probably couldn't use internal Django root system  And other features?  How did you manage to do this?  Did both systems coexist?  Django and PHP share the same database with the same data  That's why we have some strange table names and some parts of some older parts of the system  The URL routing was done both on the web server and the Django application  So some of the URLs would direct to the PHP application  Some would send you to the Django application  Is that what you wanted?  Okay, so after you launched fully Django, then you had to do some cleanup of the code  Because you basically hardcoded some of the URLs and some stuff  Yeah, as the PHP code was being removed, the rules that sent to it, the code itself  It was deleted from the configuration  Any more questions?  Sorry, it's not planned, but I can clarify the routing  What we did is we had an Nginx front-end loop answer and we had custom roots of a giant routing table in there  That was selectively root traffic to the Django app or let it root back to the PHP app  We just slowly deleted those roots and let more and more roots fall through to the Django app  That's basically how we flipped over without doing a big bang release  So if things went wrong, we could just simply add the root back in and went back to the PHP app again  Thank you for that  So I hope to see you all at the lighting talks  Let's thank Ricardo  Thank you
Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_0_1295.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_1296_6203.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_6204_6359.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_6360_11039.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_11040_11603.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_11604_12659.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_12660_13739.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_13740_13811.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_13812_14135.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_14136_14399.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_14400_15527.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_15528_17843.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_17844_22391.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_22392_23591.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_23592_24743.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_24744_25691.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_25692_26639.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_26640_29795.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_29796_30455.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_30456_33443.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_33444_33527.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_33528_34319.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_34320_34727.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_34728_35003.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_35004_37355.png Ricardo_Banffy_-_Lessons_Learned_after_190_Million_Lessons_Served_37356_43427.png