 I'm Justina Neon. I'm a developer evangelist at Optimize.ly. I'm joined by Asa Shakar, our developer advocate. How many of you have heard of Optimize.ly before for a show of hands? Cool. We're a feature management and product experimentation platform, and this is our developer relations team at Optimize.ly. What we focus on is the developer experience within the product, and ultimately how engineers like yourselves use our products, so going through things like our documentation, tutorials, presenting events just like this one. Today, we're going to be covering what feature flags are, how they fit into CI CD, and then ultimately going into a hands-on workshop where you'll be creating a feature flag, rolling out a feature to your audience, and we'll dive into things like how you can target specific features to specific users. How many of you are familiar with feature flags? Can you raise your hands? Cool. How many of you use feature flags at your current company? Kind of. Okay. We'll go into how you can do that at scale in this workshop. Feature flags enable you to turn things on and off if you think of it at a very simplistic level. If this feature flag is on, show this user X. If this feature flag is off, show user Y. It really just empowers you to really control when someone sees something and who it is that's seeing that feature. Another concept within feature flags is this idea of controlled rollouts or some of you may know it as canary releases. Maybe you're building this feature on your local development environment and maybe you want your PMs to test that feature now, going through acceptance criteria, so you move that to staging. Then after you're feeling comfortable with its performance and how it's performing, then you want to show the feature to your beta users. Maybe it's your top customers who get early access to that feature, so only a small subset of that of your audience base is seeing that feature. Then finally, you're feeling more and more confident over the weeks as you're releasing that feature out to say 30 percent of your audience, 50 percent, 75 percent. Then ultimately, everyone sees that feature. If that's what you want. But we've gotten this question a few times of, how do feature flags fit into CI CD, continuous integration or continuous delivery slash deployment? We made this chart to show you where feature flags fit into every part of the software development lifecycle. Starting with building and testing, it really saves you time to pie things behind feature flags so that you can still continue working on them without getting into messy merge conflicts. Then once you get into the deploy part, you could actually decouple the deployment and release process by implementing a feature flag, really saving you a lot of time and as most companies like maintaining track on the deployment schedule. Then lastly, but most importantly, the release part. You want to empower teams to manage their own releases. What that means is we've heard engineers say, we want to focus on shipping the code. We don't want to worry about who sees that feature when they see it, what feature is it. We want to hand that off to maybe it's a PM, maybe it's sales so that they can show the customer that new product. So going and diving into each one of these categories starting with build and test, funny little joke there, but with feature flags, you could actually make it so that you're reducing the amount of sale feature branches. So you're hiding things behind feature flags so you can develop in the safety of that. Also most importantly, you could actually continue to deploy incomplete or parts of code without deploying everything. The other thing I want to talk about is the delivery process here. By decoupling deployment from release, you can actually have more flexibility and control over your development process. Something that we just went through, so optimally, a lot of our retail customers saw a big surge in traffic during, say, Black Friday, Cyber Monday, which means a big surge in traffic for us. So what we did was we issued a deployment freeze, but that doesn't necessarily mean that we froze all development process. We still continued deploying behind feature flags, so we didn't actually cause any incidences because that's a pretty big prime time for us and our customers. We want to prevent incidences like that from occurring. Then when the release process here, how we like to think about it is, a deployment is a technical process, and then our release is a business decision. So when a customer sees that, is up to the product team or sales, and the quality of the code, and when it gets shipped is up to the technical side. So you can actually control and have everyone be able to see that visibly with feature flags. Then the other thing to note here is with feature flags, you can test it out on like smaller percentages at a time and can roll that back. So something we do at Optimize.ly is, we have something called a wall of work, and every week if we're deploying a new feature, we make it so that the Epic owner gets up and says, oh, we've deployed it to 5 percent of our audience, 10 percent of our audience, week over week. Then sometimes if we see that 30 percent of our audience we bump into a bug, we actually roll that back so that 70 percent of our audience never even saw that bug to begin with. Then lastly, I recently went to a DevOps conference, and it was really interesting hearing everyone say different times that they've been paged. Like if it's like 2 AM, 3 AM, 4 AM, but here with feature flags, you actually have much more control over these like the times that you're being paged. You can actually prevent those incidences from occurring. Something that we have at Optimize.ly is within, you can connect feature flags to JIRA tickets and we have actually a list of like what you can do with each flag, and it specifically says like, this feature can be rolled back, do it this way. So it's pretty organized and you can see like what you should be doing with each feature flag and how you can address those issues. The other thing with rollbacks is, you're not dependent on someone else's downtime. If you have some third-party JavaScript or some third-party vendor installed, and they're having downtime, that doesn't mean that you have to have that. You can just roll everything that's attached to that feature flag back. Then the last thing is, I went to a talk yesterday where they talked about where the speaker mentioned, they fixed something in production, but they didn't realize they broke this other thing. Then they fixed another thing and it broke three other things. With feature flags, you can actually prevent that from happening by tying each of those features behind a feature flag and fixing those things in isolation without making those dependencies. So the next thing I want to have everyone do is an interactive demo so you can get an understanding of what a feature flag is and how you roll that out. So you'll need your phones and you're going to scan the top QR code, and Ace is going to show you live in our UI how that works. Great. So as you get your phone out, some phones you can pull up the camera app and just point it at the QR code if you're not familiar with scanning, and it should show the URL or you can type in the URL that's next to that code. What you should see when you scan that QR code is right here. You should see kind of an empty little moon. Raise your hand if you see the moon. All right. So people are seeing the moon. So what we did was we actually put this little astronaut behind a feature flag to kind of show the power of launching a feature behind a feature flag. So here in our UI we have this slider and we can just turn the feature on and raise your hand if you see the astronaut now. Nice. So you see my astronaut too. So everyone saw it. So that's cool. That's like a nice toggle. But let's see what that control rollout might look like that Justina was mentioning. Now I put it to 0 percent. So again, keep your eyes on your phone and let them raise your hand if you see the astronaut. So we'll do 25 percent and see who sees it. Any hands up? No. Oh, there's one. There's one over there. Okay. A couple of hands up. All right. Seeing some hands, let's go to 50 percent. You keep your hands up if you're seeing the astronaut. I'm not seeing the astronaut so I'm not. All right. That's about half. Let's go to 75. I'm still not seeing. All right. This is the majority of hands are up and let's go to 100 percent. Everyone's hands should be up, including mine. All right. Cool. Very neat. So hopefully you saw a fun little demo with a simple control rollout but let's take it even a step further. For this pull out your phone and scan the second QR code. And in the second QR code, what we're going to show is more of a targeted rollout. Instead of doing random percentages, let's be a little bit mindful about who we want to get this astronaut feature. So everyone all set with QR code number two. There should be nothing. Cool. Ever. I'm seeing nods. All right. So what I'm going to do is go into this astronaut feature and we've added this audience for special rows and we can see how I've defined this audience. To be a row number, it matches the following conditions and right now it only matches the row zero and there are no rows that are zero. So no one should be saying the astronaut but who wants to see this feature? Any rows of interest of that row? So that's the numbers are one, two, three. So we'll do three and four, five, six. Three and six. So I'll do row number three. Oh, that turned into negative four. Number equals six. We'll go ahead and save that and then save the feature. And so keep your eye on your phone three and six and all the other rows can kind of just like wait and raise your hands. Did we get three and six? Looks like we got three and six. Very neat. And we can kind of go back to the audience and remove that and if there was a bug and we realized those customers didn't actually want that feature, we can save that change and have it propagate so that that bug is, we've mitigated the risk of that rollout in bug. Awesome, so hopefully you see kind of the power that this tool provides both with simple kill switches on off switches as well as targeted rollouts. But this is a workshop that you came to so we're gonna actually do this live in Express. So the first step, we're gonna follow the checklist which should look something like this with a checklist of steps. And the first step is to create a free rollouts account. On the other side of the QR code, there's a scan, you can do it with your phone if you get the URL. And if you end up running into an error with creating account, we do have a limit on the number of IP address, the number of new accounts from an IP. And so if everyone's on the same IP, sometimes we can see errors. Let me know if you run into that error. But it seems like no one is running into that. Raise your hand if you're running into any errors with creating an account. Maybe one, okay. Well maybe you can wait and create an account there. So I'll just open this URL and show you what it looks like to create an account. With this free rollouts account, you'll just sign in with your information, right? So this is what it looks like when you're creating an optimizer rollouts account. Cool, so that worked. So maybe we're not running into this IP problem that I was hoping we would avoid. And yeah, let's just put in some information here. Cool, now we have our free rollouts account. So the next step, and let me know if anyone raise your hand if you're having any troubles with setting it up. Cool, so everyone's got an account. Let's go to the next step of the workshop, which is to create an express application. How many people in the audience use Express for their work? Nice, good amount. Anyone not using Express? What are you using back there? Happy, cool. Any other frameworks people are using out there? In-house, oh, very cool, very cool. Maybe it'll open source one day and we can all use it. Based on that expression, seems like no. Okay, so we'll be creating an express application. The easiest way to do this is with this express application generator. And I wanted to ask the framework question because although this workshop isn't express, you can use rollouts in any platform, but we'll be using express middleware to make it easy to install. So in the express generator, you can use this command express view pug and then the name of your application. So go over to a terminal and I'll name this application node.js interactive. And that was super fast. And then the next steps to follow after creating it is just to change to that new directory that's created, MPM install, and then we will run the server and see it start up. So let's take this command to MPM start. And for those unfamiliar with this command, hopefully I can, there we go. This is saying just show me the logs from NJSI, the application I just named. So now we're seeing the logs. And we can go over to our browser and go to localhost 3000 and see our express app. Cool. So I'll give people just a moment to follow those instructions for creating and installing and running the application. People have an express app running, hands raised, see a couple, cool. Anyone having problems with this so far? Create an account error. Yeah, so if you're getting an account creation error, I would say you can either try if you have cellular service on your phone to try to create an account with your phone to avoid the IP problem that I mentioned, we'll try to fix that later. The other option is just to follow along with the rest of the workshop and get the account laid. Okay, so any other problems before we move on, we want to get everyone kind of working with us so we can get through all the steps. So now let's go back to our steps. We created a free rollouts account, created an express application. Now we'll follow along this link on how to for express where someone made this handy blog post on how to do optimizely with express. And so it starts with creating an account so we'll go down to step two where we're gonna start installing optimizely into this express application. And the first step to doing so is to install our SDK or express middleware, which is a wrapper around the plain vanilla JavaScript SDK. So we'll cut this server and do an MPM install save on optimizely express. And that is installing optimizely in the express application. The next step that we're gonna follow and let me know, feel free to interrupt me if you're having problems or any questions. The next step is to import that SDK that we just installed and start to initialize it. So with that, we'll pull up VS code and I'll open our NJS, cool. And we'll go to our app.js and towards the top we can require that optimizely express middleware that we installed. And then we'll want to initialize that SDK, which as you can see from the blog post, there's this initialize method that we'll call. And I'll go through each of the different options that we'll be providing. So we'll do our optimizely equals optimizely express SDK.initialize and provide some options. The first and most important option to initializing is providing the SDK key. And this is what connects your application with the optimizely UI. How do we find this SDK key? We go to our newly created account and for those who haven't created an account, you can use my SDK key, I guess. But when you go to settings in the rollouts account on the left sidebar, you'll see that there's an environments tab and under here you'll see the SDK key and we'll use for this workshop the development SDK key. And we can copy and paste that into VS code here. And the way that this SDK key connects to optimizely is you can see this URL below is a JSON file where that SDK key points. And this is where the data file gets generated, which looks like it's not quite generating yet. And that could be because it's a newly created account. So we may have to come back to that. Come back to that in a second. Okay, so we'll move on to the different options that are passed to the SDK initialize method, which is that data file I mentioned, you get to control how frequently our application is gonna pull for that JSON file which defines the feature flags that we create in this UI. So our data file options, we'll want them to have an auto update value of true, meaning that we don't want just the current state of the data file with the current state of the feature flags. We want it to continuously update. And then we wanna give it an update interval. And for these workshop purposes, I recommend updating every second, but obviously in a production application you may want a little bit longer of a time, maybe five minutes. We also, this is a polling mechanism. We also have push via web hooks to provide kind of real time, but this is kind of the easiest and simplest to set up in this workshop. So we'll start there, question. Yeah, so unfortunately this URL wasn't working earlier, but let me pull up another example of a data file to make it clear. So a data file is just a JSON object. And as we create new entities like features in the UI, those entities will be reflected in this JSON format. So you see these feature flags, it's empty right now because there's nothing here, but as we create feature flags, it will get populated. And so what the application is doing with this auto update is saying fetch the latest every, try to fetch and see if there's any changes every second. You can think of it as a remote config file that helps. Any other questions here? The last option that I'll pass to this SDK is the log level. Our logger kind of is noisy, so I'm just gonna set it at the warn level in case something is going wrong. Cool, so then the next step, any problems with initializing the SDK? Any other questions? Cool, the next step is to apply the middleware similar to other middlewares in optimizely express. So we'll do app use optimizely.middleware, which is the same kind of instruction you'll see in this blog post right here. So you can copy and paste if you don't want to type. Cool, so now is a good time to start our application after saving these changes and make sure we didn't break anything. So let's start. That seems to be working fine and we can go over to our express application and everything is working great. Cool, so what we did at this step when we used optimizely middleware, we're now giving every single route in our express application access to optimizely information. So now we're ready to install a feature flag. And to do that, we'll go over to one of our routes. So in the routes tab of this auto-generated express application, there's an index file. In the index file, you'll see the route which controls what we see in the homepage. Right now it's just rendering the title express and we can see that here express welcome to express. So what we'll do is we'll change that title and show a feature flag. So as I mentioned and also as mentioned in the blog post is each request object will get a new property.optimizely which will have the information like the SDK client which will provide the APIs like is feature enabled which controls whether or not the feature is on or off. So let's go to the code. And in the request, there's gonna be an optimizely property and in that optimizely property, there's a client which points to our APIs and here we'll call is feature enabled. And the first argument to is feature enabled is the key of the feature. We'll call it hello world for now. The second argument to is feature enabled is what we call a user ID in an application where you actually have users powering them it would be the identifier for that user. In this case, I don't have users in our backend this plain express app that doesn't have a server so we'll just hard code a user ID for now to simulate what it would be like in a production application. Once that call is made we can save this to a variable like is enabled. So this is now a Boolean that we'll get back from is feature enabled. And what we'll do is we'll just change the message that's returned when the feature is enabled or not. So I'll just do a little ternary here and say if the is enabled is true we'll do feature on and we'll get excited with an exclamation point. Otherwise we'll say feature is off, not excited. And we can use cool new syntax from JavaScript to put that message in the title, cool. I'll pause here for a second for those who are coding along and any questions about this code as people are coding it out? Feel free to ask, yes. Good, great question. So that data file, when you start the application the data file will get loaded as soon as possible and then is trying to keep up to date. So then when you call, so that data file is now in memory in the application. So when you call is feature enabled it's just going to that in memory file and determining whether it's on or off. So it's not making any network requests and it's not blocking which is why we don't have to say like a wait or anything like that, question. Yes, great question. So if optimize is down if the data file is not there is feature enabled will default to false. So that is one default behavior but you can also if optimize we're down provide your own kind of own checked in data file to say we never want this feature to be off. That's one way to say, we're gonna have our own defaults. And another way is to, if you really don't trust optimizely CDN host the data file on your own services. So every time the data file updates kind of upload it to your own CDNs and have kind of more control over when that file gets updated. Cool, so now is an even better time to make sure I didn't break the application. So we're gonna restart it and go back to our Express app and we should see the features off. And that is because we didn't turn it on and we actually also didn't create it yet in the UI. So we called the feature hello world. And so we'll have to remember that as we go to our rollouts project. And since the data file didn't look like it was quite up yet I'm gonna use an existing different project. So bear with me while I change my project. To one that I know will work for demo purposes or I hope will work. Oh, that might be wrong. Why I think I got signed out. Switching to different account. Cool, so I switched the account. So I'm gonna switch my SDK key to one that I know is working. I'm gonna do staging. Restart this application. And here you can start to see the logs. Now that I'm using a data file that I know is valid you can see the application getting that data file and we can look at the URL here and see the data file with some content. So now we want to create a new feature flag for our hello world feature. So in the UI, in the left sidebar, you should see features. Click that and click create new feature. We'll give the feature key the same one that we put in the code hello world. And we can save that. And we can see that the feature is off. And so if we go back to our express application and refresh it, the feature is still off. But now let's go and actually see this feature turn on. So we'll turn it on for our staging environment and save that. And we can at this point either see that change being reflected in the CDN file or we can go to our running application and we can see when that data file gets updated from the logs. And hopefully we'll see that we can go now to our application and which I don't think it actually there. Now it's updated and we can go to our application and now see the feature on. So now at this point, we've implemented a simple on off feature flag that we without any additional code deploys, we can go back to our application, turn this off. Save that change. We can wait as our application pulls for that change from our CDN to get that update. There it is. And we can go to our application and we can reload this without any additional code deploys and see now the feature is off. So hopefully everyone followed with me. Did anyone get to the stage where they are able to toggle a feature flag on and off? I see one. Oh wow, lots of people. Awesome. Great. Any other questions? What I will do now is ask myself a question which is how did we see that cool targeted demo piece? So optionally to the is feature enabled API call, you can pass in attributes and in those attributes, I passed in maybe like a table attribute but we can do something like, let's say you have certain users who are VIP users. And right now again, we don't have users backing our application but we can simulate this with something like query parameters. So what I'll do is say, let's say is VIP and if this is a true query parameter, let's target that feature to be on. And so now in the UI, you can go to audiences to target people and you can see the special rows and special tables. The first step is to define the attribute that I passed into that API call. So I passed an attribute called VIP. So let's go and create a new attribute called VIP. Then we'll go to the audience creation, create a new audience based on that attribute, say VIP users. And we'll just say the VIP property is a Boolean that is true, defines our VIP users. So now let's go back to our feature, Hello World, and we're gonna add this audience. So we're gonna turn the feature on but we're gonna add it only to VIP users. And we'll save that change. And we should then, once the data file updates, this feature flag is on but targeted to very specific people. And so we can go to our express application and when I reload this, the feature should still be off. So it's still off but if I add this query parameter, did I label it VIP? I labeled it is VIP. Is true. All right. Something didn't quite or anything through this. So request query parameter is VIP equals to true. That's a Boolean true passed to the attribute VIP and it should be enabled. I shouldn't have to because it should have gotten the latest data file. So like, oh, good point. Yes, change of the code. So changes to optimizely doesn't require restarting the server, changing the code does require restarting the server. Thank you, hard to demo and think at the same time. So now when we reload, we see it's true. And when we turn that to false, it's off. So I did do the coding right. Cool. And that is the workshop. So we're pretty early but thanks everyone for coming. We'll be here afterward. Just as a summary, let's go over summary of some things that we learned. We created an express application installed optimizely seen how we can roll out toggles on off switches, percentage rollouts and targeted feature flags. This application is free to use unlimited feature flags, unlimited seats. So yeah, go have fun and good luck with better deploys. Thanks so much. It's not open source, but we can make it open source. That's something I can, yeah, I can do. Yes, definitely. So great question. If you go to our docs, which are linked in the page that you'll see, you can see the different platforms we support. And so we do have like, if you just wanted to do client-side browser or if you were in specifically React, we have SDKs that are specific for those platforms. But they all connect to the same data file in same type of way. Oh yeah. So I'll show another cool demo, which is you may have wondered why my account has more stuff in the sidebar. And you also might be wondering like optimizely, why are you giving this product for free? Like either we're really stupid or we have, there's a reason why we're doing it. And the reason is because optimizely is really an experimentation platform company. So once you have the tools to give different experiences to different people, now you start to question what is the best experience? And here I'll show a demo to show the capabilities of what we can do in full stack, which is our sort of flagship product. So here's a demo. Let's say you're on the team building Flappy Bird and when you first built it, you didn't build any pipes, so you're just flapping along and it's kind of boring. And so you're trying to figure out what to do with this game. The next thing you can do is add a feature like we did just now in the workshop. And so we can now play it with pipes and we can see, wow, like optimizely gives us control of controlling whether the features are on and off. But in addition to that, in the paid version of our product, we also have variables. We can change variables like remote configuration. So let's make the gravity like way heavier and you can see this game like change quite a bit and it's kind of hard to do on this podium. Or we can do like really low gravity and like see a super floaty Flappy Bird. And the point of this is not just greater control but now you're starting to ask the question of like what is the best configuration? Part of what Flappy Bird's success was was like finding that exact right configuration. And so what we can do is add a variation and create an experiment to run on live traffic and see, given a different variation, some people will see one version of Flappy Bird and another will see another. Can we see the metrics coming back from that and actually run an experiment and see which got the most engagement? This is showing kind of the results that you get out of our paid product. We capture results from the different variations and show you which one is actually the winner to roll out. And this account, this product is a paid version. So, and this demo is, you can play with it. It's not on your sheet but optimize.github.io slash ASA slash Flappy Bird. Okay, I can zoom in. The UI is not open source but the SDKs are all open source. Totally. So you could respond to web hooks from our server and decide we're gonna save this file in our local system and control when it gets updated. Yeah, so the question about whether we can use this kind of free product in production, the nice thing because it shares the same SDK, the same infrastructure as our paid product which is relied on in production by very large customers, you get the enterprise grade with the free product. So I can stand confidently. If you want, we can provide kind of like our uptimes and SLAs separately for kind of the paid version to help gain confidence. But again, if you want kind of that control over the data file so you're not, you're confident that you're not relying on a free product in production, then you can do that. And the way those different environments show up is they're different keys, so different kind of files. So your staging will connect to a certain file and your production will connect to it. I can just say that the paid version is kind of an enterprise software sales cycle. So oftentimes we really wanna talk to the customers directly to see what are your use cases, what will make sense. Yeah, question in the back. Yeah, great question. So going to audiences. You can do exclusion, so matches or it does not match. You also have this kind of and or ability to combine more than one attribute. So it's either this or that, or they're in Montreal, the location is in Montreal and their VIP. The thing to note is that you just have to make sure that any information you want to target off of, you have to pass in as attributes to our SDK so that we can make the decision in memory without kind of going for other, fetching other data. Yeah, so yeah, we would pass in a property user agent, get it from request. You know, we are, you know, thinking about how to make these SDKs better and easier. So, you know, if we find that it's, there's a common attribute that everyone's targeting off of, we can, but this is the way to do it right now. So like whether they can edit things, whether they can just review things, so that can be helpful to provide permissions around future plugins. Yeah, so I think there are different ways to do it. One way, we did a site-wide redesign and we wanted to see what that redesign looked like and we kinda did the same thing I did with a query parameter of like, if this query parameter is on, yeah. That being said, if you don't want like a public query parameter, maybe it's a query parameter that only applies if you're, you know, signed in with a certain level of permissions, kinda you can control when these attributes get set and you can kind of control the mechanism by which when that property is on or off, does that make sense? Yeah, it's determined by the SDK. So this user ID along the user ID is hashed into a range like zero to 10,000 that maps to zero to 100%. So where that hash ends up, it determines whether it's not the feature is enabled and the attributes is more of like, do they check all the boxes? Cool, I think I'll wrap up and start closing things down but we are available around here if you wanna ask any questions and yeah. Come find us, thanks so much.